From 0c340b8042c4fbc4e8d0f231a644b8e878a594c2 Mon Sep 17 00:00:00 2001 From: simvalery <94099659+simvalery@users.noreply.github.com> Date: Wed, 18 May 2022 21:09:59 +0300 Subject: [PATCH] Develop (#895) * Bump typescript from 4.5.5 to 4.6.3 in /mrv-sender Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.5.5 to 4.6.3. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v4.5.5...v4.6.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Bump typescript from 4.6.2 to 4.6.3 in /message-broker Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.6.2 to 4.6.3. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v4.6.2...v4.6.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * fix Signed-off-by: simvalery * Bump express from 4.17.2 to 4.17.3 in /mrv-sender Bumps [express](https://github.com/expressjs/express) from 4.17.2 to 4.17.3. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.17.2...4.17.3) --- updated-dependencies: - dependency-name: express dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump express from 4.17.2 to 4.17.3 in /api-docs Bumps [express](https://github.com/expressjs/express) from 4.17.2 to 4.17.3. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.17.2...4.17.3) --- updated-dependencies: - dependency-name: express dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump axios from 0.25.0 to 0.26.1 in /mrv-sender Bumps [axios](https://github.com/axios/axios) from 0.25.0 to 0.26.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.25.0...v0.26.1) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Bump axios from 0.25.0 to 0.26.1 in /ipfs-client Bumps [axios](https://github.com/axios/axios) from 0.25.0 to 0.26.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.25.0...v0.26.1) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Bump sinon from 12.0.1 to 13.0.1 in /api-gateway Bumps [sinon](https://github.com/sinonjs/sinon) from 12.0.1 to 13.0.1. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v12.0.1...v13.0.1) --- updated-dependencies: - dependency-name: sinon dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Bump axios from 0.25.0 to 0.26.1 in /vc-modules Bumps [axios](https://github.com/axios/axios) from 0.25.0 to 0.26.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.25.0...v0.26.1) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Bump @types/node from 17.0.21 to 17.0.23 in /vc-modules Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 17.0.21 to 17.0.23. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * update * GitBook: [#29] Removed Filters in InterfaceDocumentsSourceBlock,Field data in DocumentsSourceAddOn * fix merge * fix merge * fix merge * GitBook: [#30] Added Bind Group Property in InterfaceDocumentSource * fix block updates Signed-off-by: simvalery * fix * fix unit tests * fix docker build Signed-off-by: simvalery * fix ci Signed-off-by: simvalery * GitBook: [#31] Bind Group, User Property, reassigningBlock, Versioning and Demo groups * Update RELEASE-MANAGEMENT-PLAN.md * GitBook: [#32] Create Sensor Image missing in Main * added serivces status UI support Signed-off-by: artembuslaev * fix ws in docker, fix logger status, added reflect metadata to interfaces Signed-off-by: artembuslaev * GitBook: [#33] Added Deprecated to /schemas API * remove methods Signed-off-by: simvalery * update documentation Signed-off-by: simvalery * update schemes * fix datepicker height, disabling accidental closing of dialogs Signed-off-by: artembuslaev * GitBook: [#34] Installation file updated for manual building * Update README.md * GitBook: [#36] Adding VC-modules in Installation * GitBook: [#35] Added Verra Redd Demo * update create adn import schemes * added policy user roles information Signed-off-by: artembuslaev * fix action errors with policies and tokens Signed-off-by: artembuslaev * change display policies in tokens Signed-off-by: artembuslaev * update import schema * fix update blocks Signed-off-by: artembuslaev * Added Troubleshoot section to ReadMe file * GitBook: [#37] Added Troubleshoot section in Installation file * fix * update user * Bump mathjs from 10.4.0 to 10.4.2 in /ipfs-client Bumps [mathjs](https://github.com/josdejong/mathjs) from 10.4.0 to 10.4.2. - [Release notes](https://github.com/josdejong/mathjs/releases) - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v10.4.0...v10.4.2) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * fix policies column width in tokens Signed-off-by: artembuslaev * change save token to create new token while importing Signed-off-by: artembuslaev * fix export policy file Signed-off-by: artembuslaev * update dynamic topic * GitBook: [#38] Changing Block names in Policy WorkFlows * GitBook: [#39] Changing the MRV URL in Step 16 of Demo Usage Guide * optimaize imports Signed-off-by: simvalery * update topic * GitBook: [#40] Resolving Images in Policy Workflows * GitBook: [#41] Updating Image URLs for Demo Usage Guide * Updated BlockType * GitBook: [#43] Made changes in Policy Workflow * fix required schema type fields Signed-off-by: artembuslaev * pagination Signed-off-by: simvalery * update vp block * fix policy calculate block Signed-off-by: artembuslaev * update hedera sdk version Signed-off-by: artembuslaev * fix Signed-off-by: simvalery * fix * fix linting Signed-off-by: simvalery * fix * rename block in irec policy Signed-off-by: artembuslaev * update status * GitBook: [#44] DocumentsSourceAddOnBlock to be changed to DocumentsSourceAddOn * GitBook: [#45] iREC Demo Guide Added * add topic utils * config docker Signed-off-by: simvalery * fix * separate tokens for users Signed-off-by: artembuslaev * remove pagination config Signed-off-by: simvalery * add relationships * fix typos in iRec policy 2 Signed-off-by: artembuslaev * update reassigning block update relationships in vc Signed-off-by: Stepan Kiryakov * fix Signed-off-by: Stepan Kiryakov * Topic mapping (#715) * update schemes * update create adn import schemes * update import schema * fix * update user * fix policies column width in tokens Signed-off-by: artembuslaev * update dynamic topic * optimaize imports Signed-off-by: simvalery * update topic * pagination Signed-off-by: simvalery * update vp block * fix Signed-off-by: simvalery * fix * fix linting Signed-off-by: simvalery * fix * update status * add topic utils * config docker Signed-off-by: simvalery * fix * separate tokens for users Signed-off-by: artembuslaev * remove pagination config Signed-off-by: simvalery * add relationships * update reassigning block update relationships in vc Signed-off-by: Stepan Kiryakov * fix Signed-off-by: Stepan Kiryakov Co-authored-by: Stepan Kiryakov Co-authored-by: artembuslaev Co-authored-by: simvalery * GitBook: [#46] Updated iREC Policy timestamp, Resolved Image URLs for Demo using APIs * fix api for policy roles Signed-off-by: artembuslaev * update api * fix typos in irec policies Signed-off-by: artembuslaev * update api * remove SCHEMA_TOPIC_ID * remove vc-modules section * update api * rename documentSourceAddonBlocks in REDD policy Signed-off-by: artembuslaev * GitBook: [#47] Changing the Timestamp of Verra Redd, iREC, new IREC * update api * GitBook: [#48] Changes in APIs * fix * fix * fix request block ref Signed-off-by: artembuslaev * GitBook: [#49] Blocks Updation after Topic Implementation * GitBook: [#50] Changing Timestamp of Verra Redd * fix swagger.yaml Signed-off-by: simvalery * GitBook: [#51] Remove VC-Modules, Updated sendToGuardian Block * fix policy schema Signed-off-by: simvalery * fix swagger.yaml Signed-off-by: simvalery * fix swagger.yaml Signed-off-by: simvalery * Update swagger.yaml * upgrade version * temp Signed-off-by: simvalery * GitBook: [#52] Minor fixes in iREC Policy * Revert "upgrade version" This reverts commit c5f67fb2d278b7b03b85e7a702b955913f424ddf. * fix package-lock.json Signed-off-by: simvalery * add topic owner config * add topic owner config * update demo * fix * GitBook: [#53] Adding TopicOwner Property to sendToGuardian Block * fix infinity loading in import dialogs Signed-off-by: artembuslaev * fix policy message * hedera modules unit tests Signed-off-by: artembuslaev * change response status codes in post policy and schema methods Signed-off-by: artembuslaev * remove comments, fix tests Signed-off-by: artembuslaev * added drag n drop for import policies and schemas Signed-off-by: artembuslaev * added placeholder for root authority input Signed-off-by: artembuslaev * aggregation workflow * update ui * api tests Signed-off-by: simvalery * fix Signed-off-by: simvalery * GitBook: [#54] Changes in Verra and iREC demo * add cron config * update * fix Signed-off-by: simvalery * fix Signed-off-by: simvalery * test fix Signed-off-by: simvalery * test fix Signed-off-by: simvalery * update * update tz * Cumulative Dimension * update * fix * GitBook: [#55] Adding API Workflow for new iREC Demo * added copy blocks, added states Signed-off-by: artembuslaev * change text align in service status component Signed-off-by: artembuslaev * fix copy paste blocks Signed-off-by: artembuslaev * update timer block * update * fix * GitBook: [#56] Correcting errors of API workflow * new block Signed-off-by: simvalery * refactor Signed-off-by: simvalery * fix ui issues Signed-off-by: simvalery * fix ui issues Signed-off-by: simvalery * add switch block * fix * fix Signed-off-by: Stepan Kiryakov * fix Signed-off-by: Stepan Kiryakov * fix lint Signed-off-by: Stepan Kiryakov * added users to demo admin panel Signed-off-by: artembuslaev * GitBook: [#57] Added External API, Added Sample MRV data * fix * fix * fix * fix * feat: replacing fastMQ with Nats MQ Signed-off-by: Truong Nguyen * displaying available nested blocks Signed-off-by: artembuslaev * added allowed children to action block Signed-off-by: artembuslaev * fix * GitBook: [#58] Corrected Block Properties of all Blocks * GitBook: [#59] Added URLs and Ports in Installation file * GitBook: [#60] Updated Implementation Diagram * update README.md Signed-off-by: simvalery * update README.md Signed-off-by: simvalery * GitBook: [#61] Corrected URLs and Ports * GitBook: [#62] Updating Prerequisites * GitBook: [#64] Updated Frameworks/Libraries * fix view some fields in VC Signed-off-by: artembuslaev * Feature/publish docker images (#868) publish docker images Signed-off-by: simvalery * added env balance variables (#864) Signed-off-by: artembuslaev * fix Signed-off-by: artembuslaev * GitBook: [#63] Updating API Workflow of new IREC Demo * GitBook: [#65] Updating API Workflow of IREC 2 * GitBook: [#66] Updating the API * GitBook: [#67] No subject * Feature/publish docker images (#873) add frontend image * fix Signed-off-by: simvalery * GitBook: [#69] No subject * GitBook: [#70] Adding more APIs to iREC 2 * update token creation and importing Signed-off-by: artembuslaev * fixed returns tokens while creation Signed-off-by: artembuslaev * GitBook: [#73] No subject * GitBook: [#74] Adding Switch Block * GitBook: [#75] Redoing API Workflow of iREC 2 Demo * fix merge Signed-off-by: simvalery * up version Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: brandisio Co-authored-by: Stepan Kiryakov Co-authored-by: prernaa.agarwal Co-authored-by: Stepan Kirjakov <84465157+Stepan-Kirjakov@users.noreply.github.com> Co-authored-by: AnVaBr <32775532+anvabr@users.noreply.github.com> Co-authored-by: artembuslaev Co-authored-by: artembuslaev <68849616+artembuslaev@users.noreply.github.com> Co-authored-by: prernaadev01 <79293833+prernaadev01@users.noreply.github.com> Co-authored-by: Truong Nguyen --- .env.example | 7 + .github/dependabot.yml | 114 +- .github/workflows/api.yml | 6 +- .github/workflows/main.yml | 10 +- .github/workflows/publish.yml | 101 + .gitignore | 4 +- Dockerfile | 13 + README.md | 49 +- api-docs/api/swagger/swagger.yaml | 8 +- api-docs/package.json | 3 +- api-gateway/Dockerfile | 7 + api-gateway/nodemon.json | 6 + api-gateway/package-lock.json | 323 +- api-gateway/package.json | 5 +- api-gateway/src/api/service/ipfs.ts | 2 +- api-gateway/src/api/service/policy.ts | 7 +- api-gateway/src/api/service/schema.ts | 12 +- api-gateway/src/api/service/websockets.ts | 32 +- api-gateway/src/app.ts | 22 +- api-gateway/src/helpers/guardians.ts | 2 +- api-gateway/src/helpers/ipfs.ts | 31 +- api-gateway/src/helpers/policyEngine.ts | 2 +- .../src/helpers/serviceRequestsBase.ts | 29 +- api-gateway/src/helpers/wallet.ts | 8 +- api-gateway/tsconfig.json | 1 + api-tests/index.js | 29 +- auth-service/Dockerfile | 7 + auth-service/nodemon.json | 6 + auth-service/package-lock.json | 333 +- auth-service/package.json | 7 +- auth-service/src/api/accountService.ts | 120 +- auth-service/src/api/walletService.ts | 25 +- auth-service/src/app.ts | 13 +- auth-service/src/helpers/fixtures.ts | 44 +- auth-service/tsconfig.json | 1 + {message-broker => common}/.gitignore | 0 common/package-lock.json | 2730 ++++ common/package.json | 29 + .../src/decorators/singleton.ts | 0 .../src/helpers/application-state.ts | 25 +- common/src/index.ts | 5 + .../src/models/message-response.ts | 18 +- common/src/mq/index.ts | 92 + {message-broker => common}/tsconfig.json | 4 +- common/tslint.json | 31 + dev.js | 47 + docker-compose-dev.yml | 192 + docker-compose.yml | 18 +- .../assets/Guardian_Architecture_Diagram.png | Bin 0 -> 129850 bytes docs/.gitbook/assets/PW_26 (1) (1) (1).png | Bin 0 -> 399664 bytes docs/.gitbook/assets/PW_26 (1) (1).png | Bin 0 -> 399664 bytes docs/.gitbook/assets/Verra_2 (1) (1).png | Bin 0 -> 51067 bytes docs/.gitbook/assets/Verra_2 (1).png | Bin 0 -> 51067 bytes docs/SUMMARY.md | 11 +- .../action-workflow-block.md | 14 +- .../aggregate-data-workflow-block.md | 19 - .../aggregatedocumentblock.md | 39 + .../container-workflow-block.md | 12 +- .../documentssourceaddonblock.md | 24 +- .../external-data-workflow-block.md | 15 +- .../filtersaddonblock.md | 20 +- .../information-workflow-block.md | 12 +- .../interfacedocumentssourceblock.md | 12 +- .../introduction.md | 4 +- .../paginationaddon.md | 10 +- .../reassigningblock.md | 13 +- .../reportblock-and-reportitemblock.md | 10 +- .../request-workflow-block.md | 15 +- .../retirementdocumentblock.md | 12 +- .../roles-workflow-block.md | 13 +- .../send-workflow-block.md | 33 +- .../step-workflow-block.md | 13 +- .../switchblock.md | 17 + .../timerblock.md | 18 + .../token-mint-workflow-block.md | 12 +- .../token-wipe-workflow-block.md | 12 +- docs/demo-guide/api-workflow-of-irec-demo.md | 12169 ++++++++++++++++ docs/demo-guide/demo-usage-guide.md | 2 +- docs/demo-guide/demo-using-apis.md | 51 +- docs/demo-guide/irec-demo-guide.md | 14 +- docs/demo-guide/verra-redd+-demo-guide.md | 6 +- .../sends-data-from-external-source.md | 30 + docs/getting-started/built-with.md | 14 +- docs/getting-started/contact.md | 2 +- .../getting-started/installation.md | 22 + .../getting-started/prerequisites.md | 6 +- .../reference-implementation.md | 2 +- .../creation-of-a-policy.md | 2 +- ...tting-started-with-the-policy-workflows.md | 2 +- .../policy-workflow-step-1.md | 2 +- .../policy-workflow-step-12.md | 2 +- .../policy-workflow-step-21.md | 2 +- .../policy-workflow-step-5.md | 2 +- frontend/package-lock.json | 42 +- frontend/package.json | 5 +- frontend/proxy.docker.json | 22 + frontend/src/app/app-routing.module.ts | 193 +- frontend/src/app/app.component.html | 10 +- frontend/src/app/app.component.scss | 17 +- frontend/src/app/app.component.spec.ts | 52 +- frontend/src/app/app.module.ts | 6 +- frontend/src/app/common-components.module.ts | 23 + .../confirmation-dialog.component.css} | 0 .../confirmation-dialog.component.html | 6 + .../confirmation-dialog.component.ts | 22 + .../datetime-picker.component.css | 23 + .../datetime-picker.component.html | 8 + .../datetime-picker.component.ts | 63 + .../dragonglass/dragonglass.component.css | 0 .../dragonglass/dragonglass.component.html | 0 .../dragonglass/dragonglass.component.ts | 0 .../file-drag-n-drop.component.css | 12 + .../file-drag-n-drop.component.html | 7 + .../file-drag-n-drop.component.ts | 63 + .../code-editor-dialog.component.css | 86 + .../code-editor-dialog.component.html | 13 + .../code-editor-dialog.component.ts | 65 + .../cron-config-dialog.component.css | 142 + .../cron-config-dialog.component.html | 149 + .../cron-config-dialog.component.ts | 196 + .../import-policy-dialog.component.css | 2 +- .../import-policy-dialog.component.html | 41 +- .../import-policy-dialog.component.ts | 51 +- .../tree-data-source/tree-data-source.ts | 2 + .../tree-flat-overview/tree-flat-overview.css | 232 +- .../tree-flat-overview.html | 96 +- .../tree-flat-overview/tree-flat-overview.ts | 501 +- .../calculate-config.component.html | 12 +- .../custom-logic-config.component.css | 1 + .../custom-logic-config.component.html | 24 + .../custom-logic-config.component.ts | 77 + .../aggregate-config.component.html | 102 +- .../aggregate-config.component.ts | 21 +- .../timer-config/timer-config.component.css | 0 .../timer-config/timer-config.component.html | 63 + .../timer-config/timer-config.component.ts | 81 + .../switch-config/switch-config.component.css | 0 .../switch-config.component.html | 103 + .../switch-config/switch-config.component.ts | 68 + .../common-properties.component.css | 14 +- .../common-properties.component.html | 73 +- .../common-properties.component.ts | 5 +- .../policy-configuration.component.css | 57 +- .../policy-configuration.component.html | 141 +- .../policy-configuration.component.ts | 313 +- .../app/policy-engine/policy-engine.module.ts | 27 +- .../app/policy-engine/registered-blocks.ts | 924 +- .../import-schema-dialog.component.css | 2 +- .../import-schema-dialog.component.html | 42 +- .../import-schema-dialog.component.ts | 51 +- .../app/schema-engine/schema-engine.module.ts | 14 +- .../schema-form-view.component.html | 8 +- .../schema-form-view.component.ts | 17 +- .../schema-form/schema-form.component.html | 435 +- .../service-status.component.css | 29 +- .../service-status.component.html | 21 +- .../src/app/views/header/header.component.css | 9 +- .../app/views/header/header.component.html | 18 +- .../user-profile/user-profile.component.html | 6 +- guardian-service/.env.docker | 2 +- guardian-service/Dockerfile | 7 + guardian-service/nodemon.json | 6 + guardian-service/package-lock.json | 198 +- guardian-service/package.json | 18 +- guardian-service/src/api/api-response.ts | 14 +- guardian-service/src/api/approve.service.ts | 33 +- guardian-service/src/api/config.service.ts | 27 +- guardian-service/src/api/demo.ts | 23 +- guardian-service/src/api/documents.service.ts | 76 +- guardian-service/src/api/loader.service.ts | 54 +- guardian-service/src/api/profile.service.ts | 41 +- guardian-service/src/api/schema.service.ts | 159 +- guardian-service/src/api/token.service.ts | 137 +- .../src/api/trust-chain.service.ts | 22 +- guardian-service/src/app.ts | 10 +- .../src/entity/aggregateDocuments.ts | 45 +- guardian-service/src/entity/policy.ts | 8 +- guardian-service/src/entity/schema.ts | 6 +- .../src/hedera-modules/hedera-sdk-helper.ts | 2 +- .../src/hedera-modules/message/did-message.ts | 12 +- .../hedera-modules/message/policy-message.ts | 8 + .../hedera-modules/message/schema-message.ts | 12 +- .../hedera-modules/message/topic-message.ts | 8 + .../src/hedera-modules/message/vc-message.ts | 8 + .../src/hedera-modules/message/vp-message.ts | 8 + .../src/hedera-modules/vcjs/did-document.ts | 21 +- .../src/hedera-modules/vcjs/issuer.ts | 4 + .../src/hedera-modules/vcjs/vc-document.ts | 4 + .../src/hedera-modules/vcjs/vc-subject.ts | 9 + .../src/hedera-modules/vcjs/vp-document.ts | 4 + guardian-service/src/helpers/ipfs.ts | 13 +- .../src/helpers/serviceRequestsBase.ts | 19 +- guardian-service/src/helpers/wallet.ts | 8 +- .../src/policy-engine/block-tree-generator.ts | 1 + .../policy-engine/blocks/aggregate-block.ts | 228 +- .../policy-engine/blocks/calculate-block.ts | 126 +- .../blocks/custom-logic-block.ts | 112 + .../src/policy-engine/blocks/index.ts | 31 +- .../blocks/interface-document-action-block.ts | 8 +- .../blocks/interface-step-block.ts | 4 +- .../src/policy-engine/blocks/mint-block.ts | 4 +- .../policy-engine/blocks/reassigning.block.ts | 4 +- .../blocks/request-vc-document-block.ts | 10 +- .../policy-engine/blocks/retirement-block.ts | 4 +- .../blocks/send-to-guardian-block.ts | 32 +- .../src/policy-engine/blocks/switch-block.ts | 169 + .../src/policy-engine/blocks/timer-block.ts | 178 + .../helpers/decorators/basic-block.ts | 47 +- .../helpers/policy-import-export-helper.ts | 31 +- .../src/policy-engine/helpers/utils.ts | 12 +- .../policy-engine/interfaces/policy-event.ts | 10 + .../policy-engine/policy-components-utils.ts | 102 +- .../policy-engine/policy-engine.interface.ts | 8 + .../policy-engine/policy-engine.service.ts | 182 +- .../tests/api/approve.service.test.js | 101 + .../tests/api/config.service.test.js | 123 + .../tests/api/documents.service.test.js | 148 + .../tests/api/loader.service.test.js | 133 + .../tests/api/profile.service.test.js | 193 + .../tests/api/schema.service.test.js | 138 + .../tests/unit-tests/approve.test.js | 16 +- .../blocks/block-tree-generator.test.js | 7 + .../tests/unit-tests/config.test.js | 18 +- .../tests/unit-tests/documents.test.js | 4 +- .../tests/unit-tests/dump/vc_document.js | 41 + .../message/did-message.test.js | 54 + .../hedera-modules/message/message.test.js | 41 + .../message/policy-message.test.js | 59 + .../message/schema-message.test.js | 73 + .../message/topic-message.test.js | 45 + .../hedera-modules/message/vc-message.test.js | 65 + .../hedera-modules/message/vp-message.test.js | 65 + .../hedera-modules/vcjs/did-document.test.js | 131 + .../hedera-modules/vcjs/issuer.test.js | 30 + .../hedera-modules/vcjs/vc-document.test.js | 69 + .../hedera-modules/vcjs/vc-subject.test.js | 29 + .../hedera-modules/vcjs/vcjs.test.js | 557 + .../hedera-modules/vcjs/vp-document.test.js | 63 + .../tests/unit-tests/loader.test.js | 26 +- .../tests/unit-tests/schema.test.js | 436 - .../tests/unit-tests/token.test.js | 86 - .../tests/unit-tests/trust-chain.test.js | 6 +- guardian-service/tsconfig.json | 1 + interfaces/package-lock.json | 4 +- interfaces/package.json | 2 +- interfaces/src/helpers/schema-helper.ts | 10 +- interfaces/src/index.ts | 4 +- .../src/interface/messages/account.message.ts | 59 + .../src/interface/messages/auth.message.ts | 12 + interfaces/src/interface/messages/index.ts | 5 + .../src/interface/messages/ipfs.message.ts | 17 + .../src/interface/messages/log.message.ts | 18 + .../src/interface/messages/socket.message.ts | 12 + interfaces/src/models/schema.ts | 10 +- interfaces/src/models/token.ts | 2 +- interfaces/tsconfig.json | 1 + ipfs-client/.env.docker | 2 +- ipfs-client/Dockerfile | 7 + ipfs-client/nodemon.json | 6 + ipfs-client/package-lock.json | 174 +- ipfs-client/package.json | 5 +- ipfs-client/src/api/file.service.ts | 71 +- ipfs-client/src/app.ts | 10 +- ipfs-client/src/config.ts | 2 +- ipfs-client/tsconfig.json | 3 +- logger-helper/package-lock.json | 366 +- logger-helper/package.json | 6 +- logger-helper/src/helpers/logger.ts | 21 +- logger-helper/tsconfig.json | 3 +- logger-service/Dockerfile | 7 + logger-service/nodemon.json | 6 + logger-service/package-lock.json | 209 +- logger-service/package.json | 7 +- logger-service/src/api/logger.service.ts | 61 +- logger-service/src/app.ts | 13 +- logger-service/tsconfig.json | 1 + message-broker/.dockerignore | 3 - message-broker/Dockerfile | 12 - message-broker/package-lock.json | 4705 ------ message-broker/package.json | 25 - message-broker/src/index.ts | 30 - message-broker/tsconfig.tsbuildinfo | 1 - mrv-sender/Dockerfile | 7 + mrv-sender/nodemon.json | 6 + mrv-sender/package-lock.json | 36 +- mrv-sender/package.json | 6 +- topic-viewer/package-lock.json | 49 +- topic-viewer/package.json | 3 +- web-proxy/Dockerfile.ci | 18 + web-proxy/configs/image.conf | 66 + web-proxy/configs/local.conf | 97 + 291 files changed, 24536 insertions(+), 8929 deletions(-) create mode 100644 .env.example create mode 100644 .github/workflows/publish.yml create mode 100644 Dockerfile create mode 100644 api-gateway/nodemon.json create mode 100644 auth-service/nodemon.json rename {message-broker => common}/.gitignore (100%) create mode 100644 common/package-lock.json create mode 100644 common/package.json rename {interfaces => common}/src/decorators/singleton.ts (100%) rename {interfaces => common}/src/helpers/application-state.ts (53%) create mode 100644 common/src/index.ts rename {interfaces => common}/src/models/message-response.ts (79%) create mode 100644 common/src/mq/index.ts rename {message-broker => common}/tsconfig.json (84%) create mode 100644 common/tslint.json create mode 100644 dev.js create mode 100644 docker-compose-dev.yml create mode 100644 docs/.gitbook/assets/Guardian_Architecture_Diagram.png create mode 100644 docs/.gitbook/assets/PW_26 (1) (1) (1).png create mode 100644 docs/.gitbook/assets/PW_26 (1) (1).png create mode 100644 docs/.gitbook/assets/Verra_2 (1) (1).png create mode 100644 docs/.gitbook/assets/Verra_2 (1).png delete mode 100644 docs/available-policy-workflow-blocks/aggregate-data-workflow-block.md create mode 100644 docs/available-policy-workflow-blocks/aggregatedocumentblock.md create mode 100644 docs/available-policy-workflow-blocks/switchblock.md create mode 100644 docs/available-policy-workflow-blocks/timerblock.md create mode 100644 docs/demo-guide/api-workflow-of-irec-demo.md create mode 100644 docs/external-apis/sends-data-from-external-source.md create mode 100644 frontend/proxy.docker.json create mode 100644 frontend/src/app/common-components.module.ts rename frontend/src/app/{policy-engine/helpers/dragonglass/dragonglass.component.css => components/confirmation-dialog/confirmation-dialog.component.css} (100%) create mode 100644 frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.html create mode 100644 frontend/src/app/components/confirmation-dialog/confirmation-dialog.component.ts create mode 100644 frontend/src/app/components/datetime-picker/datetime-picker.component.css create mode 100644 frontend/src/app/components/datetime-picker/datetime-picker.component.html create mode 100644 frontend/src/app/components/datetime-picker/datetime-picker.component.ts create mode 100644 frontend/src/app/components/dragonglass/dragonglass.component.css rename frontend/src/app/{policy-engine/helpers => components}/dragonglass/dragonglass.component.html (100%) rename frontend/src/app/{policy-engine/helpers => components}/dragonglass/dragonglass.component.ts (100%) create mode 100644 frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.css create mode 100644 frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.html create mode 100644 frontend/src/app/components/file-drag-n-drop/file-drag-n-drop.component.ts create mode 100644 frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.css create mode 100644 frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.html create mode 100644 frontend/src/app/policy-engine/helpers/code-editor-dialog/code-editor-dialog.component.ts create mode 100644 frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.css create mode 100644 frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.html create mode 100644 frontend/src/app/policy-engine/helpers/cron-config-dialog/cron-config-dialog.component.ts create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.css create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.html create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/calculate/custom-logic-config/custom-logic-config.component.ts create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.css create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.html create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/documents/timer-config/timer-config.component.ts create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.css create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.html create mode 100644 frontend/src/app/policy-engine/policy-configuration/blocks/main/switch-config/switch-config.component.ts create mode 100644 guardian-service/nodemon.json create mode 100644 guardian-service/src/policy-engine/blocks/custom-logic-block.ts create mode 100644 guardian-service/src/policy-engine/blocks/switch-block.ts create mode 100644 guardian-service/src/policy-engine/blocks/timer-block.ts create mode 100644 guardian-service/src/policy-engine/interfaces/policy-event.ts create mode 100644 guardian-service/tests/api/approve.service.test.js create mode 100644 guardian-service/tests/api/config.service.test.js create mode 100644 guardian-service/tests/api/documents.service.test.js create mode 100644 guardian-service/tests/api/loader.service.test.js create mode 100644 guardian-service/tests/api/profile.service.test.js create mode 100644 guardian-service/tests/api/schema.service.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/message/did-message.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/message/message.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/message/policy-message.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/message/schema-message.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/message/topic-message.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/message/vc-message.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/message/vp-message.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/vcjs/did-document.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/vcjs/issuer.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-document.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/vcjs/vc-subject.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/vcjs/vcjs.test.js create mode 100644 guardian-service/tests/unit-tests/hedera-modules/vcjs/vp-document.test.js delete mode 100644 guardian-service/tests/unit-tests/schema.test.js delete mode 100644 guardian-service/tests/unit-tests/token.test.js create mode 100644 interfaces/src/interface/messages/account.message.ts create mode 100644 interfaces/src/interface/messages/auth.message.ts create mode 100644 interfaces/src/interface/messages/index.ts create mode 100644 interfaces/src/interface/messages/ipfs.message.ts create mode 100644 interfaces/src/interface/messages/log.message.ts create mode 100644 interfaces/src/interface/messages/socket.message.ts create mode 100644 ipfs-client/nodemon.json create mode 100644 logger-service/nodemon.json delete mode 100644 message-broker/.dockerignore delete mode 100644 message-broker/Dockerfile delete mode 100644 message-broker/package-lock.json delete mode 100644 message-broker/package.json delete mode 100644 message-broker/src/index.ts delete mode 100644 message-broker/tsconfig.tsbuildinfo create mode 100644 mrv-sender/nodemon.json create mode 100644 web-proxy/Dockerfile.ci create mode 100644 web-proxy/configs/image.conf create mode 100644 web-proxy/configs/local.conf 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 0000000000000000000000000000000000000000..b48fde753caf0baa1fe130fa9e3b67570231eb40 GIT binary patch literal 129850 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⊃ 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%0D=$Y#NF>lkw3?V_3(Z7`K;~l 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 $qk8>r@wQR zS(s@bfJ~D6kixD9lP8ymHR5^m=Jd?TiwLzG4CfN8F7raW6621RwURj1%&*AZr)N6LjOcu3YSehC~ zfZhRma*fykF{$G$Rd$nj>On<%wT=dqWutNA`f-N&x^n;8w%v4(kdvS%c6nf+b*leG ztbCroe(zPa7U|-4!03WP#gvvdiDl{WL{y(tV^!U9{+~mEm9(1W>k;c{i#O%pw^Tvi3bT zSdrQQWtD%r^QyIlFjnD_T9teiwVxjYO+FMZOqNxL-)E-6Rl={SpBfL}x#K)1{13B! ztTToopx&JiMJ_3frmgoK#MztAZUE`9hWg*!m75`!N93C?!hTM8}zh=17 z|3}zYKvlJMZPVQ;0)n)3H`3jrba!`mDBU1kl1g{S0i>k6Idpe7|3UA)@AroOW9-2= zY{ua1z1CdM%xBK|{*z z?=h!8HX*rp_Fnuz_Z((-;nga2Dj0%uUrPF$9F$v?I&(C(57GMXf%|`x6F+1IUC8gV zsnxM17W$*^PqkEmZ!t_KvYf;qsxm%0=Cp=?qwyO*v`1|;p%f3SavDTl4u;`1P;^ZE zu7!M`QlHm4LRADMI*w6T9OfuW*^sHJzDZJehpL~et|8UWks`~6dEzwMHP9>U%CHb7 z(UiMg4lr^@(_qb_MND+JD-QqBAn73;`a>~$KG~{20Msq0Seq!dOIoI?W6}7^r_V@5 zzuwWw>-#lixurAPtNIh>`|Ds*!_-p2y5UMtF+g0HVXl5dN#tPXng@5JtsT01uV+;K zf@hQqOHj>$e3KxY%BlMb&dtm_$d=9J-9jGt;jZR{S!aUl$to?ake)Tr6av(tw|D!X z5j>M0Hh&cYn>zV5+pHGJJ zO{}nB4mHe!39q`SwpPOvJ8TRiYwecd9EW1BLN`$ZYW9igr52TM_G2;|+eIC|4E!AH zBhF231+tbqO^YO9rob#$zA&`i+c%$G^1Nt!dgQ#QRd{XBC&BenFdT)<;n`k7Jb?NQP+SXJr?DNU}AJ;9P@{X$=we5>K%`u|cS4?YaL0qq-bD|FV2%CP1mswfrgT+Qi=}vuD-_RrtEMcxXrPw#$NSTq+xrm}T6>+(5^L z;hgbM5b|^GMZhnT8j#8CG~tr5CHuRio23Fc2SbJ_hSkRFUe3>*DbTV+Z;e?3IwxBV zN6noEp{7>31eNni*EV;3Qg&WC8tnIh!nzfPQ=72PP6l+B%g$Plr&--|e1Ugn?ESsS zQ}I~)HC?G=v(BG9P%@PVw>}d}YaKkQNtY7JP9afm@NMqSf1;}$P~MLoj+7l;k}%OZ zHYuMH*SdJn+S9Uyd{*as#95j8%*n%YH`%dAmJdS+ug)>0^2LBI+y-q~HA{`y-Y})9 zM0LLpp#LACCO%oZ!2Pa;EBBadrgdIV_j>`UK|6LT)*d`oTYOj%+w<((szLNONu9)8 zM}Y3%M>gqsQ@>GEbg=p9z|z`HyCpC%u(_eeL+$_QE!G^)W;+KqlE8bf>KK86?%K5z5MmWy z-W8A&J;+6fl~N)A$xKDk?piOtV5-R%X6%Zsp=5JuCT+1 zfrAX0uRSwcu?4kP<@bJvT3y2z8!cjx4cbfvj6{ zC}u}NK%fwWJQ3TMe`-9?yomwZA7C;~lf+@+)Rfh#5^ZO3MWk$T+E-iG_j#{=q%T8$ zoX7kPWcAI&X8u*(rL=~*p!DAKWAL6w*rb-ur=H4o#3o)JB#S0mR}_e~OIYZ^hmU|q zwD$f-#@91*4wkwtd1%&aIi-7Pe1(Jim&$kJK~8)x>p;)To#MOYw#lc*rO3Q zfdt0U*YW8ODUvjSGVPXVDT>s6YYvwQ;!X|@8=EZ{mjo+aWIf$!9RzTHl&~Q;e**+du!VzcgESH3#EOWcbuIf)3=#_{FIHU-2rx2s%-^R8?svs}0Ya2k;&>fWRcc z2lKb>b_d?6?uhJ$0wa;K3lnyOmCgHu#(TxaU4_Z{5j16o%>gOxGkp#yr0S7X(RrX{gb?qJ9eOQ#)O(}m1UE6&*CI8(eb16;lvKhEuO9Kue2 zn^k=kI~JJ*b!2N!){^7c<O!60vJCH&O{oscn55-uT8sb*a$z0t)A9>;ZHJ!V~JSH7?eP{T;>uquH=gxB&!`B zJ-)tll}+RRSs6964&71qDEr9k`ddv43evv;M>gItdA!Z1(Lzm@>4s|5A63mc8*RL~ zz%N-xf@b#>;QlPc`wHs)!9}uEzQ2GC>-H(vOL)kdzHTkH`OWtqCRc`i9$BcVsrR#w z&Mlv`vsdh#v?+hZxl})Z1n+}v{m0)v0RRTqmH=5>QafA8ET8A78PUjSgIN?bEbxt# zbeN)gGx-k>%c%8AR*YnfzV(X{U!>SllYC;~8PSQblyB^@fpX3*#zLF&+_mL$+Si%2 z?bX5%Bi2jR?clDy>~vYl8+Z+oX@+cLAEa#$j8yc_%hQ=WXBY|WdIjr`o>~ICV!s@c zehSX5p4YW}R~hI8Q8*a?O=@|?BeN?MyFXVBCdIE*Nxl1YQc?_>J#L_ns@<#sCdar^ z#p-=`?^K_|n5tS80S#GJxP&IN-?(w*MQrR%QC!QEQMK-DnOysYRrf$bTe_`W!q0$+ zX&Xelyu;kl&B?&;rOy%rq9EP*r5xu9lt`!-@5A}{_1T*IDySS(80vxS40n5h3$Aij zVE&f-%^_5YRy|+1z?!w@z%P21?GI42@5o_C&Lg*yh3*cg5b0h5siVmL(${V z^rab#U#hvC`mJx|$K)p25}k1)4xlHCGeIR}B#(7ARQlqD`y%@V2O#{8&C5hJ3W89a z_=$(*i6#5naP-uBJ+OMV3pdN(LP#e9ryLoauA7$3^pKHJtKlPs!V%B*LLP_t0w>AF zA`=xeY_F^9xiIQ;Td7xCxP3|OZ{MEOeQ!GQj(n(#u~W~xTf`1i&hm(Q<$4J`%2q0n zoAJ5#qoNLdy;2fS2AW!sM$-IvyO&h=6@?Tuoin<`J(WpYdfnC7cKSH|*fAlm6Oqib z!8-Rn?Y{rCjz+K!pC|h64-%?D+IAeT>?Frkc-P${pPs%ZWY%ee55+Y3vZ;Y;X9;>e zgf4)uB^btcNo0+b3q#v!njzUTY`f|7UrWEWr`qruG$y{P?m47lU=Tk#f7c-AMce1t zc@AP96*Cy?rdri@^`dKJm)4?WdS7xW)2D^ui7p-k<@r0U1Ac7uV05Ya+c$GLQE&S2 z;CBY0_Miaq^&d-DWBqtdh6wuPmykf^pGhZOJxPo!aD5b01k1z>GtF>Br;uDX{WmEf zDr^$OCCh96@*-hYk(|+eTcn%4xfF~hUu%maxOw4!N3MU>Lps9w-Q)M%l%2^hMfB2X z!iSo~dLMhy#oblw~gJdw0}ELWmg0rlk|;_%+!j1BsImUxst5*{;D zS?g`#eWZYY!Kne%19%5KCBdh@xDEIC=?k_=PEfn4lOvxejnW1wP4^x7lkaQtfS5h$ zFox;!hVFIsd&h1h0*3*nBt8%Jx3|Z_@IT}L1Ia9Tl-o$=g+;b~IFseQF8EblSV{y!}4C}qogweRpXk-KiuIrRp=!biTW z`4j;(VZ~F^ZR4|Sq+s#IzTwLsu+PFg2)AvL1mj~>k;&rRTEe%bJ~yS_efhtvhhK}m ztpFj|8u`&;kTbuFx!X*L0=fJ(PM4qoO8e;81sy#fTUq2`n&vA8m#vPAbRH1W%`xlUGdmfN_dD$- zPAIc<)F^WZkemGFg75&`a>u*U(UJ|f+$D9jc~f=T{p=B>l<7kwrK!>wVRmcS;wvBf zOS{`Ly&>)hydh9Hm%+|~+0>lqbv%!!$7?StFBCLs+vnxj?CxEoAS-~wD4mCxD55eJ zHy2dWKX~57wc|}cVzf0MP{_QP>VfjwLIn~g@?R2UJnbZ3_Y^UFX(sc>FKvOyyO=zF z7qoVqnHF@lHPp#ekRBRk;uV&@!JX;2?TW`g(~ddJ7pkXW6)Ej)58vqOV7n5-qkq?* zA$X&4X8ULj51PkPz9u)nw#DBj^q7BMhlX;_Pj?#oTzMz}VoaikJ=&5zi7T>?6b(0e zF4WtBM(QleqQXS5Ya5C2JFVYoc+8HV5*}UKMm95hR?~o#&l9X$JK3^rIn8> z?xK2p@>}18e8%hh>WT4id)eu;bd74<_L$$-T3lENmAphGdO|8kiBiP!ydKg4Cp4HnpX2aZFp8LZyN ztu}ryK*_{Z4#}OY4L(6^T&XQ)?o?ie=@@=Dh zl@3eKPnj=5*sr=;I>oE3^UUYmtm->=C!Rd7A|uUo@;Io$?d~;vi?6cSEK8>cW1H&E zGxOrNpuYwOg;)K_;84sHwNxe}j$J8Wyg&Lp;+Au*JpH&o@hw12W|Mc4Ph|Ir4LMfgwm1lYDxBbL>(4QtYqdA zi%yFl1xt~AyUS?B$Uj4UzjQ1u;2>=_u70U>%KEY%*={`M5**HKt#u ziTLPB!c5hrzs*!uz*9thsT-C-+$TA=DWl6&?S1BO-J?aFV zOSxOwp#*0o%MJd>;b_zOVdO-ePBsOdfkBg~#I>1-QK$rcB}4mWe2$v)yN&|gz@H_$ z5Pm-yIO44*w|kqg?=NBBt#uy+RT%VGGs}QVmziy_@uhx?>muOD{%8Ie_z`<3qy$%}8vVerPywgyrG@*z2ZU z7|V$&u5_?1fp$ePM_jOK?xOMWd|ZCC#lyw%aB;f2XL3zCq=yg*pB+iZ`zEiU^}`_9>-PNgbeI8~DGl4r$ji40=Ndxw7UvKX}~FgQuY z&jif&5R$KDcyM@E5Bp)f(TI$b3t6G?{a{xC*g zNf0i6a30&@@tDq0=j)u>0HnjPfJnk14R0TQW4e+KP_MePIP?X(EgMA@m5AU+fIxSp zb?{`?-N+!Lb(Gi1He^(X{8YRAq~6?l+3|ARFzIVAQ6hG8)(qEO#rL#YA8#ezv}(t9 z$kVsHG`r#1&d>~5(F(1|YGg3aiNz+;^6x|e;$1!M46D}HW7I4$dNPuRe)CBQXX!a4 zwwk=>NM}V_H7>L9NbeW=Y00aB2-GxMS^WApk5_Fr`CgZ^J>hp20d2R!GzYR-CAh|5 zbr&wd2ft@g$NToJA`j0P^BDKgf2RF$vUb(E-{25X+{2p;N-wX0I`nonCx;#HY-O&F z&D*qZYl%VD^xGZhhFp^*cY_)@hn<4+WEbY+D3!LpFfvMCE>LpwSdm6x#i636Zx{CQ zhMNXD(>Tv~!{WiRP^j6W6F9Eia7uPVh?#R;@~@+LYHjF0JzR;`(ZPUtsxWoh_5|E6 zhe$hwbA}Vi7HVUIKF&8A^*i}GsQ{^D!>>F6F5L`1C(;fhgf5HNm^2A`W4V&dX*NU? z6H}|T8l^&+OI~CoRZva67rci-bs&EB;-@m5rfI|1!&+0mpfR{X+KaGKBNPGi)-BkO zwF?-LZOtbkwvo>&4inTfsRmeaS>uhm$Jut9oZn)Rw4rxdwxdYA5QPl25);0(HllTw=> z$m47Wl9(!Kts0||nW6l!SM21I8NrqEWz^(L;G7Lu!uDm255{U6^lb!s$lIybj0P0) zVob4OWInNSMTEU_gZ=PfGUYS9~1{j(5}G zWLlt}B-Y&)6fDg*CYf_(-x1`_a87<;ow@Qqt@0pDk1%Xq>|>@H)6@1sU_W zF*Nz@7_1xBoyeu9p_JEcl$$h5%v3{MX(RQMUC5XBe*lXT8mqOd1it0sSUi{)EZwJ* zS>)u0?V7$XwSb>6eONvk+H9ZQOP($PUx$RIipDMnjy3{3Q8u7IS>@exfAZ5wuM^aL zASe;zC$L>MJH^AgZ|aPp->Jd(d=Qy@;IxJeM8Wgl%B-hY@H%$;)`JrI(2Vf!Bqf3y zJ=Jdbx0Fs_9@Z`NmFWNK@bbSbO1~+Lk<{-gW;^p0GUVGDuQ^;PMzk^SDFKl&o=9c;|keGZpQ&acDb2-P4u=VZ1>#W!-hSz-V+6Ed>M zc2bl3AO*&l6(}24e%jcOec{CH7k!L}aW!(ls$0yzKov7!PzChg<9u167eTC>J--8# zG&3_Bp{F#uq#-rnaB-!74r-RGgFoz>eVg$uo9g#j9COCEXnDw8Q0-Z>`;&3S265T# zkPc;b;q=Y;af)NPum{*~6}xh`%rMmDry+qR*SI=~@vTI#&J`>D?ow3iyC^7^E|Ibz z8{(H&wT57^8H0qr-+NmvHfdGH+c*TpHUX0-iL%z z#vq9{HQQWVMQp$KN!ow3l)Sen#^4P(Uh0bRUZ2pcU!-7(sCTw*>2P(pUkUkc&!EHi zn2}P=x(hup?!csEm$YSAwDzR|ocy;$&+p_Y^30l9Z5nd;ZSb8P9vswG#)%)$9)j&6^Ate3Sm#v4jSkGoe3?Hg$P{wp5KK*2hEhRH2xdQaCu9rrPIM&H1Jpyzm{!HHE zkuB*KEaVP!2(@%+HVc*c%v5Jl4dxW~u4(sDZe<5cXE-NDJUFI1w{LhaYD#qK9~y@( z0zJK7W_Ve_j%c&t`z%KF@qrfdKs4)Qt0yJ>1NCR>>jkx{19lO*JBC2y3Y){Y-`Y@M z&>{fm2T;+#i)18ob8`h9l_*tS9OvV-y&tpAvuV!b$9zOi$;1;W&H=u~$Vj-(H_g=N zbDvDD4mud^9sGFl8MQC!H7ma%%=q?<S=*! zOkQwU-riV4TbV{HCZFy%i~j#4CJn4!n50S$`_6FHR0&gj!qVX>)I<(!;>iIWItoZm zZ9{GGPA0{1xq*RsCixZUI-5Pxc5r)eU>0GlyyY&(mBNc&tI`au*4m2$XU}{6+S|<&DWiz;#J6~>oOe5@rx^!~0O=UlTNp4qUupZ)}pKVuL3#t{L0 z^pOGWoERn3 zIx*JR=yfgR;~%}vu_2(2SQpVDT$R|-F#}8S3^~`_ims8cI%DP+Y6aDX$GcGc^nxoS z^@k)ZA7~>Dnhq{|AW;|S?yLod2WZdFP1YV&-ikf>H7)NYK81SsHMp+lsm<7rfG6E- z$XKEL#jXXtnJF0n%$5{o=zl}x^Ig>z0q!`^FioTL{C96eas(5HZue8^GXfrNGEiAI z=rkT;>J$EX$Kn>S9x!bW7Hh%(Uae70ojtiO(!Ey-5v+DzU$a7n!YBvZW+A3YgrFT)4&QjNruSkb;KTGCpH1vHF)7} zZ08MrJQ3AO|A4yAg$b*--V0xVEE)gw<~bdPCHegZX8}?W30#-`>K{1jAVWwrJy%0q zA1*ljPkfCmfuLm}5GSxBdspLh-N!b)Dxy{<$`Zr|$;pqXnkbqRv+u{pfH~zfIMeP8 zGFyaI>k>o$MNhAO7A|Qa&EHxfjuPP0^1_r7ugc^mt#Mhp9zJuPjxf3I<~xiq+(655 zU(oVCjqSPK_rIu3c14cuL(n|m%UoH&j1q5HlXfn%ptx4-TmSrqHU+OZ&KR3AovKls zFy43<)X^;xzkgC%SVx>JOcnC`98OC~5ng-70NYdMd;OnPARt-Df<#z<#2y8g&nWnP zV@_RJXjVv-o-L;ZV&SVSP$MTSHRp*>xT_ONaxshN@$YqTakYI2<+yjq1pFHWyMSBk68T_2L>Pg^O_(PfVJf#Sa=PN zLHxVRFCU(hvaA#p6tP}#p0`SBu15f+WC%J|q;kjJp!*sq=OSyi&J`Z@IYZVG#4+>? zzulu9IKBmykC(Rd`OpWv2&x#~!ChSqqZgxMm(}c|rn11FooSc7N+6f;h5B`IV}K(7 z2zRW{)FuDE_0Qk_`JgV4)%q?K4wk>5TUJw7w}R7;?UQKKqRWim%rsTg>gB~Ga&cd1 z4GBh22QxD3KGs;fU@qBVnH(Y^ONCz-KLI^7f;7`9YFqmTZdydw2KM$+OH=(vNZ6Bw zl+xgywd=_d5(2gpC&$q1G2=DKyDkw3GJ&60`7L}sZhN)SB0Gc0?D%$*cKf_`Z~sXX>l|ZF?q%Qet;1__!000KbyA<>3=QQKa29O4_S5)Lt6OS zLnazPl{K|axhXsRiF2V^5LEx*laDSdc_AEa#s8_^4((<~okzMlp3y1b^uy~AYFf$= zDO!Emn@G|)wWAzw{yoA~l)uCy8o({>`vhA)w4|>6;_rKZ%g%qi&tJa^h(C*zc+*<5 z_8&yb7~S-n2gTZTO^FF%`ye;rgk*8#vL%$j9&s(o3gbHp<8l$?T4Zxc;CJFFq%DzJ z*anin#dA9giVDnS1b?`n;_qAkExM+B5Uo@#)WE=w*Vl4eHFq?-pWn1)Lx5J4Mlx&X zO_#<}d87ly^8=bjL7nqd@KGWF4sH%Bj{e&5U;F;=KTE{2@=$aRzGBWgrpu6_MTn6z z9KXE7V41lRd4VE2z;?sVzduj(Mc53Jl#{H&Hz1z*pds^Xfcj;0>4IMxt+g{P1Rc7r zLx29b86-7<^*7X3gOiQPSkQ6`Xpjql*Ox5eU55RBdv((((87Acms8P~iZ#X#?wDJu zDC)|_`BJ^mLu3&e*4pX$C5bZyocGs>)V%qxHlVzi1eK(B8Gs}X&oYu_fY$p|8sEpK z&Zh`weW3wB`QQ8Zb9bv{A&P(xU->bLMvT9+C*N|7c$Q>YKx>;UUc|7fdIB#yQPbMq zLb&9Yq3?6`U+Z3!>>FyH&f`)$&cF32v+oZM%Rle_C7#P+1|CpLL^5bp>)3fPD^n^#EKIBt z-D_B?YjCpK6)ZvmI?5jT@1^H^-><_wf3qVo#BCkl>o0`VG&C^?OF;9FHuI)7WLH5In-Sd}hk3hY@Cgidw>!^(EBC8INIe2|ETJ3KC z)HAY6s0aJ6bNd^>Q;+gZJyq)h(v;Oha4b10?KuUK)C$f0-3!3vS^E9hMTlM4p&m*n zyspySo^!B;{11KS>~)$J&Y2Ll7Gqltf56i@M)0ixt#PgDE%@0QHi)1SmYJ#{V7U`S zlQvgDnZu*IHT#at1KXlaZCfe2!itc=Qz0TJnZ?gzL+p1c=?h#wIBTt#{==C$i1u|r zY$)A2YVs_V%wmHRaoD8Wn6ZrD0XRGhK4AB?0BE9`ts%`H{s-BJ5QJW`5Hpz_BqrP! zlu-pNJst1L&oh1*^?pi~WHDl6VXrr&HQObSn{8_d!cxfTtYt;M;}(xAh#7oE_Hey; zs5`!|k|$j+P#M8}P)p)RE(22tdOM+<&u}op;fE{#jIu=%zCIf&=)^^T0&Tz#v|jAF z2`jg=K@L)FP5+J#q4)%6Au~yMZd@0k>7j?wk~<128jWyJXE#JpztGqaz9gxFa>Emh ziOI>=>2jpB`o~Wc52!>w_e|LsogWHLC!HM#9%K<>DkPTC>#?1N!d_R8%XKz$RWWWAaMgpD(B)gvUQBL*`@=7z@RXjy==p9} zgLTqB;y<}Ft$r2YeA&~Ls2vFV$_t@phw;a_6V;VDI$|O~z6(u$I!oZPOT;p*>kXC! z)=G!7Ot=>1FPQba6avIW{vh$$+ADE5V@}lX-)5>ZL@7QObIh}-B>AIu0GN|1kVNV@ z9a4O+9dB?j!NS4{KC4R&Zut~Tgnm+sfQ^kU!BE6l3Y2fVg)$1mHTV(#=6bikj8S)F zDxX1njs-<;G+q==&R}l9?0WxfSYg76kAQPu;QBP`L`!Af%0T!p`5D=S11ZW)Yj~c2 zl=pw*%m@>lYC)6^tyBpuyIZi-0uT*@xumN5CL-wjB#kslTE{p8f0#H?Gro5=f{r&E z4F6ziq*_%!qxWhQMPV6th`|yB)^!+}w=Hh-@mvAt%6C#mpGQ{S>!lZ#l}C&NI;s?p zB#*57t`6zs%VwHplDGc8M?2Sszcd&~-)w_fN4Z3J{Xup^@ervh-jA%G_UqkcW)0{?KN(lKo1fYFpBrJBMbmhF0@Cc-Pha5dCWVP_n4c;4?XNvS^Dr;E(6ov5#b zv2a4`P?J?x(zbA4iENp|58VzPDX6Lj$20Vhms)UYntlQr@{o5~|MP;y!2-wBGoez) zf3~Cm>aVjR7v6J!G9?RrU)d_K*H>Z4Y;^l2+eRd<4d1FBJ%L`!{G-<3I2Hml|J`Bz zT7s&&qTk(N3vLFwcc<$^1jq5^{Lza<#>F-mT>ih*jBYw92x!xr@|ubNpa3rg0ddyu z$v%w-cV>1EQrgsh*{Yh^=f(xTk#36dIF7NLZHl>F-~<;mOzXHj%X522Vu=?pVA9kh z!shQqZb{I0f({UH4E7Ctx{Hq5!n`#sL&xY`dLp7){dM*$`BuHX>>9j|^%?%rNh!j< zN&*}~82$eU>i_rvP$$l!Ujp^;h73aP9Dzg?nQ3%i{08b?q8UFi0o{br=`xZfnDo{H zXVoq%%M@>j>xuwtf^4vQB=}>+XnyKS7l^xFY1FTPw--2+F1)Rb8{B5RYuXLwY})YG z5d;nT0)u`Y^mQuq2emv$3XXZF65hHC>l_FympRg;ZPMnp%6C*ItcODXNQPret4?O; z>({8jbnl8j6$a~Hy4AHJ9lmUuD-anJjTDljst{@&a8N4?X`J=8;;s>Q7fiRA6-_Ozlhm zV-bIvb)fr>0uaazcETCoAyGWrg~&eESHKnRi>TZrA$DM!@pm+_)Ih?WJ`Y+PUY;rG%7 zj`3Aoz~HbkcRs@eODk?8awF76og3?21qY9ogEdz{RRed!-tC5^q=n?^!*X+JGnXJK zQE9pu3QJQ2rs)u$^;#m}Fy>i1Hjzf3ZM9C`%7NEUj+}k}gXusRB2fCGU|vr1Gh<74 z{a#RKGVcaPY*JgPoWc}*w>pYF>x{ezgkPP2KfJ|F^(<~?Ib4gnTn?B8LayN~Ds-ft zi?>5G(H@!K=awElyfBrgi?aIb?6Bp&q_ITo)f0f?5*8IpMqYGxtu<#u%yzd!XI_%@ z^S)Vy_}+P>0Vy9cT6X1qn1P@5?(`GAfYfc<>Wc+n&B}IXhJSc$GBh;X)wJ=x4!4BY zgDysv$YDd1a8qB(weDUkEma-#YPXzP4;#Oi)sfW`+Kh-#cZRqh;%x zAx4bpL@9FSA%Nu0adwADA+&Jq#OJ`O6s67>ecX~SFuw6m_Cu^fR+V?To z@?-5X?&^R%;09%JgRZgmBewmbd=H3HE+}4k)85L0V*sAyTJ6!|)QHFB$(!1Wq|@ibm--XV;(Rm~y(np-XlxPE6a%H^;{I zKqX`o4pnDaqjzB1N`|w4d^A>}ES)y*&0zF^bo;6DR*H?&^hmc3)r>V}Qo!t`=0UT1 z#CiBEVKM+ja{Q8Qcl6e4;H!i1Sl{vC2DDK;p1f>$TeoYY-A<&*oCBWbPg4<}BANzn zi`(C1ID-zDQv$R@0F;2J1dx9^h|g}X5)|v<(MF;Uz1TS%#FtJM3ra`M_Nf-z=t}>d zQze0>*b4>*8ZcOmmEv5@Hr*VLS)7-29gxpLTOJE#53Oz0;dRxpX&?1;FlQmV;OJ6J zSNsO7?o$)s?Vr%+1%w!5RcT*zX}VJHEG;2?;?X4^`WWl*CeKZgo*UiQTox)G%6GyW z7qI*HL^X>$^@pxd;aPfHNNuO`DyxBeWiFkAoc>O{4ar$7YkiR#xM$Pw9m%2AnoTEZ zb(xh(>9+g34VU;$h%_&+A}00TKFdilwV&q7v{e)V7sj-f%VHsWi~61tn05*0>>m|z zu^I%H)ifcAvX3xJ6q!zvfMH|6iKK(vX3t57-^d;*PG=2WSzaS?+bu?WgGVk)FSyr7z2QMM z;%O!DI36D@%2Cr2pD9Lw&P70wTTiRNZ98VS{Ot!#U!ol*Tr0`Ok3e8A)}Zx_*=%sQ zM$SSCMOqMt{;5za;Z}@50-RgB+dw_LNj2nz<@^b~s3r|NPnA7{14WJ>GDj&s=XcuY zr#3|gKjWj)aXj?s3TdxUEfzf}F6o#(nyPUU%Lw{Cpgad7^dJheMK??|Mh95&6bE z2R{sVD%&TM?)U`uD6~Z-KMm`POeX~FD@oMX=s?F&R<~Uw-iOsHiQrC^%?;#)&4@9b!uJAZ?^y0Iz_A;3q&t>JfjZQS*HEdcU_%3IJ|TPfv-)cH+Mk^qdmPHf%I3R=}~c;)uYCNyI}rZEjMYJ^F@s z6>>R@dIZQadUv4aXPNXQ+Vvz07C_2xXzD(uaa%U8L?&^X>3chLpR{UHu>7*R)Mb2` zd^N(uvHxI%N$5_(f1Ov%hEGYhsj1nuWy1N+t)~$ZGuNPDvKEb%jJx=Nz@;8EH^-R} zUl1*&Orkx4t(R`Yk^DU`A2?-i3++S>>2Hn`!+D_aDKW2@f9J%O=$p35}3V;H@ z19tz*6#U1Iu=*%a8cZIyP4b2$twJZ1vDPpo3N(b}B}@Kr^wN*>W^C;1Nxh(zJX{?i zH4tx_z=hz@ZClTQ{M-8BaG-?dxqYdP=QB}J_2rBfv5z*ncY!|9BA)2_rj~t zkVPxJT_KBsM)i;i*0C|;eb-kjIRN*9iQiMTAt(p-Qde)R|M8DvgK0={!$^U=|+T7Q@S z!EK%(w_|=@tnLrbFV_)7)EcE|K%qae9g=i12>Y%c0vcne4zL$OhjAw2m>Qr&pACw`*6R2 zB5L#bO`X6Mr`UrFtGjg@Wrn*K((0#43B}C-dxHjtNfH8i$JgfUu_o6S?WLGM0Jv{+&3PNA%bv19vta|i8^vG9K9T?x(|@X z?AkW6bg#S)xzfB=L#~guqhw@&qBTufLYnOkx!$UCAtE`)yr^-Ml#CZW-)77T(q()^ z#Jk=1c0@*H$VQMLPP4%r8|@^kfL^GXZB;zZcN+|LqeSv7N*p;-k+U~RUdhbd z*0K>9g#5~^*JZ}vXm0Q3lMVj; z=7IycI5e}`%_;!vb)8tPg;2Jq8%ctw6dGM>SQoz>z~eL1HA&J3@qXJ)qDV2jY5m-e zH{Ux~=`YO{$WhiB-+xJ?u{vkBVkS5-1X}jJ!i1-lC#G&JMMulV@AU;o0p?-=eNGuK zUtA+%Le?|4LLU08Iiwz$QtSRZg;PfSm|v+r{a47eU*a3@elV4(AQKH zP2QWian9w$0P>D<_(OCWWDj&X7S7Wup8CN91S%Nkn z%Fi95sQyRYtT!yJ?1v=vy4JTuCIsG`a+$}C>h7``c$p+WmhAiK>JO&oZ7aA4AG4!1!o-;1ppMiX4}|M3+!8w%J`+)0vg;v?J{^k=2Dt9<8`$oT z1{riOaBZs-6kJFX;vnGtG?P`@Q`*No2!ycf$8! zphaBcxY8r=S@y{lm8mgo3iLI-S5I8GQ;L`@4r#xA?)J}nqv?IYub}uLOjQv5htNYg zSu=R;o=y}^?i4j?IQuG9k1t)f;oV$kXw(B zn!H}qTHECM#{sBsgQXvx=|KH=^yv$29}YS9%R9>tYM+9xfbNKQM76L}N0W#x(|bY4 zjhEk}+XDi^a9xhIg9!ZF1Fpo(6kj65HsQNebpK$tUaJiX;rr>evI`PB&OSul z=y}nIzdJJIiX>#}Xf~UoaPN`(gN#K3q%gjs;p$7|$G2SVB+4L~VM20zd<;R@Z@F5E zO~gPq*HD9Pi=waD;&QvTT>uHTv&}`>`}$pATbr3GJ0z|xWWhwE-(*)(TT{uKT1^B4cw`ID&WhhgD^1A9Ke||;kX)|}WJ5~I^fz0j z?5$gp+io&?^Efk62RROfSy`J|z-!|gNC@twq+dFb`_*#=#!<#u=s(ff|5ldjA-)KO zqru{moP3Bkm8YME)lZjcVW`IaEVb5*50*$beUO)5d>0Xobjgt+@D z6c=R?xox4EOViB0oue(CvV%a!OWko~TB0RUpUzYs z>K#dWi8W=pwohdK0xdxUiDMOY`3Sc>ag2lj2zNn20c83HSF-G{>~|pw3!H;F)`cc< zMM@!*1Ih?p?36QgJjo&HRWSvSY8_o)=&SK3ov9rtP3zBci;4I1nOzQCYd5}r$XlG) zJZ%0MlL4dJCyai>M5rg~Kg0rwolN z0eyC$7`Nb1G<@>AFWLHVTq-oueK*q*=*4Ueylf$~40^Q6Uh)jxUy1`{@zUk;&_cxQ zIwPikh_1VjI4P*9eR;GU&@OgZXSZ93D6`e(8lDTcXT*T9Qxc78Pvv_uVRi&ZM zZSLkIZm)RBeD)Tv@^}iuzLnl#`4VE6{y`EXbdfP^SIbI$K#d{^z&UlKYWRtR{GF7y zt%@B4y|&T@;wvv!2vV(qIHrw@GSbM_hER<#QOs3zXmE9mFt)TfEJ^~ysr*DS3c7t4 zLVh_aM|F`}sCEu!vx*iyMK6G`4-iEvLXC^5Q za@UqHb8g+b@pW!C&T!jV9nm$AiXes++pe=4$zIf?qrN*#t^6Q26!%;m@Vg6CF0;H&O36dlMzju!SrWQHSU$#ATZbC6vF014 zET~e!$P*?`eMznLCdBQZu0vTW5AJ@A9+sCYh+QjH;efzHX_#Q3K)*p5(aE`=2AFEt z`M6nLWjhyo6PS1ZV0qWBtkiSX@8ENQY0L1cdVQc&j+^Bzgy?jH&2VIAw9_U9I?JH= zy?K@M8t0vm(Bo{t|KsZ|fZ|-bb>U#ag1aZU6MXRCPS6al!F7PaB|vaXaJS&@?jAh2 z+u-glclJK_e*dZeoV}~MsIHf(nR2Wt#fN) zuPo*>z)d5mgpQ~tY8^$Jcsi6i;z1$GN6@3;6U`$cb66XvO$Q*}nkh+WfDCP$n!BX( zXD|##x=6mqRGIThB;l{v*}t2qOWjIlV-<}pX-+z1&cjo3~I)lhNA%s z+-51_aDHaBE1j2$khT;h<7^a?62Jg7A~n@lg#G4e{%DQvce@~?@80%xk zPOvHCp{M7}jB0$W_|z%cfwv zfFI0Re(ly709k}2Yledr6`b#tYT13k1|4&bCT}hU@)rPFKmP45pJj%5-T>T6TaU|= zoX>6Vl3SP3842Lo*-|E<%spEi&qmHbk9=+1H?~vCW$$rc2Z&WU{mEh|*C@-{vg4?`aOx8N@L!_pEXEx4aVnQ%D*Zco^-m_%A)%j_ zbg2_hJ|@7f&&EV`9>d2BEs#d80`vlp{{EaU1)?H?Y0POy3VJ!{PzT_Jw9R(mD29mx z4?1o;h#J@ZQO};~DBjc7h}iqw?cdF@G#K8Ji=viORPKVKev5TZwso0}6jQH9xnZum9r zpbOvxJTd-a#cZ99Eo7NV<*hWrHLm|LgORH15=$0wTt|=Dtv#pSOSX8PtBD>dFqAc0 z8#MbEvh?uB`6KuN)?Ltq9o(NhfV#59%>V4cNE)$Q>HRW^)bBJRj3J9GS9&ZNb5KY? zSub+ZGzD0t4ea|_y6v?eE!dI4WZvq`U5*n=Pu%#!wrx4?A^B&K8b6bXv4fG zJG?pMEHx0kK*%Awc*gW1J1Gn&QjN&-o_6n82-tTBm_9Tj{-dG?eH=8J+~N&^0~zEizuaA z!53&UhtXwvVM~*{Z^>OVbg0Vvq>WV!KZ7H_?Gc8473)>`$u#3${u(j(=jrgt;tDvC zmz`_E68|<|@s{0jOD4Aut3vj2C1O0&_nfM{;{~RWL=$0qISzN!V$tP5{6%9zr-=TZ~sF7Mi#z68PAjyAj z^8ZXU36Oe)&d-Lh-QEk~dT^T+g}d~_g68wZkZY#HAfFRIa?RS2LgVavtRT++>XiA=OzXft8{Nl)fBWPtCmtRa;`Z^L$NYc1xD}Z0TRDuO( zXPOsnzIJ=IXRVRc)<_EeNjO;r3&NJ}%VQdk1-?huEz&&v#g7#aB9p8Fc%f3iRDNH= z6(!UR6V^Ps#?Jmi+HvtD*@i^9`I63X&DsLS7k1wUyVH6rJQ3+C z$Zb7gy92N|tt+%MT|*gkvHCy9_B5XL3$XLj9Lv^l$4g3K&dN{7q{=o`hRGRffn}O^ zK4cTn$Uds6Q9YN2X6FjT@;R3D!q#U04chEr<_QZ2> zW_S&wwf}_v-{6VRPb*>)UN2hDn--*>{gI|fjyZ6PkdlCp1#7D_tYo}bT3vBjMTi!9 zIhE3Jy4Lk89)f?l%mlJK?$|sTo<#alG_ZT^)X^`j8!r{YpPR9LJ#68>*WD;yh&k8-uF30$;rrQqp2t|F5>u zanh$U@O4v?hrWz%WRBpqB6Igcb(&j$JhTTZ24pMqRvfUM?ds?UFHzRR#AyOJ8my79 zEW_qCe*c3ZsFqQhj{ytaC*wFypYmMX8-!O8Jk;w!AM#th-iQ037mF0T#njRkTjxd- zgJLuzWbuqcy^lxS)J9<0?NV{xre+lLr)JNsZPN!k-^~xpzOT=KnxzD{t!(r2Lmc#; zSshyz9{H>q0M#QS;gSs#SjqQAF644MieQKu9a%a$EodW9^nL&GE&Z(4dkX z-@cBQ-2JX0BqYgO>pp1SeV|R5XB+Nn#mG}v=)mb|?H&ku;>6(c*9_fiyPTCLWOwsC zbgW-@ERRn;j{bJ1p;*wPk7>=TO4R*~L4AIFg&UJI_CsJcfQYQd_4OmV^j-1Cpn0Edn%G*hd#DJTQ(y9|K|>4{LON zy*`4+k}oixnrAihFsI1l7Ff?| z8FzbAmW51v{wnqneVtVG-E#(>N#_u*CmRUa*>4*R4B;z;dWJn(Hg9SN&pWg40o5ILY3K98$+HV63{NtvIWA9dN>Y?KUI!yE>{lD zH~ywVl(ND;$+tGkRFnOWT=9RrNu{yINnL(7dvNOb-#M#0GxSQhEBoH1myyx z;bvfkKBdimZFFb3$Sa>d$#oIv%F0F^Ea$;NQO0L)ID%_lJz~l{&4^ud*HZ;FNUty`6u^s zUrXH^xVI9$&+W;U2Tzxu`};`{j%l~I4&;1pR~Gi>8Yo!XEp)W%#n;-s&-)MUlWuBN zUtgYc4G@jCOa+n%m}wOX`0;A_6-@jB`Hz;X3O18%h$s?Y!^6q(P=9l^{?rZ?B9=7L`|#HJB=T!CJ$~rkPWS|k zDm#i~5~o#FujO^0tZrUdBGNFwA{hGid1<}8c#@?&N7-r>CuiU=a|RuPc()R){miQ_ z>aO)b>vJ_55*xBr;zZIP-9{w(Vdj}$$i5vr9?VBAoOUhO287ih6`?siYs=ARv+Zm+yO)IDu2?cFlC==H5?v|+cy`M{0O6a$f@6~QC6?5|k(iGgRt zEmipz8GTqD*`)nknS@2^R{w)UU!%^l?ZwS6ioGe!&50@D~G-swr`H)TGTvNIaY;3q8RQdx|!Uo~nd4UoZP7b=pTY#(;D6xM8>f=M^KU~e1B3-VA{Bp^rt19<%v*4H8-0ZDjO(@VvJ<1>5 z9H5~vfucr#eC*p?M&u#=IIm!!M?0rZq?o04hl<^?$+LImU z`+BM8yiglFy#^ED%QKz5@&7E+7c~82nT7ZN9IxnXR_Mfm(da7;K*tB&t5k| zq6dEV1a*~^cS&wO3GL^`M!p82tXFGQwJs*msGVVXo!&0lTANGUEJ`R}dhIhNr6aYC;}&yD+4a zzptsjK+KU5Pw;bIo*#+9fQR`dgHRVl#Lc0aV93qm$v`TF*ZVNFYz01&{xXc#Z|9r|n^{J|GBbq68@T{t zf{jD=%wL1i>jG6DGHxeL2-&abZImYnNO0$}eVtip^EWr`ajo+*bOi@4DfN2I7D#}n zHJt4om;4Gzg8C1MKj!mi8aJAQKW>JYY^6=M(_6EL+7e$#G+szH#aLs=K0(G-y>Ra? zK|=_0o6Rkmc!;@Uk}Pu!tHUudVp!j17|Kq}gmi8^R=~Rzc}Qv`w1(aXJ5g_4HTq$5 zu;;XU)wGr)XW8RWhAG)7_BKP|fCOX$W>2360$IBTCkP15#_$_Xs-+#e>^&g~zG%H2 zb}PtpuN#`7t}7U7K4+Ep`9`?YN5Q931V&ZrWJ0Sr<`0z9GB_=E)i73O@rF;hAj~;f zoc<{3DxhHoi+gu%_(RfqRvFF9b!~>*#XbtNE@_v!lVI!9Ho?4WXa62eH%RyUPL8^P zm&la3>J_9a)9d?n^V4_#?jKlbCaZ7uP3V|jVC#PV?&oeD2tqWv*`1*$NOZhcrQmG$ zMi8(i75gbj2dY{laqYlVmgOg%vaIIq^6ij;3|Z@A@p620R>rDdbz@`J`9ehln~zqp z{qb+ES}8Tmvy0Jx_yYfNC;$7z;;modJd7H{ufj0R;%*BzX$&Eo)KCT}A;F zrP?Qw-7*F4rL;H@On4h;D$_Ptn!+2`JROXmuSCoS^7B6Om@jfWSuj_buhF#)p-r&Y z&ToD`su_2Hc3CreYPCA599K@`b<71ZQ0jj(i6-+ixmiUGetJ-7b=+Usyoe0B2U0We z4M2Ig!KwD`M2HlQm7yy9wjlE-NPcSNj56p=N#A6C1RNlhhF=5Tw{3^`3EHk+;??>! zgmsf&zx7W>Be1;V)0nmKTOGl2vT`V8u+uyfm{e8sM~cK09URY)&b#o{#Ead9`7Qb~ z88jD5r%!f`F4a++*Sm3So=-iu!Dsl1P~fDIiroE5h;vmuH6hH9r1yi8oYy8SRq@dD z2uYyB5JSsmmARC>%^I=WPgt9l<9fi=piqR9=I7G$Fat7f1gG7Ru2#EP&_Pi_Ru*Sv z`(PtYI{!ux$!XUh&UoCebozjb`)?S)=9yCCZF_m+$pc0mvhzxQN$>M2a4o>%qb2i+ z9~{-Z)lLF7(<704o3WZRBSTkH!SR}*yV-v+%id!)AH58C-Og(LS7ughHBO66u?Fp* zEjTEmQ3w_fTT>lj(KFNMw=?B&fvL#dYk;kjsBuW^aN;H@e)ksH&?QqFMm38VY>k=ZtjX!0mN8POGmn zD67W9wp3J;(d~e8WM($crVp7y5VuXTb2mt^Raj(B!jA1$hx(+(hIj0ku%SS2&f8ij zlz1}y>CrqBG1VXmJGCsg&}{saP3$QReG$jf?JDN0_nCM7aFz5mi+KAsr^D*qi#9l5^LB=x{j z;9->(T#(^IgrQf35f&DX8Na^BpHU)tG?P2tc0!OJfD?$7CY^qtqPnr}?)t2;TOoUp zlDM^h`^{?&_hDwI6Em4vs%+M}VldN$~)q_W=K0;N&JxM3&~} z?EywthC)RNNctzfq#ScdbCJkN@$Jg=8zAcm{vDcq2t^g+edQ( zf$Nsas|j?xvZ5}y`X`HdYm7V1A{U!WWk3D|@6Va0nT!`<57{Gs$O=QGpMHvA`4!p2S70I1|R*t`bh! zST>Yo6iwuTE`G*evm1o*ZiAwZ=!z{ZX-?DIPAlz5jgLAVb7T7{A#c^vT*nAFOl7Q4 z9&Zp}h|)zJ9VOOt!4Rb_pwm2`7;*;S*<(R&vbfp9#&w!$!@xsv6Y?Rt~ z0@Da7(xSYajh*7sZN;YwNP|Ra?kBR}sjeFQm?lfRZ!akCgBe0P_Qyp-b5yapLP`QJ!>TM0KszNBj4eA| zgh>>2_gzcRu7c*R4`*rC zPclj9h)tHLMMB6TmDdT!t|s|SjmWmKXLtc$P2lLDE;#*oFKm63(OkPg#_k}ul7}U` zrHS+K_x=3mq{tN=W+;wo?E_!5Fk%J;>FqP6ni6dQ`a?}jCedzdnSpIVYWb^eRZL_J zF_dqVO8w)tp`BYm7N(JV|8n`CR_L#l^#6vUkaFQmIy>KDMr2`#{qq z4QrkGjU<-wrFrY(|K?05aQ&7~(QaK;4)Sr-{#)y@+khJ?5HPvkiVxs zA@DjNHEVVdnH%Km)6&6pJ$+=(DS2@y#gY~0&~xf#EV8UY*UHQpD(mutWm3Q2cpqfR zxMf`OR)5&Jm!HXYWCr$7_o{cIkP^6V9e4Z#{AuyUy}k_-cGn(&4d4;ynJu~t&kM#D z2axKTPxliheCyru@E;$^V`<2a(wk{Z=j2-JBB_d!FZkHvqy4P&KypQ=HojTgICAgk z`^}&nZj7k;31&wVwkantAjdtUHEI2AzSHFFB1qX{z%QKT_@Iff{lv#}tm|;L+|caU zt}qZf?7=p@OTYgEx=C}aY0)x{7Bf(=;2@~#rb|gGKi#g@<|G_?6t>X z2nARP>oAQ0&pnRPRNk!9!r5F@+UIYB9(WuFWmJid>+p6*lQNAL{t5 zZBN^GA-A72FSq01JIPl7q^x_6cV|!c@PA>5{=ZrPOOeQ={K7aH5ue>fKj60}zgLS# zbgfo_nMc7t@tGsw(uO9m<2_JIcA`aYDT7HwwETE2<|DCr%k{jIxmGgxJSAE7!vqXW zz{`zxM}SKx>_a>8lgV0iIS{Sw8*Zf3&q)G{#ZQiFhPGKuN3j3w=t4PW6tG%a^z%a} zygq0T0U&B(QI2HX+X^UUg^h7wS%pbOD|>br5O4&dTPHUE$!`~Mp=9XT{Y4P6Y;%-b zpCM%5&F5>|GWHYq8V)f(9HCX$dNy?byD8oGrkAZm*ZXA0`cJDf<|R#<6(@oVRLk13 zuu6j;(Rq^j1zF?)q=SgZ={tOm>soK%SRLe~qGV>?qv`x7 z(Qf3-V14N>M(ClE0q)?=Y(?TIMmZHHI;Yah!#4ELQBPDMeI;wVt`K-!`LGs!p$FL? zA*XyfxK+}*dw>FoUwuGOBjdlQkN?}>S%9B#n`i2N=5_F9ek>CtZvNp>i9X?XuC1Ei zBmLI`O{JxzPArka-KFPJaZb#3v1EhNfak9nZ;lql=`F`%^_A{Wl}@)hf8be_`Qc(M zc`u2dc6EjqZ*vk*Yth7=f2D{4P6@sns0PTA;ZJbP@9OKrlEB3`*6ToIcWB4 zIT+NSFG!KRLm#xAtU~l$v*8>*<(-TOk32?inIj=ya=l-uBO$nXNK;N{QMP9aaZgW; z-v`;5)ik6QuS}ntWriR?&&c9CnCFw}4xOJ*Y^7iJJ|L`r`8KBZFSr$FL0GA{_~ED_ zwjPciyZ0_b?ZftbKi7lJZUdZ7_&Zpf(3#S9C`uaa;WtaU@Q~c9GpR`Dm^xBiueg-l z;zB)HQf+*{T<*{7!oeRz4tQNPJr>U{fwKLBot#rW_f}yBS=Kt6k|h7S1#Htlol&Yz zwK=b)Kky23W=l=Y%xWT|bXvb-A^Ddqv1TF?K#}S28jLRP8ZU}`ewPwa3J0JksD`!C zW^O4?w{*<0tpvWRJ#}AmUfgt3{_w!I|A-wWBj9LPF*YqjWw(e%>;KkRb^PgDIzE^? z$J<%@f<m%$6Ql?0tAjGyF&QGtdz1EeBju5i>jQ0HQ0mYVxtIpSW_fBky}O?nFG0kn!S1R zn>1!+_@FBS&qPA=pBVoCocQfvSsV>)=Tp<;tvEC8N3>f73fQuBl=B6nxG~Odqj*jB z9kr9*s&XiTM@FlexBG&v54cXXzvRWaFp+DhXe$-c>HP`4Ccbv8Re1a9Wg$HPAd>mW zM5#P}OdBz3h&@u=vWu3E#~mw_-(X=HlhHC0Ap7t~`Lh8kkz9Q05M*U}caP&FPoX>#nxP2N4I2#>9Y!62@$eW**fm5FjIQ zq#fG)sx*gy{%2Q?x6j6y-J3rmr9C&-e~oo+A)qQ3;c5KjSV1lyN%Yq9hpWyO^|4k> zs;))fPRWdO!HJ)@neb_RPM*U`w4UlK)XuR9Rkuk9+1khEnAP8)0)u7e`_d#n;}&zv zr(Y>167L7GmQxt9u}mS!Kh|;P`tc?4yM90iJOTF@Ou>9UTi~Sf6%CD1Mr)}f9^*=s z?qN3VG|N8tt+B7UN*&pj-La;fx#KFe`_RTB!^xs1+DZeN%o$N&t@ZF4-2{G1WrCUt zgd=2|^DLjS0ur{STMZ1)o6OZV=JBKj1KQ05mO4h3xmfGF9~|OlRsec`^+8HjF%z4o*7LAkXknsu zBc@0!e=O}d_J&fqbV5Of7pycH_lR!6e$8k@i2|R-Lj+QZ_2p-$uRjg4M{QcmGj_IF zyDX{Icp?sgjDzYE9gi!gm9H<4CR)Y#;RI}*cju7vr%U^{Q<}TF!CZZ{G4TG64Dq9A zf1+Ed)f}ve1#aY3*n8aeHl%+P7M&B|f0OJZ(ce4zz_iKoX#|?Gi&{9gXCrFRt|6*`TA;FJ{>^`yFSY^r6 zFGGU|VrLSla^V*0!MTlkGca1vnoSXQl_xRVI@rwfgX5ziFi7l= zxpzA2R(tKI`rI0+b(yPIXC3A=RT3NIoet|E&YYni(a=F2-J^70_enECbC;jg`6jRN zScF1Ww2AHdjSODC8IFU`Y!Fi;7M-+sjigOx_@X~~Y_@<`@L^?LAcx2G|I^V8do{?8t*Qg&8g6bf%1eAGns^{HFo-j&x@yi=u&X!qh@ z`MsGsP49k*xFd!$?QGl>7tS&*+{0N=o4pa4YxGqXcXhf|N3WQve{y(D`)A# zz^sbxqm0y->3T-c4mfn#yJ$_qO75f8ksHn^&!dCMF>n0Z5e}D1Wzi*Pl6e zx^lf3TCJTyHPj%5wwJ^ z+tJ!9k8w6HfR-xkGyCf- z7?XNm{Q+!-P@P@R89;{FI(nhs6pkVM^hO>U#N=J`Vp97!XT02a`q61eVJZ-7fGj!` zhc2v+PE0UPfXsM_oS{*=XcQNZzgHgCr@mGuYyqmCxEA8 zd*7bPi@e6Gi($|eyLqx_zF$Ce;`wEX0a?JDzAxJ4&S+12%dq-nbh}M)3FL{MC_0$T zg>cp5k!2+P5$E75bGp}ZRpZg*@K#_Lyj{n$3#rdm(M6O$(oj|5e$UlDCGL{*t;ms;A8=gV3~5}yfe`{Rv{`&-w6JNpg{vx0>4lJRV!0W%h~t&>Ga)8-F>fkpim z;nL&F=F9UZmr}rcYj?$$vf;HAJ6DR77MJVAA^ycL{M~=k>7kIt|8;!Qq0WkuRb=R; z)-Q`@-4EQ0(GG$5dZU&5-hD`Wx?DvHPpvW+%U8tzd0A(P0PyNXkeN|8Bkf@1ayJ^E zCZI5$SZDOfmmrDH{EdYgA2#J!)W|^aOA~Ei(TI;iT_wKAkqaj z>7ieT;GN*j5yMYEN!gRy6$f3H*WJ6T1XPEE3f_Lp@s1FKOm}9UBh?S!Ar(BdUkb*T z`8_M=%c5TdP7}v7_#I=Dka|}^a5YTzm!fE+_i*v7}D%2WX z++rg8&iLXpz`2FB@i1_}VW%l^=xWS7#Gd$WVfa3M7y7r06Qz zFir#C*q@K+b@Wt>JqiV-oe2ou?!zB>-C^#Vz*emKBJ2A;YcQ9wc4nKu!nrPkDc)j` zzawg!H}1@DguDoV2990dmnL{C`Y>xQtr!OX4g0FJ!?HMN@mXos)<^q?4f6M{DW&v- zLkB<;H{ga469!$6Nm)YM^v=bjD`Xr{VIvWahQ?hDfbui6!yklS{kEbaXE8;_3UPMd z*>rKYlG$w4!j(L9gZPi2V)JD6rs~O`U%?@^lvlrBCb9$077A6YTJS&$4~1f-eDzP` z1E(Fg?I4T+2xX4tLJlRV$KVGy1HwZ2q1a2?=KcIVT~)$bHaiPNQ&Us3w%rWR&Fo}YpYWm;lU?fxPBRC`v4l!49JpE_%#zdGFk zKA_XT}uzgqRa53BljgeKOxx!(!JpAf2Cnsw}*9q+2&$x8FaT7yA! zS;Ml#o}5-wmJ+v-je3SuWbfy4XdX%s4VyWqaydAulJi78_E%q>flF{n0#@ashaHW# z$_G{mTzf>cCWA21EBiyi@W+>XL>lzdcUUIknjO1rUt4`c#Vha=?aR1S>2BYb^NLF6 znmezzli&{vAXif)^by>;NSvhBmWlfevl?CD@d{C{d@cP=C^wpzG=mM)JS_u6wW*^$ z-0FR<-%gtTvoO-)%GUQ?8ABcas;5Y&@9Yf2YH$)o%-__54bDKfP&R~lUa zbAL!q*Xy_ra5HZb8U6)fh&$toG%%2``t`-_dIlIUwSRhY07!6aKZV{2FZL7fv8Jd$ zU-so$Kjd9Y=%sR(U>|}Bq$}lP%+q=gI@Q6*z=sw_{h zBcFCt3LCy4e2$G%499VT16jYEA9SoQv8{C%6=e7`NkvJ3BUMtM#H@=Z`9#(`rRDTc ziT5v76i^mwm~fj%XcB#nv0NYDvGyU#yL_C(3F)AMC^XsV;czs%&|y7@)@fxA`aHDx zCFtTe-9~bvK5W8o+)a*~nKH6z)PueB`@hN{YA-TidYg)ro#=bJ@ zcQ#F3e@)r)xj9_=Y^>r-g^|3hL)7!oJDSFaN@7z9vw47YqVA715YcH}5s6KAHhe*P zVzT(hoa4jT=9H2En(ti?g~NuV`FgiVMii%#$mo>{+i(2@KD@u{$r6*Rm08X;MmY!hZDV6T=%9++f|VD`I1Sr7!agP z{LIA+rO)#mY^ti~_eJhaHwf%}H)#j-|Pq>)|yV4{*hr(a8UO%wQTeH;`jG$p>CN zU>o!a-E-(e3McfuVGG{KMkMdOD&myLS|UZ=#e*a>jddBIFD+RN=Zu6Qs+TKP03QtT z+58)uL;J+NXOjmu@>?iA_8X5P2Zuumwc%iPHPvAh&2LK2haa79)6bVpFyu(Q*IAgl zP#X*a)NbN^?=jU^9cD>y}**kqq^3yU0${E~l7uZZ~sp!fr z66q$ua+_S{lG1mgh!Qx!b^raT-(&P^8o#rXuG;_={j#ZjFVD~Vt>k6%Z_%-DZ~I4i zmm>-rZ?BOb?@B1n_PjB|O0>cT-PGCnI9b7-fwBW}B)w>5K+R-CsISN`2=nOrdtB#m zjVUqF=t`lWU7-O!egk7aTU%dlAMeW>p-ulH4jofR z5ed!rpomvLqsJ5c>G5avU3>lKRJ&FzlYS@;W%e}MM+d!M=yo}vq`Vo09URMu>ne6EbzGvDXP+mAW-9EbDCZ3&9MfHN`UeK@!=Nm_RHjsA4lEc%t zUThhvd<@*dxOUAOQXmX@laq|pgn;K`M7wC6S1{966LIBe{k;2}o~f695S&j_rotgJ z8;#7<{^qOsso?q%;{ltG{!)q})eo`vm>z7CEtnn^u&TJ{uZUO(-#fTq@O~7B$SA8T ze-ich`ToZn|L>m)VZ@MrhIPIm;R5WJ9Y7R>EuAxub*%9%Hm?_nt` zQ?NtyZVDb7y~K0jZU;xY8R#-?*jDI6z9IeN=wwthRH_boP$l*C3YnVW*xFm=7Oi*n zK)+dWHR%6ZHS>R4@T&;9;Mkx>Dfawb{MY{*?99N_osgoQKHu+vrH#*U5HAQ>X z6t{S{+7Ghx!R5}3kY^LeCV4NUzh7z^B&XLQ$dm$*bW*fs*%`4FEzr)VtFZAuQF!}n z-Rnnk;ZBhvk#k{%R9%O!66x_Ip2&r+^la~P5`*_U-P?JVJ-IGc#SI5?y{_wPjl%k( zVxkLpn^tUu@jz>IooCKeYzaJZI{erVYPn1y|%3dB|`TvJ&>M-jbJ3Y*CWFrv@a#{o530i-w78Pp`p} zK?YKZpD6y?DgQidaWq>IYgArjo@`r6w_O6qf2!ev6tBX_8GzHhsC?ycq`TN1Uc_47opmlcAdwv!l{_D{(W-{IkU{waX zs2g+3YFI^dMOh?D6uE1IhHMoNS*al`ayd*|?fn=LF){sW%YM7NF&khWcW;%?hK-2p z%oL87x28?pP!2ITfI>(Rc~>Q3G-fqB1H$Rt6v@du+Z~Q0OeP=FADQl?>KsKvGJwxq zVw=FSBfOlfrwUy6#^ck^O z(a0Dm%Wkzpw?Lg0UUPOOKN(1Gj4s^f&I^-IbiTSq{_eMH{&rieMMaA>qvXxNfo{b) zH%vc?m;NrRmhQmft#%r#OIWeabhHGR+jABd zqa~OAHAT8+ge!p-zDqUGH1%56dWKMqL}DFik>#gc!!p>J?rDX-c-!C<)-357yO@wU%Wym zIXc@u+;+vv*RWCZu~f?X7|RZr#}jtr#+aZ{!G@c99W4LeWb?FdjE80-8DVU^ZUe_{u4@{k z!7RGcE&PBEv;-0-TV*DGm*f%4UL)o}??IqD`DT-O>Jbh6f1RwK@J9uVAwXgQ1Ncq9f}6FVyEI|Zdk5s-82 zdbuN?k}4+E#36H#OV0}UG6X!{ytOV^BgnD*j%pP7MLU1EPAv2H@vO5^Lt0->6hR-u zp(ks^7o8zK(VH1kxN=luAL?F8Y0u{QDV0c#bGs8mmcy}$Ji&L{AIKvk%2gb1lj%>D zonAN$2-`mxlv>Ip`q&@amp`^Fq5FL4UfZE*Ld?VaCvpG%{4NE)nh&MWOQw|`bYhKvj8Gl8`@%?< ztA~NU7MR#M9~Qhgwylm&K$ajGhlhJ`%MV(Jug6flWJ2kWO3u@BySGiuVG5V;?ElI$ zUX+@c8;jp^7D)Y6>`_`WJT?E#DWJTy^a5U`wU4>sRMUNiA0PUwekibfk0cbU7DbKq zl%HwdRLCqA%fm~2`iEgy_rcI^K{7B<_%*L{XSTTx>`E|QhOe;^u1M^y zM_=h}=6}UhQQcf9=9?`48uW|4jW6gI=FK0iu{9Zow^J{NQ}^i|(Gn_2k>xGi(G0VF z-c6v>G}g}Oitpk?it_4zz>$@G?)Vbyx$qYWaSxU9iRRV(R7?|g!GP~8ZswOe& zm$!7OG)T`7;5^F?1Ihy`Qnj$`_MIK1^-Adcn1PY5Yzc_%!!%$(50J}zXTY2xWzr7j z>$)dN>+B=Z9_-4wW1()!fxhY&D%f~m5&YZR&I?mpNgcz=*rjsq5-YR{h*Q7 ztce7N`Z$39$Fy6u+wOd0m+U&jWBA4D<}lbY#nEBI-J4DUvhWKa9=NtJP1RDgJ3Jo+ zU2=zEtIp>ex#Rb%KklF~%S?8pL(tmEMET_OVs@JHRQK&R#^G=@L59b57|X7{&+@EZ z!e!MJ4xN&-EQ@di&h4g{7EGQG%CnZs&tN0c`Y2N`kk$E~+^jjqIgcIlcLJCkbyS}O zt1<ygn;$XdJ2SG%naa|iEY5mzxjZLx)#B6TS*=h9K{>NzNDlPIw^3vH+^*7rX`^Sw> zt!08GI$rDT)DY%mnTe);joet-uR4<;MqhwrAH*6p6UxUwhp#gzSAvq8`rn}B_E)yi|yEhgxvV+ z<(<;nL`!^;*g^dP@*IJANA7J0z?3l(2?`+*&AK?1-aZZ0YiM*6MAx}(__Q&X@Fj`U z9R29IAfBxK;q~Je7gUXZQNG`hO8w#SX>F3NXRkPMeASjY79?Aom?%C~Aic|8p`Flr z4i)Q1ZTk5&@!Faqn88QfBlT)dOqM>1v!m}jZg|3z|F2rEI)_}YpiAZUc)~zsJHT9f zOy^`oCT#iv(7;;}G_<3-pdwPg!lp9x9x2$1MwIuU!J!Rzjo)DPvk*Bv1YxR2=%!MfXp63MDp$y$%BG@E0n->{L1Z2zT#{%QEp&>CVy*cPwcke8<4 zu)zy7bp9?8kGm6Hr*0q@(@3`w@bLc_it*l`RbYW|KAb`Qg-4XgR^g)$Ws=d{r zjnLrdcm;wksg-S>b-1tTL;WNRx1r$yiMTtzw8WaY`^ze^}C+vWBN`f&B4pMh_g5KvlUZY7w0+DHn*{7V{0EZxPbDd zjcr-If!^H)_AJbAv-v*C-D&64g|NsEQiN3qVw~rBZ;L-n#&bjHD|MG!M!#~{@vA`+ z#wXJCXX7n5mCUF1ew4cOY5D44%$xP|j`u1DZwjWg-qjB{1hNMALaAUSbfqCR$XR{j+dV_CzT!ahd zb_W>iFxJP3Sb5VoT<8yN+FEGAm_idBVAj8`&td;g{|=+!oasC^aoDp-PIcse5eQ}F z5GH+D8!>6)PdH9d#5`nYjX(w^K@znVa_vckE08~ha(w2FO$MaIquEoBEfqASx3j60 z$hKQ>#DbeMFb4X59odEgL>e<-${5=a<3hN3l9)}OGi6}q*!lr_j9^I`Sx*~KSR>`e z;cj1ux9)E4eb6+6nh9DMMJ^a$=FNLjf{k~(b&?I2sAkiAh{CGA)qNJmZb2A+}a zw1`+oIWBssjhJUo`!Yv=ATI$uu2W+`aM?woo*IW9E*d4OQ2U(!FdS~f@Dk6YzZ}Lc zbcTsp5(bejhC`*(>GlEqyX{>i6!_~0|()K{Y>Z?!Cuz^X(6^&P< zT)gDJ>2HawXRN^;`uacDs7kMo0hg>@$>u(pn|2v05jBydc+%uxVw+||)Zs6#o>mz2Fn}iPsTDl9nO^3up500wY~xy?39>!xc(HPbSR%4_|K?)mGbl z4;PA4q{WL06IH7ldY#PWTVOvn^waJsYWb$VF=pD zXyuJMlz0hB=CO*&?$Pgj$goJeC52d0v@qfrx(bc8|0C4XsF`u}(M<0JkF`f;#u07} zadccCV)FsW@>qmO|9T0JCPxk)rzNo(1@iORyQ zb5Xww{i;5LE9u_Gb{tFzwRt17qvBGY427Ur1(TcbR8NQoE~4@e0QsL*Ie7nA!BEqP z^TQXF4sfwoNq1-dh~}xXBMfP9kLioBuK(ASl{cax0ZF4#8RcIChQe3V{wZ0&+a&3} zX5bcs@=kA5**mk|1zxX{yui(xp`7j*3jRHOwO2_hW=r+9H#b}HD-TG{r-%R1hlW#C zwK9?334dTE@D6vCijVOHIt69?`8UBPpoQXA5avUqObA9^4R965m4f^5iWrpM%?#@d z;a2nyvWOQY?P|H;8_y8u*3?NGU+%c#{_^9W29n9;+Ogy5Gsc_VCpQd1;NV}BIM}X| z;jYI9*p$h_BiQ45YK$^kbd9!U6%@uilNtME|AyKC!k`ab34m$;gAWS-1w)aao8rAT zjSpo_0>*v-%d&{Q!o5&&DT`9=PGg3}ZmG4tOfkNsOGq=}A1l;8GNHjsyZz~q7R`SA zz<%|(p|B8e{E^W(kklVv1VcSOC*(Ht*2{gjOk}T|c5}1LNwzPQ-s?Qu#4Kg2D};#a zh9XST8+X6BJ=EA+(y-bLFg| z3nu>XEU4Udu9k~P(*f{9%To40lRZd@VFk<1*u^Hjv|Vi`Tfff+;8{S<^RT%`h*K-nXwTA#E<; zA#wGI%JnY(dD%f|4Q+?&*fAAibN+x(`B#!*2Yp=Ux?=y!z4x@YD4LX4eF-^rX6H&z zR9`vI8>w5w=PdW87rl~cy2EQ)SwDMy(6;qOxzgo&T~VrzquPe$|_j-)AWSv^+Vbq(F_-9@0tA_0nPb*X!#EQyU)qsEr`oXTL;qMNHot&BYtBQ`zR+jRJpVjK1tPtLla1F0!N! zUk)@Bh*00}vd>61Yrb@_Oj6<{Ah z;9E>!PfPcjKeA=0_z^gDDg|YJ&5r$JYNQ?OYF7ll|?F^O;v%)-MWy*91G*UJwcBY<_^-8LXIi;P`VpoogS zFXvNtG@5%}9=h7#{EEevpT}R{v|4d$U#=$J zLfa~sexvLaN$BtIpH$6QR3EgiO!JwO8&lsr!|39B(qPoO9-^*P`$X%wS+=}li|u(l zN3zpTzT)y&^y(b@vWlT_lbFHB;||O?a4s3>3r5_sqxkY=FI{^=gB$UQ!^X--UBq@i z;CU5AwBy0}V2yMeO&86L7=*Nx_w_1vc;-E|+lq&BIp|||L9tOp84b;6J;T1H*KJZ? zm++JhSBV-@Lk;s#2oMJjnQk}#>}KvqTz>4c=<0kH=)Z#gFqDRk0i0O?ZIc8^~sP(12<>q9KxmfHrW7p+yZTN52%A| zTD~pRGAf0|W4Pu5X(Fl}9j_nFt?6x0QbayEzt4Wh#XR#p#O?6-}AkVQAx;qR00 z$&W%KDP1p0WIXL>8N`kbW=e8b)G~Q(IU%MIf9iio%jLk z9RIL9C%gd~-@~A#eSKkLOgta#@C$J)U}LeIJ@sMN`J~suPRh)J%J1}`#s6*82BvP4 zPyeQV{`&z5#=aR*pk#GD&5armY2ucnvSr*N9{+9#Pugh383Fby7e zSQ1$FgLQaWoR}W!^Jk*ch4##B@tj3#6bgp5By&i%S!Vnmn#gB4+p)0SZr0I4JJit% zDZ0b(gAbAAsdKzI7}Wkvr$%2JYF=mg^Yq{e_+ zX=mZ(G|$ps1f6D`{Zda!s`qK-rc72Udth~K8ReA}W!O`KB{E)vIjiyBx0{vR|&pamiaqY0y5S$DSu$rTC7@#X*y_3kOJ1Gs+^o3jc&fIcv#S zB{#(Ae}+{H^(vwCzthYA1H8C|JW!_QfYQ*(4xf!BlZO{M5@#%YYB851v$ipXxWti+ z`XZs{pRFGh_U^|pGZCQWA{SP0+9Sk zTKHLC$`l-~`(53VvCIiDG@2<%+(iRUR*XFQ|8YA#Zh+BtanMki&&zRBpMh_&CW zn*e7*$;|FEs$8#sc|!e>KCS6hkGnai035=!hZQS3Q?@_VU?7G%D5%EF<=MC+Ew#1S=EBzyfg;u* zhrNsJP{~9v-Qh`os zM#wCRys7POjSBmd+mkkTJ%@=k?eCMLIW4Sd7HOxIOIvCZGcA0~h1R(iLvg7|`&5y3 z_4YKto97}sSW&K|Dh?JDebPQ-)C~Ls3beo*V`Rg)j<0s+-sMfOF#prxf_OU6cSy`H z;CPj7ZcD1e=3H+jwdNsJ6Upf}iyUzgTLKj0E~i_tG;7#V^R3Nx2e_b~Y*Dr0i# znSmU?vytYDQj_MAY+qM4pzCv25)%)nXOtIvA@NM=gE4j{d?o_bC^eTKvUt4bF?Wf7 z_mW|FWu20_>;u6}HJ=jhv_6yw_FlO$#oupplEI`nf>dGSKI5GBw=Te_?wH2N3Gacx zg&<{8>RqjWF%>`Ri_f}s_`i?-x}o#2zBB}Gt;#5`RVimf?>Z(=^>+8a%r}S{IcB07 z=;)B>>$|wER_^?|+}7`4+7=vWYdL2e=s+duQEQM~@xB(w>S?EmRzNjLA0qv(1JIa` z&7%x$^W%zF$*fchbDyQy&NxriQik%%sdDwz8=f~s0fzb9w%umuKV)buxJegzoUR`4 z#WxsyKs)*8jX`BSKp90TzvaKLP7z1 zm&~5zNJP-!Z;@}ZV9+Ob!GY#xB4<^EAiZ!xWM)PlSG22|A*~q{=!(hz{>mM$lFY|B zAlhctGk+|23X)Y;R_0w*ICsTYiVa0Z{ z4E=xz>_Y6#+M(Ff;<4x%x3roiNq6yLQ_hT1K2uqD2){Ke>Qcp+S ziZ3ekFA~d2RYb;}?N)76P1uKIjT)BKE zoN+Kc?a*2PC8>A#jt94X6avEBYtnbuiA4Way0NT^&? zXtg`#8IE_xVHz}9l5OdrXU416LkSz9AS_n!b3UiS#LvcG)%uTXobE(gAIG)(g89h* z&R~@@p{W@1*VyUctI=ItS6BPi9DFO+Z5=yvJ5I$O4ITViD`6Djy5qgU-EZ4vjzz5U zwJ_r4Nz=Yw^aV9_r8spCbKc_^Tx5S}`uHn@7{T7CODisJX87GlxnT?Jg4!cqp4Oz==K1mK=PEwd)`Z8hl8&6_ zx&evb!^}cSm-}zVDm!0D-|tx-cKvjLc0CA|`im+KP z11z;8H#drZ#DX~c@0)Qz$~(GR{A z5<+YENtvbIXne}V81swIv1R|}H2z}t$~Vy16k-7Z0TaQf&cIR#)(67FkZJ?s&-XqP zGRAna4unx#p}PaYbk$rnPYy#@>p|~={c5*S9c;`FCR3g)r-x6x7w!%Q3O81eLb%Ng1&L;TWz{wv{^=4o9tveKztuR) zl>uR>^8JfTgBffZs?F8Kj4QyokhhVbh({d|##rV2#M;7)N|7S?jUg4;DrxO7xY=kVNnFvozVL^H#;llElW|5WCbkp;aSHd@ClxS=FD7D^cTA_skf-(@y1oaBZKnqLR$ zHvHc=@W0#<4T>+1JwcMM8!S$~HcK+w=tR`B44+Mm#b6*gi}>8v>4yos2n>XU&$`t! zL-`An8l=uiRYY9r_9Wb|$D1NEE6?yKCHs$>>053{lW+X74pR6~3T#UGemy?w zezDd1-JairdF$@G5k0D!70gzuXx^bt|Eb=Vnz< z1z{_jUf{sa{K(j04`dgwa%Mi#ZJq{udqo*XV~nfoLQ@;3c%z+hxiMQ-BEFQx70Bky z-H)V3f}caLZ!%B&Bo&Rcke zveEa%3g|t8j1j(=O_v>^?Ix6|XA$BAy=CGx1l)6tub+eq`pLDLOG$I}da=cZ6B23O zv6CE~@xMzk_F|Do73$UR-;he#jSYWa{AVu$UZ60ep2JoxQ;fnWo!V=RR($rFYK#Px zW1s)`ogwe|<7;fM>#Et{6+HQO`X9lbN$t#n`v1QV|3HuG@}x>OtFY*A#7lSWD?+M- z9#)EXl@Zr!!}cHBK+No7QgZF0Vw?_@-{9o6r*T}C+fUOWf+A3el%J=TwJP*{OmJumu*&no9vyS@`XJ+%y0M&X4GtHN(ec{ny_WC~x2 zWQKoIV6I`G!cf(IpV}+Bmo;S8p8N}b)*&ZaUsqb2h2prAK9`5mxzf4xRUf(dNXMp& zwsd#os2i(sVcGfrdI4x#{LRa~L0e))nO$!VE#Z-4f0T5_qVeBU!0D9{#noL}$fzdm zZxH&<^8cQa{CXMEyFb_|zN7zJ1y&h7im$}@1ln>tYx6Q#NIH($v5U+%%Y|(aQzrRz zq-FMNCO=7Arax!AvUrUdp^tm1kiQ?%sz|;oRz8G}@Q6C+jLE_(8oKG4Q$d%Gu zj)=Kgv`#LYX9*8#ad2l_c6>mls<+3U%B|AIq0JU*^8QFYzQC>QlZb2bx{_mTKDrE9 z%bU`WR^aR7wR_4UyyTD*H&xIImP$Pt-s+C{_V#j_szzRyv1Q(gEm_uGRahHT84G@Z z(&2ZipSD5QWXoI0N)vb)7mrKjdmZAR`4PE(EDw>PgBao;TSkBQb4-J--ge&yG!2E7 zsQ%3m(V?b_ z_8$T#j*Ot;_@%7}p-knof@2_lxQarmit#j(&O4!GEmG>5A61Jqy{=cTzp4pa=)1nM z5}X)#Gz^sFYTjia=F@g@P7%6o@i2JSo^M6CFu!W_{84QaW$hvm7=%pLZM=l9R^g@0`_EiHv0+T z3rlX(2?z_m%9x6_)y(Ih_NBrdt3N!}P&U`ffmLg|Ne!LEyo#HeIn`d!r0i1qiPJ-hXkwvJ+6gLdV zEpU7ZaeJ!4Hs;BCGnb9E!BVx<=T$=zOmJlX+?X5ZRD(ysc|Nill~*)Wi07*r*)j~0 zxToXxpK6g3x9F)&P+$PDoODLivx9McN;w{P5f)?{HTcfkZf$=`qUFWpjj<=GQOrXs zeQVamz?lc;jm~H%+1d8w;afbMrnKAPxvT!f{bORIveYUZ%2^S=M+)dxYk2km8cr3z z1@?G^`_@vAEf>keSpreeKI_eh8ME1bpw!U#R5tX6BKq1&+hPj$@e2WRT9#4i?l7l7 z+tH@-WIuK>^_Pe1jwe5ax+BGrnuts7cEsSA<8odJztLe9@LHK*BNH5ewk^AA3n$?OLP?0+>24D-wXvtb5(VjBAR)_85>Y3sfeW*Du3Sq6#3- z_J*W=MZ0m4Fb>?erK)~JDGwoGPWS-SZfqEkUnkrpZ8XK-Fgb~OKXLM~Ajn~wjbN7hdB>}VdbAjDA@5F(5D`pUV zQu1O(BC`RaMAgTm?=z=%ST-o(%NWGRzFQj)p6fsEujM4eN1t}Jp$7Up(iMTlrieev z%ye0;qFvae4PIk0+?u&iJFl9+w@Ufr-c+TtX&0aW98r-GQ^FNBYGJV-_wxsi6~yO) zCn@vJF#vV7w_a|&;WkS(1m6W-i03V+Yps4;ysPNo%=Ww1ic#^9mlF$Tzgm0h`LIRr zxBM%n2!G{dJtA_!`kY3jUR}uwqCIoF_qK7oPgrIXE63Y3Pz9eFbv(_`rY3|Ld5z_ zAS5kNG^KjXs#oA>0N8lcfNXZ(B3d+JPFh@_EoCiW*SOT1l*WU5CM(N>+a^ZlVx;k} z^{4rhnTYSm7y3(PBBDEr$y7bMWrs*mVE@A_62RaiRm;gfU}gCkei)qPc3UXA*x>GR0an6 zLa*DraDqRk;dz_y={mJ%u9ie(T;{0vES`9tEuZsNNQj7VUBxY>oU1#hBmDY2HHR}d zZQoYQ>csD+cjN4>Js&EAim0-F6E}2E|#Oxcpb}8 z`FF4W8nV#sHRbk^ttAf4gNiM9?+T&p|p4zH^eby_ez+V7aWZtD)t-q{N#8U z^<|6VCC0(!4ydn_5$DgMREwY;5|9cT9JKqb?TaLC%`ONwh2B(kT~{6Z-J>S{)ndt; z3epjl$H{DME|sq>xRZ@%36rTiAFb&jhY2>VG#0#3(sdLIDc(g$-1ZXzPY1%AGjez; zG41T^Y*1ryoDY7U;dEp=^a3m2MLGE2mB)8ntwtX_p^a{49eg%ncql0FI%)C$PYACkod8uk zT%o8{z#C`I4FOQ3N6;)U0nHhPc^lQ|KP{GvVNIk1Ac4-)*w|BiPy`LHIa=eY9iTsT zXq3BO^9Izldm?$kqc$;qrP0;k-2Yr@ee&UcreTb0!3yk9b2><=L^dil0d%yO94tC= z@LvDoS!ONkJNnDO!o=s6~19& zkMR+dR_RrGFPYIa-px;)R*cbhpZeN|NU4kSu2*k!3Wj#o#FGl&_TmhAG7iEENY3WW8+u zSrv+guGiYEzT|={KtO>LW17>-ngI~?DgBmfV^8_oEa97fE_f`v*k2|U3oM%mFkNVyK$i2w_rWHm!?=Y{)Kcf>6&qFmWf_++OTmlv*4f{N%*|XH;ZxF&R1@b?iVjMnU6nx`eQ4kY(BOs=l_GC5={^1~6xr5Q z`}dAnS4CrfiE!j6iO|UsuFSz!_DRW2o6f_p7DO*@c3T1q!em`DkLrYwRDU+Pm_0eZ zluf**(GL3l$3KDn5^KNku^s2M(7%~!%gq%4IaNM zI+ahvyqUV(Oy#j8#N8Yq?W8lsHx8?$@|snW+$(xk{AK)fuq0jYiUw>SBHOr#hY3(y zu3&Sh$Za>X=rQb{`+k1e-SF5<2I3pdkM8@C+#<9e)SIeKF=n@?(nM$-plqR)=qhXD z_n1qX2}ZoOP+f%IvB$^BF4mu&L?b}@GMQH$rC&|htfEt(2CJ37(McV0FZ`Xv~k z6p$}ZziQy2Ds&z`;~wSKKwVnWuCXwtxvK2aVM+w%;6YBSC!rSCL|g)AP|7|n%7mRW z{hGH7|FXnQg3=^ZnM7!M{x!i_+_OCT>a-HHdjbibA~iY`_cW(9A6m&d@6MuNMlX-GbKV+ytdwH>o@TPC7f#-i0R zIW)0^Auo;!@D8ZIZ|)qr`1|Mb?oTfr%zq)oF?QnpTm!tZH0aOU|GvgD-n{?Crd{>J zU?M3=OD=j2Wa9%3j_f5poMR19>E?_2MFTQ+rzgd>Zyc-D1D@%{P#F|i9d+0Ux%&c+iK$t=QV1kB@5XdY1flN!)!DhVw+bbb0G8k zflkj^`8t>bxqPc#;;5)&pZnM^wmOAG^s(KcZ|qfvnk+;4y@ZjOBjfAE#U5$?5ACWt z4i>yVw0VaUPuD)=3?-TEMLCfsvc(>cq^n#zXQNhggI~V4lS`C3V@lZ^i|0_tIG{}_ zo&AQaMX-BAhbUU`?34_EAw@M9Au3J(y@m|c`-INsTE2FUgl%j~+HUVjv(k+>IE&&Z zLkemc(-pL2hwhiE8t(w!Somv%WZc?PMOVT3o^GThB4wbt=G>3HrwLX)DYMZDL+81aKO#P_hIznGB2c3v{ zp)@aAt1l7HKHKoA`MfEk{XPj)Ei1nD5E|x8^BogKB=Tp6%#*A0bbdW;<7R1M*p#pc zv34T?$5?*yuCuMe>)+fcUXd7v3Y&ud2%Yth>vJ~?p5u)s_xrlIh9-;8k+i-C!Owud zSt%qb$R?0T=ZP-La}e6`j@fy2hzt~iXH^?@)>}a~W~ALJbQZ=}Zz6{3Efz504d}&4 z85@`oPL6)rITU@rg|1;@slj8E8y_XvCLfF2(krzW3a(ZJk_XD<;_ballIK+zY9T9) zmUSfj;UD%@8f(=|bwks8<7XmYzYRAM2>TFyOeHtI4OSrhQgA;CrAP7Fxen6*+x855 zo+<#$Z`*3mNpAFC31F-UWpxj+co7h_tm!wmzux@})kx#(xvVK6Mu;id7c(E>dk6Sk zl&p($4A^P@Bl3yV7LNp={nVk8vrE22#^Y5^5yvD0`=Qs{xnwl@nD!X=cGv679WgrcEg<8DU3XbCx#q z3p*%G@6#xJL%d1m*~K$s3q02s``y(I#!?P;Dk;7sc}yA$wC$3Pe#w#N)F<@=kHL9h z{AA+{XC>U^Cy9Ou+h41y1=HTdsVVz9w@c8z5A^R$3jRQNMrv%H8YPScDAYDyz|*?F zWA$Z6-*%=sgZj5R8?#lNvDjG`o{*tIM{mB0V})<{u=;Bo?|2V4ZNs}c6DgD4mwJvU z8)l34eys0MMaNrnsxjT*k~dfT>L%+~x{HMmlEVoM+FC}>3GDH;nP4?k|8jS~`3qeh zfTff}MSa@+8$?-(hyKM+N(yo?1;29M{E)&I(}ji(W060_u3G;h7`+!A_v_WptU{X? zORw%@#LZCh6y$vR@tR?pBoW{q${?Lv(p}m#h0oH7PzdUo=D7>|jUzg4U zFn{kJP{sxRnyEZ~+-j;inLfok)+E{iG=2+|y#D#qnkZBi7PZ3Cw4awE&vu$RxMOo0 zXBU!KjQ;s-eB*6!se9Fzf1saP77adDNNG3(H|*Y#w!ge%UshiTzd?89P*Z8H`gLQR zY51;=?Rj7}>t74`V;M{dA|{N;Xs?#K`i5c@`^hed-zbcdnt20+YeCe#G`G|6_g6RroT8=qeN^^J$#>++)jt|WUUdZW_-1nkZ7qvN)PhIHupi9gPftixhaN5h4xh2`Gzd5h6yWe-mGzEP)`+S78xe}E(`H5M zeR`}=@x1jXfc|lR6yV;~Rk+ur5F1^{s_U&Ah`M9JOll&;kfy=T?Ri=JQ{2!P%^qi$ zCpmMzt({GO+~vNEGdfLw}2qy@d@LV^>lb&X-UqH#HgbQp|_*-cKx+ zXao(fX=ZMr=lREA>IPwv-H*X-iSpYls#XQ?RK1m+0bM9WNw34TN%Z;eoZ(-W*4Nr3 zq7AjDR;y397K-ESZ4r z?30SGlDjib@^O_vO;YCE^YGnSgx&MJZq`gpOs5F$!uY`;?;(CY*HLs7?jJG7(uqV{ z`K^PTB9Z`aduWmx_(j9~5%!VIQF$HzT7JHTkQn!hH485rw@8khXkNocXYb`#X+x*0 zE&9EKvQrBCcD=U{yJabYuInw9W9nn9N#7JZdfEU^$T}ll98&F$_`MC_@gH=X`#qqc zr4^zg@v^E%ly)g0P6-d!5YYZgWEmDL7%pyd5;cGZ^?gg?#UbHt&{1DK_rd%EOeo(N zTBuLQ<@`*|d~!{o#gj1S?!v@z+!kwC8aw&PaZ1SZw|g*0HVi}!cIOOcpw$N|GNucWD4 z-aa#<`odc~+~3;#9@VMimUJ+lwrd(troVkgj_LilGG%#>I59zaJ+;=_P8QY0P{I}6 z{qB!^q|h_yE#64bRI1@UBMtIrr^6ndqH-1B>W;?so*5h*AkxhZ6>SYb$QWx7KPC!-Sdd`$xO zvYodLNxiVz46FC3Kb{d@i9;C}&#+s+=wX6T8}Z7=8gC=p!L_H}F*&*tLlR=1)+o|# zaN}n=zuyjV!g?Iezl{p#TNzU+RWxyKHn1`tlup+aQO1d^i%5v?x(h(OXcy52RnsFe zvwdEk?ie9+=f983S{LkGg)lq|B3&SUc*nZzLz#<>X|78TX>#C33DCks znn6a~Vbki%n7vu+TIoHt*B0Q~8n&i1vtP&rzgufbu^DkoKzgOQQ@>Z1MM9-27w_brt3!+oD$~2*{`yp{y9AY#5%eZseTsSo)AQRY5Z0%g@~G zu+drJ2=4VC*c)%)bS~fQC_dw~*A)mjTyC_f-_|3Qya>1l?>^+G@3mN`ms^+{q7Dgg zgRR;zyDr(7)H3#thca&(Lw(Y3&BGlaZzrZvobcVj<7xZLC7mk+u7N{AuR4zH@wfQR2S{qX;rW$OEsQs7_*k6yQhnXFi{x8|*w?75JX*d;Dto~8+>_Z^ z)l~7OZ##OoGo&@F{!2@PtWgbxr{tH`QdSl<6s|TCS-pCwFEeg_VULi*$OD_~IW55H zx0I#^>-tLX1=G-&8b9%79Hb1{AJ(-_FWJnc+^y|5P29A`x_>lyC!y@{`x_Pq0qQqs zpm$<9-{0^6QgLRB3i+DFTktu<(TA!IqSd}mJTWo{7J=**%m9uYrn?^bhxsNAD_izG zPeW)CPqKVG4KE~x1=c5;)&>VNah5U%QXVgLr~)@5Q?JHj-xzVKiCz*@xgPQcEbS?f zHFWFX1Zd|Lu>QOsSQjf~n|M6CIaqrL3&EGb8c7y=MlD9Hl<9(s)RwUx*3AmOmyatvjLo_Yxsy1fNib$-pIhE*IX6MY{ccG)(s1i0#P zt2M(O0?jXe&NRbHamkpyc~wQNn~d$}Dh3Y5_H)~_Ep;H@leY$MWLpQRF3k`b3DV7_ zDfNi63$+Vty}20OkJVxoN0s-)mXD|F(mb|vB8ILLf&)T+SphdtxySy*DW+Bz^MFb3 zva$-`!!0z&qH8w3ZyjW!q%=vMTkZ1#>z=k#ylmg--4kOSU$vvZO6@IW=~yiO5ys<7 zSLsHx;=k*9oY>f7&M7?k{zfN1eI}DnR3pT&J)N@Q!{Efkl!63_lF?Yr&AAhkdGXWm zbsL=itQMv!$v5hQ`FmMCf}a7+^q}B7$E@ksLQ~j<#o1@n%lB|N4{#alV%be=JY5j? zPp{v0F1%DeOPrT`qef00mnRFk&`h4Xtsvh#KuYEAq|49R%`rFBr@pWM+m&mJA_+k0FsSs`BfXQDSsKhlW|XT3p5Cwer*e2VAeM$zq?Xe zuy1S7n7R_yBF_$qAb62DlFMj`gj z_^wmU+PUU)-<2xqE99|kOCUh>R+U2z3LpX%IXH8A!6s5x>Zkp?Y6u#aU64bjAf}t* zu#FB|PI77C5aDqA9wB5qXs!``;mXcTfhFvlTdoenE;p`EhN8T!!dc|IB%@0bpkN_g z$NXe~x;2m62`)LmkATp^EtY+aH?5n6iN2TZg3^N5RxIyMLeuF;g!;5aRbS0sQAafm zjCNvzTx8P%IYwH@>#jYV9^u{jZsCp|-Jm1NR#zZqBuW)*%BKCd*?zB1k?bVF+m}K=z zqd|UABsWj}4_@bswgt0r>T3L~#rX)R71NAJ*YhE#_p!jO!2;l&M0wq$nAh1v&(Er= zq33PKLqe}l7s0Ugx+y8S%SOzvV|O39`w)oZ@i=!EL#f*nYPX-T&lOh-L;ljOJ50^C zWm`3q!$0`FHu|P!YAl|{fxX#(l$M^ZpLm{3Cf2-F$qo`;^T8B9_XPmL&mC~DJ8=9y zr%_=Z-nntd++4UmLzwb-JB2zq&V+Nq)xCJ!B?+8}iMeIGLHrzXvkdMvun0nG4L08fNN1t;9f= z$yhj&Q3_#12MdR{N5Zl$B{Mx&y@{h0HzJv{oi|-vT@#1`t^IFbUls0(ueYFZK$Q(o z?qMPOpkC0jAQ`r{q90*+@XxYa zooW(wm%*y_2WyX9neOwRS=F~oWmS1=L72gKz~J1K0tXeyFC*7W!QIu4Hg;)40L+4G z6U8v#b|+QBwie(>qEL0sO1FA{j?)DSZKZ71rQh89SIP`2OZKcs6h z;J|BfLr?0onsz&!G-)e1vugVOSq9x5ol%9;Gc#|$k_}uJ0j2`Q*j}vF>yq{^4U?Ft zUmyI!;926HG@aKSu#F&0n(iNw2_Hf3F}#~XNjp^$-rCOt~KFPas4;vnWD|x-<1t1^6sD}UaKv84yq^W zi|Q$cXMr~pP62&uu_a#nd&SO>H0#YJ6XR%^5MvjB8TgVp$8RyR>q@f8Jr}t?njr4^ zaO+GUhRFlZj8GWLQ;hYfv8wKgrscy*WLHnQ=EK@C7ObXb-m9HvAn``=R>DS(2y;uv z*XJT%u6TQqA}hysitAP1c(_9wazw_8h=Ze@heI}>1Dn-E=739BodJW)eM%SNbpRX; zX1SYh>6Ey?nB{dHREgQSUZU#03T*^B-lnsDHgVoS|8xi!9@$MVr#RaM zXBDFI)WeC)#HHqdR@sT6UKY+!-A%6l_I&hFieuZQE$SB*KzAi?@Gmlli0)DP_qQj$ zC(RN}{X<*1a`STeQNaWCXpYT5e8s7;_Yu*r%qHbyTors#y4gpYSwKaOBZIjWM(OzGeoi7z z@)iwoH5^cB6zR8(CCHmG7A?m6GuwPV31k?lhL<({_24ZEkbz73(VnVvtH`ZT^GR_* zi?4^o{777%GLcYE8fZ1#lg77SR6T(cn@VN~qRu56D|@j;E)nn)aWlnjcGE>Gi!3PR z5&jUe_Si{8(|O>L>9xW=lMt+LEyi4R2iIyosDYl0JiX2p4n4kgdstj5od0>n!L%SY zIWKk4*~++*XGql4EtRI8$1!oEZ6&qRV;D|BIZe_@&(*fc*GW8$8EOB**P;EnvDZ)O z&K7Xd&F^)+n`%e7XC0R>m^;ZJWX_WEPy;g)-o>C$Wu5Q4tMzIxni8EX%s4cd_$e>d#vXN zpK}7g-Ll$rA^a@*FE+8rULvFL$}v) z;LJ^_&^`C-8~n;n2(aoZQ9O1zbpD`fpvOq`{jPo7k@Jg(i{S$ihiD^>q0a1) zl1Qi4{g+g$S(mdV@B++LMZda$=F?*9=2NeATi(^{7B5&spefwxI6Ny(isEUQf7r_P z8a74TfsFccoHSyCOC@a$8*1dv?RfheZ<1GxRVUmy!|{tatc@0A?8_EDBL@Ns9RkB80-^$9bB?I3I1xEU=Ot#`0cOR7E0K)t# zo2jXZ`!ORN00xuNk5y9`H;cceq57+CH#Dtetyx#fhwWoB&FkG##|rUg;xv)$x2Qt| zS754HRi5HE_v_LRL6U6=%;+0Lj|kdj(G$*P7sQnzLo-f?5O@x|pSmU6!wkkf0}o#t zVx=;$&h#PXAYPLk}nm^@2(1CQqFk~TAg(@~DwijlCAj8nKUk!`% zBiej~?w9enU8IN{%<+E(ILb7dVN6Qh6IW_w%kV3#xPwf{peD{z^JQtl2?UF1N+voX zf$hQ+(4)yT%vQ%3-0W5|>#YBewD*i^D(tpK6)6G&B1kU^N|7egyGm23BGRk$UJ?jB z0s_(%RC<#py(je0ks45>1wv2gp@$I47vFR59p}e6en0LQI~jXq|47?wJ?mL>t~q__ zC!IG3p|+^8C60c!5W`RC;6spCP$|bs8H;r2)9c|#zZ(e59+lZqvc}l`EOl5GwBHSk z7f2{*T!^*_Hr5Sd*72;?=<=4^Zn$cC zjm-RbV94gv#*`p;BF$Uw^HaRB#0BivKQbLy)mDQ?nU48vbFTls@0ze;4nq9VqTJs7 zI^{d#!x$8>!I&!U|3oce_?@BlM)RbJi;UO3m$cgihix^^nCGsaOc`-YQJj4{I#-M$ zxBM7fK(CDIDL?;sI^n9b$Yk!Mlrsr&6blxwMBw+3Q+yAEb8JF6~u8^<}`8dfF*2KFilOh@)GH<$V!O>(sT6RM>6h zi1`O*uE{7TTphIS*!(W=csshrrvKMhd2%}Gk(#EY5&o7jtCcXK9Z6GiEIm`yH@r4E}keW_X@QCaMvQvI5;Xm_9r%v`^4WB+;M3Zb@ucKwk3T2 zE@wyPn_6xA$T-x)GU#MLGj6GE1~?;0a@1qXD|NS4W{#1?Rrm9bDKKrfZpxzff#k^) zdSYV*q#B+LHy97-Akw(S+&H@BZnS*>5WHQcLDiyV@FR07E z-iMWlndO*rj9P9J@0NpxOf%B@QubAsia!J79w>Rp;;+Vh5~aCH9+}(q#f6 zLxvtO<5teVsP0D7mN^+LgDaKS3N4z^dPoS`GlHFqa>({4z3`nQF$Fm9Sq7qm5`Is} zWecY$&QgYY>_T(!cxy3Zqnj&;gbGXS0vHU903e`K_pUd#oy5&P{1>7=6mgA&jgf17 z@XM{hYPW-k43;z^5uKVqjI@Qo(OP|lkn~1RLazU9rPg+C3W?8S<6pJ4HzmzXkI6C< z8s0lK#f#Q`QUPshNdECoNa%dAxL4{>#NsnEO7FN;bJ$L175hkgWq1#3p4h1vh)JZe z+z73pk-f<;yYIY_lhJ<+a4Q@5(@a%EenO0-0Ci~w=TSGw7(d{9(VIpFA$9%LQ~ZGa z1NrKmV_^9Ka{cCT@8OT4dy)#q@$8UkYO>wnYkD(@X(2B1sckHb3s`vzSO{SAgVX8? zaJ^4PRd7CX<9JflM_HX$x6mYgJYrdgDx!j|x7h1#rU7(ncKs=|w&Lzw-dG%UIcwHW z-rpZJxf0d0{cmM}W?8O+myNdplh%&!nEhkEeu@8No1rP_4C{oBG*@-_fI2Uin>!-> zD43he+;(OdcI#T_UFBl~VsabkJCn8}+y9uqMs$SUhUXT^ghskjQM@$^pCZ*PfA1e5 zzIjMDlR~%OSznMLiwndbdwqA7hf5S~Kt?kHo~eBqm{S8wc5tcht455|FGd1pttm&E zgxLTJ)xEo{fceEo;u+Ftq6MSsymWjfUS2Ufvxnw%xwDDvsF$!!Q15r(o*$$SoRPHM z-ieg&uZz!fmQ%4r4v~_ykhKG!fnP-9~IOy0~j<&-@b9|MBo2a$7l6wJ`)V&U7D`yMg3!N_m-NMhdftqlj z`dg@lAGk+-;&s`2_3qPPnFJ3`ug9{hd|av8cGiQm%yj97?%p1oslMumHTQ*c5t zX`@*`LnQ0K&g;JOjfh!b^Ax~*_rcV;R$k>Boq}mjNQiq9wq6@r`SbUITYzt<_OW)B z=K0#lUJJdA0%V`EFIE)z{S*FbJBuvS?CnJ_d_rhO%i}@lgL^L>xl{wF9s)mc9qU8` z>4~3}-s8LZsP~TSO}#JQ@7>c1c>A>Z=^c|79vQaDZgp=i(V&GEvAVjnquQ6FR36Ay zf^{CY9n&T@4ir8Q7}**h4<|?ot0bSmN1)g5YyW%|GYvKbCCMJ`Y=S zA=Y30TnIW>H8Bk1UwL&P-F#sM3JDVa>J z;QsCF{D8~dz9^n;Org$Y8)Hm3%>QzGa2^q-|1YH^!q{Ut`E=ssNtLwE4ojYm=S`AD zUS`VVeE@$~>Te;vi*K>9Em$7Yr3-9^C;nn3(<-S{b6oV4-dSM5A#Tyl>-@5X!4QpX z;T+=MKII%RZ*hePu%|Le{Yh&2bm5;;^FE~lGCSLg)=a&r9y*el&2tCOxuzk~5Y!UY zYLocxs|=09Gr}8U5_IUa&W<*QzP9k!KY6P+He5vXY-|B92A2;H zK0&e;XI4|H_TLK7!lKWp~1v16F+|FufL z(({YiHNg-GOT6!b5lUO}o0B?sy)`}EWbH4}7tb2iurb(R3+Q8Os%k%Du_1?rC5M1x z=rn~+w#}N866Kd)05@hMXdX;>Q`bb>%MKB2XdGuyDmhbQx4&3%YW{p;Sf?Ssy8wg5 zTCy!T2ZOFAM_wlLdSzpCZ?d2rsx@w}_#Ps)eWw0Nxm!wq(ArAnrPK%YGlvQfb6q=?0)H$>SJV%^LJV? zNHSp(lOBOLl7sL&zSXgGZE${vW-_YC?MC5-P5OSJ6?guAuX>|C2H4!Y(-Zjqby}ng zJjKE%=dGnr7y!w(SM9{sci9jk^DNaEBHw;Ibig9b!QgR57B>>q6Kzglx92RLQ|ffl zB`S5I^^?j&28_=x9bwz#)2BPnqS{9)4A+U>*FfESOWlW~mM-J)wq>~0KHhGjthZ`B z`?c=>B^Xw2rqVl^-k+hFKJq=_oR4`+yWJFgE5)LgvvinWUEL)iVc0QYAB=++6!Jwh zXajE>h?3e*WQNAUoZaOkEerWSzoTc*f5z&{t0v0x>T}92d{8h8@}p<2?^b2-DM{<8 z7CQtHAeUX&o_eb8z$ugqNy|?xJFgYauD7h;sE_s5P_tkB6by?E+-;_L!#iHYRMJW2 zaZZye%l?+$XZh%6b9~Cfa*JlRzycvD3oVm8@C{207J^HfKpIj@ZJ^8UJnbb`?KqdKV`<-Myiq|J z>CzR1={@{1M2vtK{ygohI6d9s_dAb}lA$io*fp?qSSb@(P`|Ndt#2)VI5+eo!@PgG z5@`Ni?4*42gHOLs$Al4h!b{Fhmv>wDiiG0~p_Iw$&rpowu4)e}whYR4H#BfK6M~Af zr$WZvhsbr~M}gcr_ye)wup(B99L3`W{ zd=7hZ`7nUG|vTL`6ttHMo7g(LMK$zaJ9TEj)K zP4P+z`YN{BPbnnxY~`oWRHq#HLZST}C1%T|^&>-`3^Wg9jN}Zt1IKn)(?>4&pZaQ+ zW^`U&w~Tjr*SfW^_vT2L>{I~guCpD&h7cqd zEwv!b<#fqAFrdp=GWPz+>uue6vShS)c&RaoW?UP@i{V3ED|c{4-3 z>PA$D3%mG7C2KfkgkQtlHMk)qYu%h$X3V+#{WY=Q#oT(1-?VqmIjzi~Ihe4p=u-sc z)pL!c;AqWfSHggGS4>1n-9}`hHfkEKmZ%xF6IWCR6X=(X2U+^Z0wQSAR9N;FZ-5q? zT|B=396p^X4^y)_TK~n$Oe7gSkIqz;U}7WU7aOPL!HrPG{mNWUiJ@a>n&WGYBA!DN2*R zI5HOnj@^uW5w9!a?!9*K^*}3ATUos5ae;%SCyBM;LiG~&K9r18#dT5IP+Wby>{R{q z{CH9t>?fj4X!hQ`#LwuL!>23TOy!oMxOMVJ#En>>jnvreDO33gfU$SoNAry83=DK0`~1IJ z0G4wAxPtWdQL<+z3FBh&0G0GbG1~ekmYS;|x2n>-ISDlDq2!96v^`JQR|mDO3&y-I z>(e3f{cQwh5t5>S+w3esDhR8n*A0aaI21aN|3!pq+RfItG5aFszVi~#<+oCTY0GypEg zm=T0W06jtd;V4MS=CjApb=X5SmrZCc+8SBSmGr8N2*j@iq#%S+Vvgra26k_kV zI5gjucf1`*&9OZfiJJ5|j2ISf*?y9Fkzv{>ey06ms&d7w8`hLcz4U!Gf)5~-5e^z# zd?vm5gS$pVMoLP`x@w-rd)utsjQUqKm1GA28OF^0Kq+1Z2={;OXT6ororadOk>Bc0 zl%DJDkeJ#mZ#FqcNx{_YL@2(}Yl}3k-pTacEcua!m4Qr$)l^L(pg*J@dJIXMx-t6_ z7?YLWHhzEJ8ZIGUOSQl)7Al~b`u*i~@3vijkvN1u&SpB)54scQla2*KgeOo%|nAWuwHjpPam z=K%clBQ5t>z88g|>@*|7z2Pgsw&jsbf@v^FW4r5NnC0bo&Gde?GGX41ait(x=Q(h&17Cpb~><@fBLJoiU7UcK}z?jaY@p4EgnALhtcS|5Rq%sp=cwqkIZKw>uyK$X{ zak(H_yUYIKOd6ywK$6CnqI-PY>$YK5RA0freP=#EGfsQ+4vDydRRt#y+hld{B1 zbaf%haV+FvS>2`hxKH|W;=Zx)Z{wHyQtHJyTMm5HJvcnHM*EkRE6%A8eM|3Nm)ge7 z`Uw@U!Ck4BWIw(pnhYEB#6~+0>8S&rwV>`m{OzbU>FS*>Ro=Ye<{G$X;KKW@!Pn&7 zGX(==(iOX6n%ylc0-q?_Ojg9KbFcT!qft{N#$h;h>CAqJ9B5SH0Bh>flD;ovXqYgn*)P^_SL@bf9!obwucO~+=e+{_ zSR@ky_$m5X^RZ$DxzOvrn?;^OU-DxozTI@s{r%evl*K1(63m=X)|>7gKk7A<0$RIq z4X>9P2;QUzncqc-elCizn2^J?-r$DJWO8}js@ouvTIx%5_*$W@b?h0QpU^QPHUB|~ z467C#tPn6stf9q=@(%fB-F~vcz1MXJ&(ry~U!9SzYyNf#CB^--`Lf`-dhv*uM#bl* zO7OlJqqtNX4q^dyqR}x?Hr^O zwHOZ5OOkTx1c$_vU_uUVTs8ZZH>>I{Q?DU3p{@^8+TGV25U3iQj~krUCnslc50FWo z5<|UAig0~A{+pxAk-SggTwdG8%vD1{ARKP^AqSS*ZiSpNLU@Upj|9aInpM+7f<;nw zuevg-_B)e*4}2W5tE+m`#1@q4hN;7mvcWUP|GW!3?BWly>fJ3#*Y*S~sJW_MFPfaR zQZ%@&pLxi=^(_w-WV3B+x+xQ>z4~+#sMTWE&i??>T53CIqaj1^ED=zdVJw4%0;W-E z!S37FKL#i|E`N*WMG-48G7I~=U2O-xb^61-h+a7l;21WI9I^lL-hVxcHZXp5j*?*P zr7+O}6FGSam32iDh&#k^`J=4T+Z`k7sk5$?)o4ayWzaALq|Unh8IDpQ?I71>NWFZntFS^>2B+N zUhz&-U&G>_4_Q!6a}xdWubM@95upETRyqNdy!k@STUSB5{=@l{Q%U5m3@Z{T;@1;{ zSMI?3=2}k9nVMcPP0gr;#O}LXJRx(9qkCktYobBFTi!}OO^eL$mGTXvUen=4rRH`E zS@Me1V6}&r@TJZ%DNEs`2J_z^l)+Ix@+%m*FdJ>A=x`nReshjt9;=vG@JKm>aQLV# zS3#jB-&{-hUhf$_8vVrLZt;8f;ICb16v%__2viHW5d7Q%P9TKM&%&dv9)F{2RT&FY%Hv6$*t%kL{RYLm6XWP@< zXCH#0JBb zi)+D*rI!D*fZ~7EWU`M#-@VSg0jeu-L9L6Sc}aAf?;&40CYWd#$L=}ih9o3^`jDu(8N*n3E871}xMe08Bn#&EhP3wBGtb({THkU4YQ>v#V%o$%8qy>bi zfu2zeI#Mq>gYj}$v{q?@Eu6*ZU?(6?+HK!E?NQdE*}BdbZG)5?^33K9-P3$t#G3m0 zJ;-#ev1~v0cAe@6NRMN=_UX~eDv^pIZ}m$iyb4&1UaxT&fZS`=u2ZS`H4z|L^_%RfwIL|=``NciD6(!i^VJ4){kNXm^d)AE~ z08nI|UIJFwE-KxXk`bdXugP_|T^C@kff~9W4O(5YLO|8lcc2S(36xh7n z9hlTPR@ErRjHoymZe?=nD!X%m)#SU0uoAtC%7NX>tXldyaDH*n{2d<`k>EJmlUtBM z26^(_Q=vFU`3n`=P1O$!NqYbA>fT4Wv7txm9aln@^$AhQog*@%a)7LsrXEHtwqUOW zn^Tr+k&%B1XmAu7snUOZhz6^8>BDoj+yiHSelazJHg&Z0_9b z2m)WUH|jtpL`GU8RIn(YDf8~a9~;YSNqhBBu!lcIju{onUABVk8Q5Nh#tz6)wdG4SP5WN?s5w%UiV6?8zP1)hW1LLlM7JhStQ|bW938EN(UDXx z`T6sDbw1ysIJ>;7CgGQY@yG@tK1&!@39SuFWQGT10;Izzn$yC2lQ((+?kkHyj~Jx8 zT2kqdP0emHK#Sd=a$j)!LMKuV7t{_nAIBHE!Gs#_&f{_QhEFU}Z{8K!<8Y1D+FxWF z84WDZs#Y%vA{-Wa-p$(oiv7PCAeSoi7gLp+_9o$+a9Bm${&cPN`QtL$e?gZ<4L1dc zOAI`3Mrsels-hW)B<;J2Je5$Z(1VrI;6& zAwg<0!A$`}7S+#n{H{+WMqw(bqOuOL%#nI__PSjM;jNyEUxvef`7dn=Wmw)hY%;^? zNh9-iZE7K9N|}ZsA;rqY)rljUi0A+^ukj0G)9hH#<3I;MNOp?vi~hg2K=qxQ^p|Q? zANu|j{FDCv-&IoydUN;4_G)cP(*LzjwfcNBHTjpE(1l_WR9{%{E_PtB-u_j-J44|mR zPy|w8A+=iwE2q1&(zMuEJ>h!@T16c9M=+!ux9Gk0eZ7_Q)-Xz+C;UZy+l$>M#=eJ*IgX9`2j3wz)!q?jj0WBV zqj)@D+bq;{H^@3$m>^KYmqIY}WejQ%X;{Ut&9|fVE2GwMUt8YwqC^yOBK}lY2 z>&dDrJ9r2J<0PX7b>$g9#vWxvx)D!BkXh9mVBNBC29XOqLmnfUuY6&e2^V*K!hl)5#;c zrq8t@*K4XR$Ix&5Gq!xH8;N-|Qx{PV7-X9=t}U3#g3k?XzlQokw;cr5fTy7FHekl~ zAg6Yvs*6pnjzn-%%S0=my8Xx~6n0D)+UR-`!eJksOW;s*xi-J}S1S3I`84WwNL%}+ zk3M+YLtq&D{O2+S$Hv~-dE!_eLgtQ8$pCZ$I>dIL;PU0Av`* z4Vq3+vRpUX8-2-G)gK2KZLyKECN4`3T1z8FwzwMFAMG`=n1FY&>+B-y%VTBB*f{W>R~ z7LR%OGHrE~y=xt2sI00zU|-l`wD93I5r>Xai+}yZvJXOWPJqh%JSzr@5R04qcjX7y z&?)Ul$5Df3lEBM=>!KoTwQOJ|^>Y2r!zs`UzcP>FTHs}Rt~K?%q`RdO2L#$lli1dm zam+lIVMQp{{iCWu=LZEt*uw|6NOovu+&x)v_v);1kL4WasAori{?em`Z1LExau9!s6)e+5wAMiZQJ-#XP#82)pepdwGbwte*c&3@~(MiwNx)KkN&`TgN{ zhmz7wkB+!5)fL{bkKnpx}I1 zz;;G1mVH|?aN$HB!7bT$7%M9$2=UA~?J~fIK_KyW6V4?f*xF1<$WLbs-C-2Sq~_L0 z+UlmV2mhika8(!4J@y*yDHF8hBd%0(rIf!~HVs8OFwC<>v_{j7gBGoVo}d5>BTMza zbqF4TbBjNl)_f~6jrqERx9XjwaRtA1-^|?2dN*I)2?Y_HG33!I)-KKm1uy+p$JNce zdK#_l{M>|X4r<@p6o%=aBhgN$G%w?w+}Traa8(m<T{LsCPI?!ezhCU;Sagmh#-(u=uPhUy3V(03$ z0YmF<4;nS|3*yyurEa;YtOy0|GyYvakIXGYo(%8Z1yr2*RFAx5*J8(Kzs%hgJ{B&~ z^n`r(*aCmyIIZ_$o2@ z(z(?`p!SVobz!z>7D7`c|E2R$@a+*#;b|i#X`3&XktZ zW+#XO?td#Jc44e#_pE8vN?Yr zn4zx-y!YD4TIC_`@1xzUsZGT2|M%r)>aUz3Wz#VvCqihf8xl{A_qYec;xyW!>0ka; zH9aMs^d#b0L}g_}6TfXRc(6Q&U;Wy!H$9rReivFRyvBD&Z(WQ`bSvOsz;JwGE{?#? zWFD|hdSt?)07X*tpPvfK?=6OR-fdOvKcL0jTiahx>|fl?xQZ*z4&f0&kwoy}C``Y{=u z6=aZ@Pc+?1_)oR;2dtFR7?0btSY&Xz9>f}>OsE3$od2R}%1+tH67!z&07<`#?6bu*^ z(Cv=a`|8#sz}Y&)-w{PpO1k_@E_-oWO?0IKx_5X%)3wc;)7cd0Mj02v`kCOxG%$6} z@<-4G@!7#L&N$Oia>{kINyZVs%>*6E_}00&t9&}vc}-Dij7&)pOCcM$llP&@Yu-nx zhq*W_h9G&Bwi816d6w!uGbcB5PF%lYdSr|{>tc^MH^m`dyRH0!!P;YQ61i96(dz{_I)NYy7mGczt@8na^;OwvH*!`%j3<&XS;8w z2|iiriUEU@2#YBzPyy|h0>^aP5{akdKm7wC^HUjRW^?jY#Mmg)Q z`||GsZXh2j37#?xI&^;huk~CdSDDuH`EF2vE%k5`z#mJ%jo<#lx%N1)`Lvzw^k=8GIxmKWv zi%aQSC-&&fxVn_;YnUL+)r5@j5JkIKiWQPV+zKb9@$K)1BCdm*u0kfDk}LaC3mqTbAibF~6@{FXAf14{X$)d|@O|J-0^w!9HD)n-SNz<<{ zh0Xm!8rOw5`pBriUD;_pBziJzmtNQ+Z5XeZl`p+@w6ZraVeEIXCbf57CX!$1^F%S{ zmAZF5V>`@?aPO?{G!p2%HU|?t+btU=eyCB)>k8}29FsQ!Ljt+unpdB<$_CuoER$Wr z1$uM~vsNl!J;HZh&L(xC;BmFA5PqQ#?_)tOb=)t6pNnNJpmPE_O7Gk?f`Qr47e{>Z zXE#$0MQ?bCLPY!r=mHuCd@t4>m;> zr3}&Nme=d-A8p`g{MbL!7jiGzyn6cl_6yN6T5nQKvU*Sp2+pknSeMD%rECc)yuLjA z7&LdYVt^;JZiQ!B@N>^F+PyzAd?xSu)-oJ(k?6bss`Ys0)||w_<6DEnopmc{t5L~7 zt7LP?Q=V^~JPW%q^NCCeSLb-kkE=24FrJnd0p#}a7KE8w1BUCtlof&p&W8VrN&{LV z+;j)!R#lUz&^VRZTVoPH+}W2Q-3LSV;{;vW835lLj&3gF#&pk8a)K<&UlZoB>FJ-3 zTyYCGMe=SATtFeyL{+V46sU3Ipo!P&*5O)^9@xU!doE5Abh`GaOe?|fYh_TNs%th} zs#B!$TvfNKp}V=FQj!St8XwT&NG$jbu+VTe+cmr!X5Ah6dW#o)&`{Ws%pfw&%c<1- z;s}(mk7C$<;%9#J!dI=zkBXyt!yeS@5fZ5I{WEbhPrynT1O;yHMIf_bE zHFN0mp~Bh8(kGDjic=IydUv4;CYMq$2O}sVleFdDkj`=C5Dmtyr7+cRRT9PssI|Q| zRcA0paoVjv%}&6T4gBm$AFY!XN9lb7OY>c6C52 zg#8S~=6KoP1rK5>EZ=4eX3!S64Y~Q<;)lnbxON%9X;`fCNmBRv# zn7U=ze%QuX%|cZP^+!^xFW<&_f8xt^KgS6Vuk~!XcRkc{c^)aDKfVJPfkq+Y^y=md z&rX*TsXJrg3*kc^K`eN-ko&*lw>@km?CXnaFnLic8>S+vE37oj%`l~Syv2nG0>T6# zN1w&lw28MknYP&a_u>lscZ7}F#Jb z4Rc(P&-VZxhb!Q*>-BW!{-k#+MD^{a$(nn{&Q>B@UmG z=Edd@wk^fy%H1CR{f~`||JM2cw+NHvx?ZRMi`;*fCgeTq#%QKuaKP9QimeiM8L$n7 zBaIw7WQE~u4f}rbm~yS(B%5pmF@Qt`P{(vl&I&5SgS^sX$s3*%-;sIUdLO_ymw3GPE#sNO01ioirwlG7!71`4Qwa{e{Co3psIMB!DLJ_nHepGx+h@qBcE-&qM-v&@%&+u1YsKbv)5N=ZTdd%(;ZR#yRj*ZO~v)@Pol3yX2{huLs&vU`)fanDC@sg4p79{ zxZ~_?)Z>LLo{ftjddY2BCx*L=6D?vnGXW%{(ueX4KYBZ;qx z(2|kY&J)p&$0AH!Kg8FTb6E+X}YHvS6o?1;TOdC(CM?uGML>WOY~jRLHrg3t4! z#>-qd#m_N-2^zK!(RZmDPxo$kF~DI85j2FY@_nh@9PL|`_UG1h+&YUM(93ot|YewQiuyV$L-SN}HEPXpri)>YStI6djp5 zrW_C{-}FN&U-qAHB3ZebW-*5iLy?8}PE+^9G@qas_f292uJ!`AA^1vd(}c#<0m0or zR!Z>H!vFLX1k#_bb|EkWGfBkX&LE?{Iu@$Oz4hPwpY8mkzba@$bgWOxO>g5Ky!hG> z5Gkx^y6kr?C41fQ363^=i=FF z^}|Bgl^Wk}GyPe_say@fNljJ`ZBLov>+X)KZD}A+wS=;!%uC!KA-2*Os8$45{q!nv z&^T!k!$>f0eCR8>g|hn|hhVvW1(<{b8-suk?&#lM@$Nv)WhHIerrbB~oURg_eW)A? zf1*c^USG`|f&!Sy8k+;}Y5I?3Uhy=7KA%!dkd<12cJ?b!j3 z!r*UHiWZY4+Dc>P<`GawpL78!xuG@jKBmKzW5XgomcuiDGlQ9~o6vVGAs77%_i$bc zAtx;h`6b`Gx(>ffN~Q7s_VWeO#7(;g*2i5jCN(sqGUu}lPjD+l_&A6v&cKBX=Z8it z4BWQBh@e4ln~UwX3)?9)Vz<=)inyh+O=#YnYDk(S#@l_>>v%TCI_O2IMhJ~>54{?eC{p_}KwuakN-?w><<2YoMC4iM=aMRkpI@j*-sz6n zG<^K<3Lpf2QMIG}8O~Dg4SZ)3JZTmeW0vC{dW}i=>Gt5d-9CBh>*2IsE+FC{hZF7i zV58_c4J#cXw;4+9E{W%EJ{`y+I|?N$dEz%UpMu3fpcL=s&9x=qEirDDqAfh~+NuGM ziGef|z5FV?0-32>D#n1@fDlPFX=IH_ecv4*f4}vGH~;LER!l>;G6MxNqQ!Mg>yVd> zpJSNS1)*ngN=5B&`Al1SM|X(a;qX^PJ4)hNUEKBUA(#K^6MTN(9&5lABq8*#hF=+1 zC|C09j9s~BQvwlgqw7|0A5=SP*YAyLN*`y~MG(3B`CiJs(G|i4d#?VOI7iL_#&IJ8 zsI;Z&FG$~Dst7a7HG;T)%J2mG!{V<%BMz!k?f{>z!YyRX_QQ;4w7D_IQML;X@aXYW~Q&9 z{zH4FI zs$ijoW7RU{DG`=p@4}ucwlvit%b9bAij*>+l3$p{KWFwnfPa87|8=R1;d<$i!IZt6!dk@`IU*T&;p($mgNW_=aWN1n>0ywAfQ zW_`$>}cObb= zfkxOK-bI=i3af@Uy40M z#c6uyLUWIX`jm{c_4Z&yYqxiMkf)I}XZ9#2>|ke;@@ufjIW)2hC?53bUb^KiS(dg;=Ngik53P40W&#fxdRyrvfhKCt9c&-yF9-SHg22Iz@En?j)3eq(ei-%` zjXlKVidaf-vFCOop(#q1vx(=?zognZayTc^G>pHhf@-SGmi(v!4dt)(&fXAB-DCa8 zL_2)|-|6?JvMEH|{o5kqBC^p@RiW~A=!VPItr#v(RA1fKN)=h)=GpX*{l^BSRTVDPVM0Ts$EQXW z?PrjNI(=jwbNx!yVW4Fd$d{-4tc|bu7n=DC)gI*Y$Ji#5bRA!4+A<=l8v9v`iC6XS+;?1l?}sJ-y3%Ab%Te{ryk&E}_*JGRiQ#7uG1;2f&2JrX_7}&`03~~2 zdg>0suvLI=$JCZh3#sUx5kr;}xLk^I)L|D}_RM#@2Vi9>)WahLJy|ZV^S$EDlpOH) z=l9@8cZS83M9%%r$}ar;cKylRLM}fXM`SjPMl^_qGS|z#u7@p@qNNvn z4LeY{`E2mgVNJcnM!kai8k6%%E zoul8hXFva@^vB*~?fh422VMqlLAYw=#QEJ=;I z8@F(hvyer2Lrx^6iA9?myX@Zp3e_XJY$+6n9Z6q7tB-nKDSo@wnnd<=;lDz1wO8-Vz2S+iZ=@94m5$YK z?drWBS7b_ScRs28nF7=vy)*0c`2~+i`HWYwCh132(c&l3K%S`0qNd8AU{wcbm2Zs| zcO3aPH7$#uIeU%Yt)^R;D749^_w4;9rr}{h@xAK{tH%}JQhs=MSqQLqe`|d+A@|&- z$-XBEm;oW40^i+65g4#3fT81AUbLr_yYZ41IpnMlT%jQ&0F+S}M);>2na*<9>zYmxsZgsysS0#SEAUnZOEx#}1VpYU@&hgA#a`PZzsss=E{9a^GlCHUF7d&JCyT9A*|X zKTHF%7{@rY>+}XwM-pUwH5|c2Su&--c<1;enXf zB(3s|ss^F#*x!d4RyvP1)G8OZT%jY;Ji443Tz5-=rgrWekERX2X)l@yhY!ZE5NZ9Q zc@-I2i9YT7$ny%jo|qs<=z3hS&*2XO{XFblI%fRj473II908#suN#%pL= zPP|{3jS3@3tJq`?gt;K}>C8X93rX_7TVo*ZJ)GgE>LS?bPYVYtJ`x+LuJ{bUHr+Qn z$FL-Rj%pLBK~^8{sjjd|^)DNb2D1Y3@@XzJGAZ47uN=|9s{eEgT!aZ-^U5ZhDmljg zu~YP)7mYNDP@0-!y|cgOy8a~HfR2iY8~zT7o)|7F{{ zf3{Wq1k;A+NQW`Q*V5^L1d#!}cY**NdBh&gLLes;>04GN(0kxpg*wO-ce+FHS>v7< zN$-`sid5$eCie01`IxT8cmg1}!<_c#CobTaEo@!U6O5pu_nV_=Lvat#msrQu!yO|oW=5;Q4{GdRpoJS?Ai0LRU ziy*#P0Y!#k7XoR7goJQ4=>s)6iot5_#murT3jtffb0PSg{S#A zxFWthBmcxd^Pe&5%Cq;!LnfCvZ--6;|(El78F&CuOQ zswhJvA_CIgT~b3y4-G?i4Gi%PpYQtp_v%`+_~TiuHSpYf&pqetefB=-+_jDKGS8;Q zNGV+!IKu;dN7R@o@xz)CCdE~=t~b{qHlK1xg;cmL_`tFlMm4aMc$;Cj1`zw_;n6Xr zmFheOo)*l+n>B5`B?}8N-tAKKo^4CI>AB1Vd@m@&y}uvcs2tWI+-_zg{L_r*`s<;) zOKG0n;ULo^7_;ldZZ5A^FK67{5$WT0x4644T)Ez6!lCq-SE?;U+;N!+mK>R#z1M8Z_#5ewUGL)tE4%W*(e6-T#gE4c{aEtyRWl8yb3HwW(@W;r zDImv9y|cL+~BN}CwtO!hH0TyXcgN=-VI8sQyC$e~rTR;H-OonQj_9s9Jago|#ttK@I?0tOmqEGLYP5zNB* zV-g`WE)C>m%|{ZoTe2Rh*;Us~_YWS}#6fxOP^5>h;l=2197X_>P;n^;DDk8>_UGYZ z4H0}fz+vtor)rO3TxL)`xpyfy*EjO!APJ^~yk_}ZHh_FSC4*LIdvt0iVVLFZY02YW zL94nbnSeTdhl0oo5LOk1$wCqN*&?V_wS^e>x$vgr3LTWmu;bm>#J-BC!_Juo(H~on zRawHW&ErA_3pycrw%7L04f`9&DpCQP*`XVsPdC|D#|gG$df7w_+@U|ODXyt zS@^}Vm;~0EFZL#q`qs8c5>|o_X+xH>{U}|pIAMA9!wQ<7Lfk*RZ9Ht!)l(fho7Wq? zkA@Rn*IS!%{3PP3j52u_+o!OyqUR6q_yc|I(UQ!+QX!E^Q0Xtsoz@?0nF`OR=u9By zCbrLSAqfU+Cmf1q3yZs^TgF)CWv`;v3U2E>ZsSI89q#pK50|k#I?Zn53Wnf4FwdV8 zb3MNJ2ZO6999)EGv_QzGIgq5i{ti+w4!qpAY1kbpV)L1t%40%aWcByq=%@KmVPhW} znvzKdhPIO@tph`Dgy@ddR~JVMK_KRR#68v z=HdVbEd;dkACekQ9MszgLlXN&g}--qOyi%K@&6tGS^O`y z^F`J_T4d;Ytdi@D%KL?q@(r`l#7<1s<0awzSoDya=cOw6iu7W)YYbE&!$miRX^Lca z&$RANeBGUTBQ*W2Z1~4EfshX0;Kd&C%ltY0MgTip-jpbN)4Za>q^>E%Rxk1ifN7L0V(Fgcmx&a%+7dFX@Cz@a! z+dQ5XQKDQ6aA2u^rH{GQkdfmR?i>{3f20hSr{&)clUISQ_Jg~x-w-S(2t3(|{d+kJitsi{GY596Kybt&M_}7AQ3SK}yEo=w|1$h1-zX zJk!@APbFCcT7$Qhpi0c|w#@P~FCLe?0Zs$VD(`-90ZKo#k()efshkN&WIp<%>0*({ zPvCkh@A>pA|8h{7amXXjr7&SxRIZ8k_yqx0E{o=Ol3g4gnqxe{eK#W+*|sI$IA+mT ze3Pv(M15VEaXm>x!W*r4#g83DY;KllzN?f-&?w}CFK@j$)(HTF0(O=p=X$sYTmYQRv`=WTn z?xHGWA*Qju4Z}LZ>!n)@zyPgkbwR^qIHH-q#BfMF_E&O$z1eyxmHP>I#jKfhr?Zjf z)}JcY7k!vE#t$qWt`UUrzTbgH+pPbvA4%-;KK#KUV3bLlzS!~h+GayF5EaO z2v4t+mYg2V&5YH%?V8>z#WZE>wbeWzuM=HY1^CPp^iD zw5%qy?wxPNA(;xG^)Rx#}n zAg%Onah2=DurT8*n@Sd-o9B+!L@(pMF2cbllg@_XG|F42!8kcBShRJ)@bTu!wSi+u zCfnT-XhH=L)OLHZ=Dip+adWU|7FB$|GcxZC{<)hn$Bgbyu$OXz$*p{n_A1Iu+?)9@!wUUk#G4+Ca z&mX#8agTIg_3g#8S=?HyAgZYvLEY9}L9V6qYzuXIbzHP%xBdo!r?-Q>ks8%>k*|cJ zSERi%5*hB-&9$_qnZ{2I;9Y}*+kZzfu~jYSeQyTGEUOzE6A&h#zjP!ci~^;38PslqqhR zyxS7GVY}Im>vB7&eWjirofBDMusL=#Ysz8F%4O}S2C|q~NYkh8t0UJj3S>9Fy9^rj zT9$FFIHsuItQB`fD(8RG zf~?BxeE;lhJpY6mw~2iKwPvG3+@q76H8Zl$xfwq@NDMiETtR+tw@)r|7ra7sv_QPo ze4LQ+NUwN4+hSxy#)B!LvD^1XqB!A9h5&SO zXBV9`#8;Ahap#TIYDwQS*S0SGz}{rHEVakJg4v{I$vEw$i-x0t0%GYEUJdFV&8$1S zySz0Z!wZa%zYkLMzVCLvl~Gy_6{8N-LB=;oF#^uy*zGZ9K{`#3_TG&Gr&Yi(NbC)$feH*2*BC(2fw`e&%jxB zK%1b>Aj?E<%HkJO&SiA-N#aNX>$n}V`5d?e`yw@-V7$jKIF7kw9Lip4U0w&*)yPJt zlyK=0QwwMD^QBd$_djJH&>2xwgmLA4U-={+%#3SK)cglRsz$;<@|iCAGhKY9!y6!jT=vJ!WP@A1Lp`LwdpX$b`ZW3(@;J7)hSGlbm59!EP1X@uw3c=e zwHF!^<<_M499!87g`~H!@skvh-r2JOG#f06+#16|N|#T@ieG#!Pw6jt-J^%2sbhea zQYe}R@*k2nk_UqrCi<$Tl2Gu<+&3ilLB&lRZ4_YQ+HU!vh1R2Y%Jm>4q5cn_)mX}oy?xOFVl!S5kFDAK2n2cJ3*71Q><2fZvqbzqi9 z6}589OEo78ZE_D(5WRQ~5>N=!9sfEjQ@SuBaQ~!;&mJPyi~{WCxmaPzX5-(L|glP>Cqh^ zt*DTz_iRfWBuzh*>ztUzM zWs3H17stc%5c#J>a#-Zihg2wts*Zs*ee5AB7v-_LlySvoGXFunqOH%4ko1FBS z`DD8&k#UrGqXibaF?fj%=#D0f<%i{^Oa!jF2Cj=tseH7}#f3Fv0(8XS$#*XX;)n6bI=BD%Zr#l1NP3Eq}ug_z} zTQwSi{QfUGj18OmuA3B!u|%cWY(|3<51e2}ofK+s6_EP}iI1k8QO@6_f5_5<4g6SvXkLR-|( zo!i|)3tSciI*aE!yurBZvuNWMHDZeWnpLy*RLBKDDe{8<)3ON3W6NV&qkd)lia64< zp?7IZljU_@I{P@O~w|2OAd+$aGeP1qU z2p#U>Cxlg*X&l^Cv_WzGVJzDE5@>;Y6#nmDBLy}FMJ-62!eAGSq&<-7~5c8E!&^xQv@Kn`g7jK5#_7bk#- z2Tfh(wsh;bhY)~2%4C6_8h(jx)3)Qm4Aih{+l+p<7aa*kU}4WO zP!1RvMYz8V3^We!Ed7e}PPc;6Uqu%O0aJSLIz`T)#LBF=XpTNY%rDN(?X*%_@ZPsH zR{CyI?wk1R7g_x^&qE$pT`n9l@$grgrA=x{Ej!jj*zz?jZ64f3J|>Raym__dC*Q)o zte?NKC`}yRwK(uKE3H<%YaY4WXnr*#9vdJUw6r*;R}b*s9K5=5M|ihpJ00d4`fPC1 zpb@{Q=ijx4-A)BIzwK+`BaMrdKHLn;_6juqaa%cRhPT9tW}+_v`hoa8D+R0ey1Ty8 zl*m>_0emqzy1mw`T7D6-w99v!!Cf%;z>hW#7(HoyMI_ECD(&aHU3`$=(w5Ms!yNmM`AfcjAn}&@Z~w2hRws$ zchjn4Y+DK7ZBh?l+eFS=e}w>)&>oD~;JC$Br~F-?5^5MQ4jl$}TViKW8Rlmd;ar9= z2hMf$!%&Kw*&e5|Y9YG+npr2$mKnaMiny(wI9h+&MM8(a3$)b#6}yrXg6~7Tx9!I! znacgK>#wM_Gl#8R`{gOeJmzb;?onho6Q;g)GZF<@Cz9P{PbzmcNj6 zL%hSa-F8dw6w`fzrfP~0Hf@EED;*a(lv;b_wJRldQE)ZMaRLsMQj1`kLC5b|N~%b> zU)NneuWM0NdAU zUx4QU=Y<*Ip>L7W)w#B=;C1y~^dj64 zyBS`T!fo?W{;8j~3}c$4`@(MpITF+RETa#>t9`MErp*O0Qave z@#eJ2A68jixn24Q$yISYY`cgVEZMqbNt`O)f=&Jd=|plFw9qb2x5phhE?WoAp@ofF zeUCSD{ax-k6QvDoc7l`br~-Ry;0L^5riqLk1h~*cppLg5Hmk;a^s#DmCgX7~dOFe8 z+9l>;DDyq3x9g(+4~UZeK!)b#4AUBMdONN6>oEEhjX$aKUBc|z76yoQrR4d#Hd#?z z*5#Qh-HbtrzKrp?0pZRI=8~jsw-g0E7k|6oM{V@*c=HbIghnTS1`CZ ztq#oz0Q zN~wI(9!lue_>`ugXwC8@*NE2>y6KI$x>TPi#GH?xA#Z8YpS4!b6vFVBNE<`yINY2^ zOsn^ZDIB!oGm(?Sm(MScIs)Pf6nUgL;ub0s_p)Mg83wLm7 z3n%uAlc}zmJqOSo?j+;7SVnmIY@#zzQ8f!$`}5A>TU2}e1mgF-@JnSN$WQ^asX?wn zsQp9=Y{cvh16p`OHk?|vLm<={ke&?S40PMG<{ra77=tG6_y}I0ycDK$EYDW7fb~S8cFY9X1LzqL~HQeY~>OjXATQ> zDdzSy09{(Io+qrHBi*uie=4WO`5iQ1H66B!LnQXKB<|pANcRbn1d)^1P>=gHLtqLT z3^5~QIv-tUjNy7#FG5r7Ag1W1b6m6ot2vL?8eqoBrT|ADgj;b9XNOt zi{D* zTOM!l!cnIQpbv($xTBO#Fq`M{l5-vskLI^^d9E`8Zv~EN3F09=sCWT4{rw`hL;T0b zaO~PSYZ}_KKkv5$klX+XXQBieA944j>_=iAo!fQL*jsJ{7k%5x^XAiTj{2KLhl;*Z z@f&HsO;j5ljiBSxo!T!dhv72VPf=x)eg>cYA|n3ygoyp^B{$kz4R!VyEev!yBBGBk zUQ_11#tkRY4<>reYL%o?xiNWvHQaK#IA7Of_iR?h9rLj15|VkHIZG*h2<6xOm~;AE zqN&N$c(l0~c>y4`Sh!Ge+8y>si`E|E+}}Rs-e}~8zZ!nppdt4;4n+J=94?H}=vb@B zOPZYx8s|+BDj{IFM@av1$Sp|k+wiv;e({4^!kg!_s+^^klh?OjkHawWzax^+xKCM0 zWQ>@>q}JsuIl{U@0sbfbtXsThB<_ah^?sKj-d;D}>s1Dfm3$X;o`Sm;b~s4)6{+7= zm4;8mX3~Wxtw<%#U^LNxAg)SLZI_E6$J*_mGw$F_qfbZ!*oZFVLF6~NX1I=r{!kwt zqSli*|D##I;+3fW8e(>|{3OGtciS5_Yjc#j(sc|cz3(BgNWg6L^zaFEA4m;pA0$Wm zj64>jPXwlJeXFODbFq69+&rW&yh9yFEZ%M$)FwS3(V~N`qu#u%Tcv)tO;=j^QgqPmP}Y)QK&U^m zf1duGL!@&f*zQ6O7%poj)LZFo;a90paN(XfjZWA5TAL?`{(~*Xi#CHk7GM1wwUK^CoX?rmkTW$H9Kt5)eOruERRo&O7wZ4BvB(#hYLZEn%`N z@%EA5VT15$At&T&h49#HAKS4dgllQoCrNdsr9XSQp^rhKc~uCuA@JsGHLwFG19~rU zHg8GVjZDOVCM)uqt#Y@N6JsTw-)N>JGS{PfU9ZN-KCIdKORR7?)@&rxE``J;noBCL z6}vl0rgYgtOUigLnBxas4^e#aUH zO$~gOzlj`cMi!|M%fqVh+t2Q8@t`)}K-D}Y5xiT(`K$ZZ+oOZNwXr-0;h|+EjOQDK zj`W8E)D<0=kgNDDNJmBmn4r@XL1a@&7MvOa2Fx_u@hZ(xUAB}iAnK|RSqMp(?9m|+0HxHTaio6apt%^>M2 z-S~W)YXFF|X-n`Pv#dDh)C2B&!M7sSZ-;3dFXF8hsVveY8A&@3YEcSWA<+t0p1j?=8+Q3_e8TG1*hK?ZTOOiGg)#l?)^5g z;_^Y$A*Q|kQ7%Jv+@s4yn(6!P5wgJC-|mEF82=R)Axx-Ts797K9RDgcbRDqe8Yo?e z(5yzF?NH0F*R+?0d9{da2X0WJiUIJ%1tjTpeDf7#*7(tFP>><$x0mZ#2=JqWVf0QK z;I*5I@dRecA6~>>7{iHcPUME?ho_e-z>WYmVv}+MG|D~CultYpl2H}|b#7^jBfrNSt-~ap|*Om$~eCF!?NHTOl1byvi>k3SPs6*1v$=o&XVAn;GM(2KG z?`hhaW=%(9iiiVhW(#ypG({3BlS1g|>}KhtOuUi>5quB7srmpgu?Y8*Gk5xV6H6icS@p3#Z5@<+sL4npwF(@x&N?k*21eKiKeyc=7agIj4B%YHC<(o^9v; zwmqUT?Na#YUZ2?;9)4$NTj)|D&EL?;M|vddU+z*xoY)i=hJ*#j@P3AI&m8tUI`fOC zi2yuPa_19tou$5Si{0Gy1Tj}`^JG-+I#a!W-^I!~(%>oDm_Zqsfuy+|>^ek|dZv>3 zG}Y!>U3UtYl2AGZ+0jS1Q*9$GM+Vn!TL$M>yQFbOO7U4(>TAJyb{f91ouL1U|DrF! zwCzP?bua!o?KK(K{+afxlVrZF<2^Yvqeu@t4TF{b=H+LX(oGf(ebw4RL*SehpQ8tm zbdDOPsk5wlQ{N042z1?Gx{1Oma|%B>JCKj4g_+a%kpJhwjX{Ob7Q@^I*D{?(Kcz5gWh1s|@0YFSX(xzPQlkgI0;aJE@VpPHM+~7u-}=ku~gb ztcrtAi0HZTAv~3waf4L+10eBzXGj|%`j#@=mNqPObIhO3My_*n1^4j=H=zD4eB~5@ zur0uB$}0)@A&zyf&=r`nwJ)oisJ62^5^=l_ri5W5c29SanMAoYQFJ&WX&%?er*-4Y zu(cbK;ZV1g(Q@-=>?NA3Vq);lKae}!UF?~}Ub=nE3uyws90)Ebkmq|24<%uQ5ceMp zDO0h4L0WK*W8{gu>@E0MD!+`ecowXA7v{q{8s(JH`WF7nqPcRHn|rBFSc%e=lfG{Q zd|NwutKGFS7EX90aY8+SF{#X!(cAKIm$deUh(A&C;bx|qaf*plwu|DH;pOQtZbPe4 zVBod8e{&o6V>% zvOgXSyz@1yvl_Wsda2<}FcBeJ8+0&uj-;FTH$#xe(g70{Ays{-EAF^`BVv+f$ByFV zD9wW6#ThjD4|Uyg3KE_Qu3?6_+?98q>0+OL92zfqLj2awO6knkXc9Njcxxas)JTd9 z<{rV~5$1lQU0SGaa*CEidEy_q6n7CWc<=wlhIFqPWoJZbpz3?JmsU$FgK_!r^~+Pj z&Z;2iIv>az2J;MXA!u$`jk|yX{f0+lO1!QMp$ph8ZT^-nUp@sCVCc4C?r3p|b@`ml zEoB5C`AyO4w1F4kFO{Kw3uDoY=Q4`927=i7U0LiWg6l1dHRfyrB4J zd)|BO_vOTrS6PXN#>Q&0+Vt4wH={GyT-l5jS~;bEESjrQ-w&_16c|t$nbS@KKeTc$ z*XvfwQ$&iDxZ>N#M^JD{cyhwD)v&{M+YTJy(iG6Lv3Vl(1uX3_#W`)Ao}D~Rz>UJ{ z9`Zwv$Tc^leP{QGz?B;X!IBivyo3;@rkL@i#~^G*p&iCjo&RhG8g|L#-g%kLsHK~sE2)1~Z-TN`fo zRJg;XPw5eFU1_Q2nL3(lJ{6|mKL%M%ofwxfsvyuM87cwA0=keeeiE@4{2-7*y@aa( z89H+g#<)1o6@UG%enI-N;<3!@i-h00LLYnK6Aen>MDz{65C}JhX2QhSW^f1YFwpN;gUeVC$ai_NDSZbq^sfQL(bsv^uJ>vBOZ7)Xd*^D(>SYl7Y{~h##9ya`1gztIw~tX z0Ac+r%m!ErlW43gQ5yLE8ci# z<>bxuNhV8Gh}HIHN2mU5TnQJgoOElRWTR{446PXa5;xRNkN&=y4UW*J$O&!M3x!pWEZ|oFdw@n&u(}v|H0lG<+1VFE+uA~3&tQSd#j30V7N!{O^ zF5vR}G=^lN?6u{Kl^0zT?8v}>{bLFhiA$#iRp#NYHw=O>jRnZQ(OFKql(Liwj#h^ zWh{SJJR8SaJ||#>E5H@-B84j=zXz98u97o0UrWptw<(HZg&;xllH5~C>U2>s50q^- z=+ZG~w#|h;j1S{>$)w5L@2|@GHndt?X)RQxM&U^9kZ$K(tJmO3HfL6+t*9P}(-s0x zx0qbvE1SYZru88;$-!P%bF&^Io(`cFn(q0A-7txnIXteoY-*I zyl$M?VK$BNa(2h`cZ96Bx-XGUHu2-}-tX{cxblA)?Pw}?^&Q2Ya*3wFKmPECx{fEL zozk*1HR8JxTl9xbO{C<$4oERsVfgK$L9~r^(`m*|h-%Vqx-;l9`e!B^MZ9(+KZS~$ z?23~GYYtKm%4V>QlN8_x0oK0^Sql z8A$81@X{IGpMdxn4)!yKgvW>>6^Y@_3(ph4qV60PoKteTjdtw4Q|X9!UdgIhZ-?W_ zmo-Ao%{B5}Ttk8@Up5ziHaGH2e`q@YBvtN|<7b)A?}nag8+2LCG_?8HOgW6b9&fV2 z_i1lu75RZwUrS*;@bMJjTPLjWLvKaaK^A4lYz@Y5IT05hxvLKn+-qh*%FWgdNh!h|n_*q!M*P&9ejB-95a4csi#;z3*--!~pk1`AnWSvTEuCK{ zY{yk8IQ?@Bnc%6Zvk`(3F(SMa*F_-N?1Ag9N9zYoY!Kd?JV?zum-gS>8W@@xZ-vz2 zAl1L-y;mYAp+L$JS^(GS7tH%dzIGX<;;bQbn1nCmm|W$d2_i4P^McBDVmGsB45%(6 zw5}5WgYLyFmXH%ny&4+n|JtIaETrWO zQ423KIc5;TQ35>;x@-P%v(~_y-JrwOtHM(_4@6Q^Wo{>QJA1gdXhbSv%}Kr73ctiJY(FURiEYv#fkWJFTbt@h}m#&K7sStn%aJ{I$mGnq1!Zi3VlY_?7+0 zrGvfxDXLb9pOUoI;kz}ZGQ8Xl=}sqSE(5i z1Ul`#qMYGzQjroHVp}jrdzcu6C3?Y{WZeBVPc)nV)OBQ%%$sKRQcKYKk7v&-Qr4%h z6hT7saW`O1o=eEQ+qzy`dofA1kfsub>75=svRPZaf-ZK7tK1VLIeqj}{qkQ+hn!1F zkU5XW=RvlTk8e&#fZR)l%g_z?HkY2 zftlirs4)n{K^3a+T!Brr+y(YT5xRzmmQc}FiVQPoQz!eVwa<)k z6Gf$A7!>x>+k)7zNi-5^e1sbnaL<$BIqpW5d6ltEFn7NThY&}d&SpZc9DIra2FZ=f zT3(O2q(#6bZ)3fjHUbiqG@Bd@zR&Hf4B~7s+LS%jl0RCFU zWbh@POr6awf7oXFRu?Cw7XF*$=cZP zq1Z~jNX;GKL821GA zZ2`tF2QK2DwOl#eVN*gK0to;zwW4j*FP#^Z#R9>%Emzf1Ot3wn-QC$a*B_Y2QXBJ9-*o9BW>Bk~VYst{8CSc)$*% zT5|2ehtEy7M(&oi(c5IWG2MA?($yzS^V>i;>jlJ53HMtQ9p)ND{Am>@WR)Vcb~#CJ zc1=im!`9Bu_v`Wjw7+uvt0$)n#^usw_{OH`T3!?#-SuUYy?+Os<*Q~Jht}aGF1Rx1 ztAFlckPN8nk>ckr1kEJQ=}Dl0dJ{{GM!WAPa;I-Y3%rZ%EiIkA&J+7B>^jaHMOzd1*#*@>N7*c zfOoOqmhIV&ff6GiqRgdEGA%8Q=c0sFL%NMV2?mg18E%VxvZFz|8}&HG=c`uVDs)g# zRoeR1D^hu}yJvLy*p9L$?@8ZP_-b)NAD1nOQi#(Apcn_<*c}Yb4SyBSuRxvHg_+tO zN;w~z*p!{w)8x#av_9rYl=%#pwM}?5(6EelK1aWexmU4-TFWJ%vbYcmPov86+Z6mJ zzEDA1c=d^jqT6q+rS6~)lg23;HX50X{jRB^nuPhy&wT8m{VcmSE9KfwIuosnZfl#& zsJb9v8foURq@#Q{PiD5vtLKA~A-ke=-wVn&vf0Hp`KT>PLDvc=1p*x6_uwBqyJ@PF zzHxRZo?Z71o!(h=MKS^BDE>!tq%&I%yNqgzuHB+RU6|AJOA&PI?aZIcKnOkHDqn)r zYoOg({r-D8vVKim-g(f<_h4r=@`rSg6|KbBo87_R#`tbF?MYzL*Bbr0zis*dJ$K*= z@!wj92HoExZ9oY%JRG_u38kVB6QtPG8*II9Zce$&5eI&wsMqyC9fbyAhcD&^FI1wq zv-`YVq`%E4u6uf3!g`g}CD$dLGQI$PU>-(BbVwY3^#X@p*qL@Q=sqCB{iJ_up~$O< zm(9z!_U*T5a^-d{O-zEX6+wH)QJ+)=nZITx=Jv*Q8|N#Ae6tV4+~1mIj{NoOg|G<}figsyH<3c(%9G6*G^2fpR$Cxj-muAs zd3$_J3^5YsUH~%8LsEg4dG~je%tABmRux)P5huBs&=_Q)uZxcj4|13j_qqTandtuy z7x-KGA5s$)>_hR$#lj#UVe^*}i0>TdVyRg;VbD2NDN8q63Mk##VNlX#lg$f6Z}UA- zDfWU_)GvqA+0`kp4pZ+keJzk>dRu0b^__MirKn!%MXa;Ht#y*oC!|lV)gufMpdGA< z@zZXMzd7-B9Btgb=NxJ-;gk3QvIxtVJ{8bYVIidUNBNgswBwN{6xEA@8VnpsD0F4D zU;q~Qk<899HtZRPD7}W*Al&3s3mP~{9qs7D>&(_2>~7>NApMWM zsv#v4lpD;r1bsx~QYqLg>5uwri|EewfU;oW1DZPqhVEd`ne$MCa2XD_HaJ4yx(WDw zUN*z$S_(dBF=7@g>7`iapKI{lUutujTxTJ2D8CFj+fhcC*;^}6jWc4H0KGPKLRNsY zQ7;ysH*|oWse!BHf%hgt*??73yB*yxn{1cTu)ry!dXQ+oKz3F92Q&CyW@7N0L$kpS z$z|m(ZD+Tb#*_6{Ak`TongcItVE>Hprxt2+6QUcy<3-7p*~2{JZx(g|6pV20hBsXZ5=DPU z$Ok%^%WD1kqbC)D-i*GG3Y+o2i`e81y7MpHppoAhc581IyOemR_o1sbh^n;y=CN`% z@4|<+Q~2KZSitu;GZZM=TV&`1ljx*^FJ2s721&*326+dEy0=*3!}Oq8QxJ4_XeTpss6~T8`|0dM&7g1NllN?kPo5 zA#SBOMnnlln1M5uunne?pxQH=^xgKY!-U=rkQ5=!RHBF8AlXAk_YFwQc0X`nSfc6h z?*vaQ5@n$=T6?wr(dDaVGkVpl#g_#tg6|IZRUcWYK|Pk8XD&{?h_|cANoe*zbb}ep z)xp;OW0vWSp0AdE+EIPEB3Ve^aXk{Q?Ga8^pT25BQ3KLp5~Pcw zZ4_4(xzGi$+z6h{I;)*6ZKF7fI0k@0=2vS2|y?)W*sX}@*_0{HS+UrJ19}9o8r@c4iW2N3OX^Yt` zJbSE*m%gh=N)gzmN-~|9nC3%3-2$1Wjq-Y6YkCDIY$FIpUwa#}R;yD^$ceQTTIy)y z0i$!Q+t=)w!JsOyC>u(fv|FtgP z^gifjeJGnJ`E*Ent)bs!v*Am%3ayxn$&EkBLR;;+NcqQ}^dW~xkZ>8)Ba7hd*`5DH zHv3y}vO?GKa))=&1?T2#FY*Zc4_sRN?}P*y`7E)mhn8rY5DXI-rv#O5Qsu>=cIYq8yN>@+Zc4eQqL9oqUZ3R%x;ezh!1+^ z!hCh;MPs^Z@jz`m=pL;C-^p?6Zh%63qj@x+hZ*~rNy|Jwekbeyl|&9@7LjM?ilE;{ z=QCVwVCNnE>hf8iiMUIBigJykPT~{>(K96LWLc+<#SS(^`xi&Ur+NaNo_bOTc8;pn{QUEaZMBm5 zcFi?YYP}&!Ne1OUyO5ltd9Hf=@tK;R`K;fO!BU2mX}PUaTqEfZ+23E;!(b0Yu06b3 zcj!ySQxUUxS)-Rf@|yS@{3;?lRu}kxy4j^JU6|GcgebjYqK*!iQUL;|@-CSy?DUPw z#L$H3oiJlE@ARa2x+y;EQGmJ3Pk+eymVbX6b9!Z@K&m!hG{}N|sz2Kd(szK%27g^M zA+SA8kg10PyR{Z7)r*^EzKu`j7**|S9J}e^H2x>hmW&>=#KE;Deyxfe6{km?{BIQE zZ|5g7I#`s6Yvyy^^YXF7?E{W_iL%?#;Y^K%fG>V<{b<+hX$g#FY_2apjiM9E7Te!J zf%gIr|1jSp6)iGBstkg^v)oIfV@&a?Cgqa`Y6P8{H`x#Hm!E$4nyFExFVl{4aQuDqNjVuc`9+T1m(rNG@i?w zj)6UrCS|-g6*#8x%eMi^$YgZ@WZ*Ss%&x>$SFT?67yE}!_ z;k#kC*v^Bm3>tfGy^XJj?p;-9XDD-lSj5rpH;>U+!I#e5=xfl$3G?P*y!=9nTB89LDB5bdobVgW(;j+|&u5~@o-N_VG{`__mJ;V+2;f07^O3)ORqi(FN z_VJ3?d{+S&2{4Fww?Q9qC6$o)(BmhhDp{NboB*Uw z$@-^2>co__M6Nu^2XX1iPomfZw)ekkvZ+%d-=o8`ka5bd1LC?b?&i)hC=J!Kesmog z+zrmJ3~N04_f`84sX~J(CCrcO=O?a^$$~k5Gx`pT#!}_eMchI<0174gO1V*Ms?}yF z3hl+<Q$u;s z3>2k&>|HX*JyM9sV_DwZ-J7k#)$=!WV64v@)pxz7psnv1I))tAFKG&AXlNYpIx&*k zZKEh$`9J2`3N(gay-Oi9{zhHYg6}C7LzP#wpRrjnNZ{3BI{%@BFl=){v4Etk+?Ns!s)PO-Kz+Qk&w~UA6L$ zeZcD}J@#=1^OqSRL-z@z!x2ZtO`|kA^d)CE2aVK=n^QY~*Zl010{7<u@t{c`%u_ltxtmDQ0=+ z7M#w34po+1^i{74HM5 zkT3Au*4tJZXa`K(0A6#FV3E&n;)WMs&d0;$l&)I<$-A_<1Uqw0gWkl-UU{G2@`)Wj zM%Q?jp;HL)D@Jj2&VbpNFLtzE)A=8C3-XXnw(+4uJ(G8vmM4$ z8PLLsj;=lg`VCwO=(iq=SAfS{(fw>E8W#nNev^*+!F%W{Z~Pq(^MQy<$R+IfYU_62 zP(LF*BDyYCLmD--P-aM>=S(nX%68}GeBp1Hyv(bGg6$h!>KgiYTHH#gsv0>{{9OBY ziQ~?ELErTzV5GVME|#1s=W@0{)Uio0%;tR8`p&@D*SYj%1I_OtqKTU$3eH7cAA7>X zsxxZXr1Id=p_uXV(fM_;KJ+}Gv*{$nIJ;&&;Rqi+d`ojZJ2=JmO5ZUQ-6Gbg3#2b@ z$f$RgF?IU*g9x{gU#ytvF9`Oc9TSkz9IH(BuNq*6U^A0vQsKN;vU5Hhslg^JlsV{N zkRi>gG$0C5jg1vhO3~eUT_mj*4p6BIA$V+*#Z&aS=)K7C>tm_SWHn0=UB=*v_r}Yf z$^oIAioTyBV^z~mi2H^#wIBAfKjEskY>xr^&f7{JvLuOaWZMs`S+1+{ugl;04KR{* zo$%cX-xB>9$z-NV(^$I^A6$>jc6||vGy{CMsSMnrV!N-iy;Px7j$4{&5az2FVDvRR zvy3H5_12SHE=N1jmyfwYoJxx~UUh51rPy=y3)^f%t7lNyh{r;X*KmBm4=vWA9#3OI zTLCh86KdNidX7Bj;eCM;dnUmve&z(LyiE`4S5URrtOEo+^P#iyfn+{QKyCo?4y%QnkY6u+MR}&MU71J;pc}ay>{YK4tcvJF8u+YHx#ey9Np;JXXW0@nAdF3vvR90ZgMs%#v{DuLJe!ds77_xMCd{Z3=|%ZOY? z!-p!SA3Z2}k!)#hzWb-lcOyyV3&wO6(!QByC~yqnXGFMte0lhXjo(D;OFTfX<)}}^ zTy)JCqV>$?rRNn3C&v%>_5O=FcQCfV=GQk0`5C;_{Fz(DsYm*GVi&JuCT!M5Mn-D- z;7WW{g#a~_WQt7;yPk64lt%L4^~LewY8V-7t_v4wI((`TBQ{!iV|KXW;K)IF`cK-z zj2xCpVnaQFdVI(aQGhpTy6HqXKRrD~am#f5r3pjeLC^L~BYqXg#zbK~cluNiBX+>J z84BRa5L&$Xh(jFIy5sQCD(aqb+Zy6?zJ+k0%gmeWl@YDlF_3)E_d63DPehCssXVO; zs*7XtkbO6TheLIZn;JX2hg`umSPI{P??6_}oy-)FtFv(q@R5tWn0P>a_yBFuDBPJ0 zUmyASG!Oat>Nc1TJr_jgIW`Kmtxg>92j@o_GA&U>xlS+>amk2nQF_Yi7R0uSS)K@O zJ@otzrzrnMkZLpXc(C=0s~hQ#Q&S|?lhxwoyx2K&7m4ZmjKK@K1{S)f z^&%edS2nrY4CyW9f=Ze$DJobbYu7?m?B54REQT+KRUG|3Fc4`lgFMX|1;Tf*S0quw z`(`|$xHEK-Rdl22Ed=Ak-A9kN;pzu|LZ-01L|W>jsaPSb%r7L1Y3Qbr`7axnZ#FF@mYP6Il5J1L6~N!f)FeB0yPTUtRy7;`Hzw0 zFAq?Z^CRWgzh z|CzF@+bCg5erGgjcW0}{?Eb*-cY2~|O1axP!K;50qS?AF z<zUs$}jKv%FFQ_%jKK*0-069K^JNbPFW(X!UfTzF~luD79VDr08%7i_6{ z+2h7{Yw3)3K%&IeVaRg1!|#vfj#Y^OL%;3e5Vva`W1G+yGu4{~AnyAqGmJGvyVQ69li;XlW>nockR1n7a0{Um?QYl!(<`(|zSIFMq$do)mQ(aVD1^o}cT+DiEZ+ zn$>V)y_4oiSaO;eBBu^7w=&&%UbPz**oMUnI-&yA{+2pPo;?3;(XM1u$ZaE}F3Qxh z_I|%@i!?*##=)-PGx>ve9Vm|7yE#ym{a z20NL@`V(x8qmRdA>FRBRqg8H2nTp76je(#?<@%hgxNk1IACxx#s{8U{7(Mu$BN@YJaf24700@@6+U|l>v%U6E#~@EEN#& zTC~)C$li7p8GuyOZX-B@o^TksO|aRiZ5_&;iRTTs-febB`nvXBL8CGXS|<+Y({J&* z+7UXhX#T(wyDmuhKu1E&wnD6LWX}5O&zH|YiF8x8Yx7%qebvE1pZ5|FJ`A;z*8IE~ zm(Xwd15A4uS6Z{32OGV-58i4m#%faU4=@2!mfNFpx5MtRp8spG#2mAyIBFt<5n`5y zYbugk=p{_X8Z&j1kpUz21f zpYa3*(2=H8^qKtXy|`Z@ZOjuW!|_Kx?ykCjK75Cf?G>}UwS|p)MNX3V(fEJ&IF~y% zxjp4QTn<2)&#~{ps+(65!boMv(?1lb^8L~xm%&R%UGVC<*qgqE$ZX{R+%{8#-YYaC zMUa94*K{-%rHtZ$-@Li48oa}I6---s0enc{ZLkw)2c80dNZWV;m%zv+4>zo}I_W2@0^%{BI81@1U57(-usKWG$@C zNGJ=Yf7cEXaDhrNv>h}3sH_}lC0mIUv>Ys;8ThzhpBsCcRbJhLC!19h#2!!Me~qsx zdrGCuDBPz0d{kTA7U2x+q|9~((FOa%d-#^{u1E0`#nsP<1W z9GY+cYpK{S;IZ-g`s4)lu293`Jj8e|fl|N*WeWQY&M%ngAWSz7rc3`dy7ucMp$a3A zb#RJ64!&x+EoBlOv9z_?Qk1xsymNe54aUMhj2DOgN+-9#_@ycy#Ji&Q(u|lVY-Pn) zs$ka(4tpaC7YzIzLe$Ns0ovWaZ@rz~AbQnEznyYnU=Lp`G@}`C%sUvPUOd>Z51cQ~ zHM7UuMsccJV=JjU<8h5N(%7_nQ1fl=+JCk9o=-x?Qy~$#hT@@PPN<3Rlq0=c9i#6z zhLu{RxzqFFt*7`*gC{seM)88(AjJ|%q)>XG-%mrj*^UqJ^%MD*hFo<1!1uY`iDPn% zh67W--aV`IccHGjoZdXYH6>lEe~esF73NZE_Mg!P2WhJi8`BuW2#{}_l4(>cw-YpN z`8TW|Fm0*T zsyXu#$LwR#z1wR+OUSyQNun>m{=gRavjqaGZv-5Q-g|;PP&!iIz)m0vzRUv_o1j}R zWTwo$-^N|>OtQ0uoR5`&Gr+Y&l>+!ZLU^n4$!D8`v923jUHNl)nLg|2s52X8TIh0v zjLNnKvZ6PnamvkK+&nPg@y;rJa5e*E}aL6 z+-C5SxJm3!MY29+3~hpF^ukX7Cots6U}s@=Jr_C~mb^tf{c-i652Iz*KNdVr1$r<; zIS0qe*JAP2Q{=H#yz{PB7X%Dg;5f)P_>x&PYZJD4z1v~Ru+&=S1C~-12LV>kDGT;9 z>Z&q$UWfZ1(#LUcXEys8v*W4!2$6d-Q-U=j8{CnTAP@4?hCY2s8T!rSH{31EB3m{jTR2%B8a%g1pRQO;89iF|ys^Q1B4#UPGn%2acICW( zUdh-~BH&iN`-%$Kaya&*qT)N$k0t{oM3Ai z!j?kIPPCD=`2z=yr?a)xQ;M4Cplu5d2E(kS%2?222?(QF5C)24!!Rt`+tV`1b6opy zJETpc7o2B}msX5zZ*QA4&Vd2aTn?hD{|)v2?N?JN1PXbH>78knl9^tLy}p5__8DG23npW4BT03nO8cArUbSCZTxyst%ISuGPF2>HV6gAf4Z(YJodU zjdT9(iU;$+JaA3WSz*Q|CEh$H+x^eL_~{Ool4Ua)kL%W0KI$8k>`;<0CM_~yI%CmL z?6t|I{f^r8QZ8xL>k?A>dTh(dAUA~9>{_?{^$?qvwQw%Nt7Eh~WMF@=#8z|bR;_rF zity?7a%DCpZ{--fr0z4WBk!`pcUkTi%)YDlPxe{`nTqO6M7Yz%|fbf$o?|Rp8>8_>bR9)N)4*hLkeA!};R*SNy=ps@RgY7C2N!DmHPA z=$km}|H`=(Xu8g0D!D=yXlJ_ zI92U(LR6<%I%@3Y1{0YRt46-I#(NSQI?I!1*NrctjCf!f zcF?Xm`C9v$qJ6)PNaOL1D52g=(u*45;t|PDT%ObKBoxE>Od_AV1WA4WNiA$MGAO|A z{7qnn{CAs?ew#dCr0fN;2uorp%XU+->qANE+D(l`bB!A;4$$D!6k@LK%yto*fI_MC zvd=DRcB8Lt#ysejX_e#x!WjlE3GJ8Kh!t)+G>v3aJ%5b8nW@=#aMDWZdFq-_R3sc` zg$t>QHX9w5`p((pwf8=DO_&Sac_&w=P7L4D&Eaynhk$Bj zs6Ip0a-f&pwVdQUB-*4Uvu`XU1!H^*gB>`f^aU~}B_5{M)>EuWCXEzL4zfA5Hp*vf z7U|}#J8O}^0o9An&CC(T&CkwGd}>g*W2+@mreMDSm)MvRo85v9)W_MXZj2Hi)14fg zcQN&`Yk!qsqC3eJq{j?W;i{}!rX%dzG6_d)*fTGCWWN^lrCC~G>j_&)h%K)fp0DxI zA1oUvtj!Lls-{>jyd3>PJOYnvmcZjj;`m&DSIizN&n9w5b2F8%#$q?gds6zpYp6sD z;zTjZ<1OtEU{U5;Lc6jeMluG|vGx4LdiJyJgA|-d-LUv+J8JkMX8hGxZKLJAtLZ;;?#ZV(9#`K7(I;{-GhvAM^;qV z-Hq$nQte(-i?8eH9*Ipp+0;bf(&1anWZXoM$nKPNAdK+BTbs=@X8n#lz0jvHo zm>HJEUEP0sh1gqgB~=5U4K56w1pi1%p*r?7IOMXZFWXn{n2J<@__D2AC~CusST3zn z$*6{DOXTn|&|OY0_$v2>fRzyq@}hm*j>d3-`o?n#%&ih=ef-` z!|i_k8-+{zDR=&}yZFPA`-TPcL_AeUGhAmd1X>;C0ffpMc|EcTvJX(%+J4~DudRDW zv6}n`&HAY|!kI}((M_PO(~J+0O#|<5{M?Q~AlFbncZ|%MISf|j*XqDF(qs6r_o-p~ z@Q9NP>1yzdt}#H=lr*EK<2{dF#vrPyHEEGvyp@J!m_XJRY1Az5=D#44<331-%p};o zxgzWCRU(?`caWSny8IiCg3`>`=-=Uiv|P58zc)2a48blxJaumVAAlipF~1*-@gfOD z?`UD(nh44ol+Yr|2i1Az9dLUIyb4X_Te!k^i4eDJB_h5nHbGtw{U7qT*vUEXWV1sJ z!^MV!_uz-^dp~!Mh#y+9+TwPOys8;+afjAgnu?5!!dkNV2HtSwg;$eFP&5s>%DJ|u z803vdQMoE>g(By0xhhsF`HM26u~yLmsL&|pE^0j>xl;85WwFkLsvUn%>t#ND_~v92 zorCkCOJ^>2i?|Xjg#C{-^=iOX5M_RcFjLEOW0L{1$5P$$N(N%g0;E1xO` z-eX|=e#nE{?yB_(uF*jS#fxM3oUM5!NV)=~VpjRGF_E$JS*<}n^5bYvY;#VCqUIIv zsPvt9#ze+o;mV!dt@pgFM#W-<4U1gIsZ$_o%CKny)P?b%d|=@x+dD!wwJ_83Dv-7t5n`| z7Aj87)8g)!plr*oFtS0@V1Lq4*$si5tgHw`(;{i9Yb`#8A{y=M&Em6AsbVdnFe@hM zPP*|N_M_YgU(o{Fojsj&#qLsU?$U6jPf9V$0{IOu$7k8^1%DGqGT=&gQErBTc$5W{ z(k)5xK%yrwC$`7M!3LJY^;y3H;@t-qCY;O;cD6Kv1pNfMpO|O7Uu5<=hOeco?1wHa zFxjnBB}^2`vDK1B4&cK|1I~Jt0bL1|=xaVaGN!n;3oi-O)>dIm!aAea;zJHb_h+O_ zKJtIg7~$d2sA>s(dUVyxXX5num5cb|op-pAE=^Ad<_iNTx;v+{rd^Z% zF7l7F-&yrkNiQXWZ_mu7v!h?tLc(7d9?dRf7q-~+x=hZPHI2X6;vh)?FL_F8NbS6G zlK(NIvu7=k$azI`6u;3rBYYta2r;TwpUI5 zY!;BN`_(FI%aQz}s%+5a=5q4${EB~6TU+Z7WZ-WL&v3`^;vWCrto{8pA;VHM@3((V&_Pqd^_nsv zl$z30yi2>MiJ8ASLA5t%--F9Vd(MO>OtoxT^ZA@(75qvn?#Ze_z)1$B*`J)3A;(`? z$K&if-B%UBYe?xaa9iI@F`mn#qfR_NX4x(ff#}lnrE%}ybwDR(3n*pQ+Ee!OO`-Lh zmS2A4`+n3@PlL7}j9TiY`sL9H^{h;*$suRrM=xcJclPyoz_)eA>a}^EboE`vp|jk{ zM#=42^d5`koPV))8LZ+v6WfcU4*f|IN^&M$*U3idd#9acs z$lj@C?SYKnijsNQQhLSJY+Xl3Q-IaoTjhgw{QP!sV%K@yRo<_b&4Vxok9*DP8nyr0 z0b|@s9;7}KHpUBacpTQg8P)nM7fQ7aw-aHBdAy8BzaB1zyuT;1Gwt2n=vm@r5dCU@ zYg?v;wuT4|Xl67HUFpmW3HT)>5t8EGT43P0Xm(S8l)!xv+1XU)6>lHosg$Qgs>dJg z6Hyz~nbYD>*@&h0MN*shK*XZ-J+1ky4ruSoDLCqZ|H-bl9e?u8QdrVcjBVpxhmtfp3B%cF@kI9V072KanpRT$ zyYBtuefy+>vFu)6Rrb;h`rMe+2rNr@ORZYTSPy!<`1M;%g1EzsHCDW2C-1l=eGS~N zISAdyk?-9fT-(gtoN25PO6E>AqR1YCa#qV5uufgYP*$`d>tfr79;v?^PK?*h2lE;JHP^;A6l0!he)aVXPiy3Qm$Rxy zIn}=&IEF{W74lBp(66(ZFp%v}gPMrp2RoJ^$=X^G6?)tT3hk_->C?Ire%|gak`q{g zV&#HfmN`iWAKk0Hw!Ppr)@|1^pXo32=5OAf(V7%nUAMG)H)NRmZdA3q|4CAT+1lO_ zPa9vn{j^8E=wJyIDs!wuDP{~8^K&g13r_rE9z0{HL82;geNk#arkORIxJUXTem{$GWdOy_L9~3U$%XP8cID z!Zr&K_I3dzFmafJR4@MtpnW5*ux`7Tmt%60;kK_XVQHayC+x;V|4>Sy2 zAS$3YR|XhCWT*z(;9g2|Lee2W3GzNYW6P2^t+nnPLUO|r3>ScK!vBk;IUNlvI(&Tkj z++;sn>(kCdge5TaX7E|=w!;Y8OJD28%dZo(0s?NrUAvTQi??W~$;AT#><@6G9{HKp zR5y#1RbdRjFi)NBF57vl|5(H8AI`~U0~7~&9q6}4-oW@3RCDJ;Y284-yYxS%`N0G`L%DI*3CeeKdKGFW z@N6R^PG^>B&@9nvaS z%ImolB(WdSB)#4lsSsl)cR+bD=i&37PYsn1R^+x|e|SyINP>c#;kh*5>MReTwfM%q z8h!7;=T$vKIMW&WZv_}U*6m2(GuNGgzD1hWvZ;cOj;G+?jWsicisLWnNMOCeQ80vL zDr%yA!+<8ARRx3l^NqC@=TMAXoe!i>-A)Z80tHRqY5MI}8?>Lgy7vHh{o^oi9rUWJ z{irVH0+PRNf*F03C^&DBC)Sq|z?Jt~X)76w(}dIi^GE-$)6h}iK0o@BIr65p-mBHR z-Gleli!Q5LQ;V7WAm%`mt|LLOS2TndLl|1*^yR~$u}#qw`8$U*kTD{4eQ{;^c-^Ai zxm3^MLUkXwxLH-9$A6nPI_=97>B$~uCqfPk6GUUv<=k-cmUTfET)4&aVYbgI3Y}hn z{DVN7st)>Jsw(`?{XpNL2w8sqY8m5NuiK&gptmbkN9U`4i?wpqf4yi-Q$GdiF8Elc zY#E*7JFg@m+fT|tEJxb(;OmF~rzcp${*coLTG=9pMlJ;mJZj2eOO?i%DtwYjl$-i{ zyeEr9{Andd4xaU`hkx-f6njdVLb!@;nP8W(W?7OLXY6Kda+CDe5t=GD9&wWlIvTW< zOsYc9+l=L@AF@W?-dwV*zcK}^UAo}H$Vtwwai>~W^Z9$;BUJ6Z_%>Wm`z1d;U6X+{ zFIdjmI_0`X^!rAL@4K>B$eVu?Q54GwP8sam4LuJvK@|0s_KJf~qPyUV5pv99*P-QA@-ee+y4mO;c)B*e@57Mr@V@ZAWv&JSr|Z3A)Sk zS{?r76i-Bua%;BVj#_$o8|*AYk4@z55IeE(>wD3q(={S`5X16;O29Q-Z)=A==@vwSgogRK5*v)cPfSi zCmCYI7qzfp@RxRTeuDy{n0!ireb?f8e(hfWGxb1`z0&U%Jm&0T>YmOH}s z1FU))qp&NgEhqBc+b9jw6;0F5JLzLA=QY2K<#Z&hlYIYdlaxVUb{+CGo)> zGR-zH=*si2^iU3~80bSp&C`uZmfZ!F^L6bD@sTj^7l8uVs^^R_-vWKLam6^a%2$Al;Xl0xpK}R!de3#vfu<`uEr$-PV5_Dqf0N!c;ZTdOoSOq=6{HO zf}ZhL)ZsL7z|%jG9;>`uo8>KYat9gZ2jS-3sFLbfDb$canv2tAxnrN7e0!o7MG$ng z5X+xJW8|wamloU!OIT;UON6t+-l<+RE08a z1)o{nn20Pop4L3T(Jf8u>tznJYlt~aw_0z0=;0e zskZ>?#Y8w;sLm5#Kim<~qK%@?^WHN6x?Qz5e7jEyV0XKlSQDLVvS7EjZ#_R(1;0K}1?2yaVOdEw>f1dKZ!ZUh}# zGo@%-@t~U#T}hgSw;XNU9Co%mPEjkcw(mX=9Yepn&H@BXQ3deiT6y*CUQ=gerTs06 zM+3iR?Xc3QN!d3GlBK$XIXPrP^kfn+S#XnxtHnQ5*U~%rUXg%9`gY+4W#|6{`v2D- z>2W{E&^w}Q4?KEW6ej|95M)=Y`)+sR|%U7vq{O$k6`Fk2cg#KDX*goN46*u9t1kck;LCoc1;u22=W6+cK1Z z%a;T+@?_|M?I@G)8522uApvtaJ%argMgHL$R{U6t^OEXxTQEreg^2g4#~XWTgQ&&; zsNu1l^dJK?)8;5v%?td8--C91EBoB;dhw5fFtmN%sXHzGO5!-WMHAqO-DFskn`^Wi zRp7_eZOI2i)W|HWLlz5o^3$5ROqcg5l#C^d~x4ELec#3W^@Z)tu94*Hj@PIAZ(j!(!dX=yzL{2kUkpM?|$wU#_xuv=06 zpXulSx2gR9{Y*|SU_O?HHh$@bWu~8{#y-a}^KEN-q%T7dY&MnjRM2bTBaeXq*{rFL ztOmxl9kZ09x0W`;8xoxWiK$5+h8*t)UTNgv$<&eR> z>&fFkP+8Y-q=`L%-*0MJT`m?8ox=yc7O=ZfKSbSukQPQ#h6Yfat2lyUstW}TtQZBtbDZ-RW|m&pZ+ajTDC z`g0iu?%925%7oMlJBLGD7L9cOCkH`4ICn*%^SCiR*nb~8IvAgMa?fvXxO=`2Gb{wGrOFb&9yM44kP3X&hB9t*zqx4HuAX(ts8=e@p9Vd}ecEvQe{Z*41I^@ct z+McCWisp_^!_&F!RO`)MwSm5BQ|Cd;Ifmxk1I3Rse+quOKlGlj!)Rw=JTm92eRDon z)e{$x>PMI!ZkfH+ydb6Yqn=!gb z5x}iMWK3SwCw@BHmv2$N%mH!0>qDB?2Mo=ZP#WbgKs;DQ>dj7qH;aRutr_Vh9s)Ar zvne+4)h_ixh4PC&*^%xVJ_uf&&M{uC_q^qHDi=CAZ0s-pGf zGtZl~>a>e6Z~u51!NFn=NLR-G2^__Jpae-$R?UyxckoPohwSMd;iBS zPq0a6aXL<&w^Z(nFXUL}TKC02V%7bsk?4K$ocPI;~JrfGF+hPVHvo&5}Rr zRJU~WMwr+5gb`r>iik#p1~EWwlv8|9W2HUlt7*yLns%x^$3w18LceYF=%D zCG;&cQaw#w77O74b8B$%_&x1!albO#tOtY)RGVi{@V1=y5>31;Y~YfnGL?ielxnx# zmTU^76c4^TpdVv8w|lWM^^(!Iv(DlGyz;sw#HwDG-g&i zR&~bo0_X-}tW2i@XDq=8f#41RXX0=|NzwVdF9#eGoa%KBp9Musj7Y8IK1`uflkkwqcSFGleR}M^ z5|^1FgjhU0g^Yp22`I_G?+M6=Gt>tk6UPj&;+n}lde5_3@l~^De3)EBoD`fR33!*T zq4iahYOjUO|F0G(gb$+}@#!ff`4>DfS4WW1HQBlS3E|mekpDHA>XGo)Q1O&_gG7h* z&^s!}ks$l`Z(9vqB|Rest4yWSF8Pjm#rR)JDHdT#rB%LwtX8%fn+2{4&8VnzmVnJ( zF8S}vw1k06jpIz1ubRCs44lMWuv~5?5E7SjmToZXm4T~f`gj`VD_o)C=@vK{k-&P* zSNEO^Q}DcPegd7iQS5xZ?S03WDW<;I!pJTf+Z7SY^!#8UWEY&!%EQYS89@UZ^zv(7 zTyGOy#(k4W?}c)cl=ww53b|SVw>z zjRb?kW~fHXbsBi0&5bEIV8xmC70EP1JKRD{)%o>VTj#ry=JaYmMfSBJTNA|we=%g& z5l+Q}$ij>6se^iElkkMzKpAv9u7nwXOtYhjb(leI1xxH^pppV5vi*)rMqn@9&e<>` zb)fjyrtT_oujJ6^*d4s0y!zGjlIucd1T@lju9+8S336v7mELv>yg7;$Kx_oLqs}x{ zGF*DgOgjlor2&McX(q8%EeiWUXRBstgvHricz4R#+_r6 zYB_|V-=46uY1r+#S-w-2Gxyn{6>nEr*=OWxwZ-pbw!a)fD0luC>~vOQnr|vE0K`lt zfAj#^cC69%ex;iUwM2l~*HL!w6i-=#&DQbJgKX(Wajk&-;`hP>b?v^xc}TqgRm1ia zvFI0tFAisON`HGDrt$+b&3=2~l&V%$C+=ws4aYkR7J?ga^coJ{j1I`OT(#Egcbr2R z_M47D*U;Ud>l-@asQZPw%=;1^8xjHy5*o0Y)Y16Xno)P%)%m_h)cXAq$f$ z>g#E31oxx)n05`tK=?0BEjIY+nattou= zchr-m{BjQ}OtbkfPo?fp?C;*{cZ?&ezxW{smIv}oU5>|cTHt?hOA%hx7CDaMNlWoo zTUp0aI9+Ajna&&9y0 zUT4Q6j+?7P-<2!U0b!tC9H%tx+86fgi;}y3`v62V%2bfCeZNhbuXES`u^Ml%AY*=D zag4Rqa6!&VyMMg?TTvXW4N0V5OoEtBT)m^BD+u}pW(be9rsF2tIpRA`eLO@yK_$J@ zn=1%==p^mJ^Z0SpH^JGsMBpwFG!g94kyJ<9EVDeb^IYC}XeWnNGK!^@@vta=)SJ~Q z;jnDaZkB{rQyiAFh0CYf5&V+Jw2sQP14JH{H8`;;8-58C1|5$G@1SqF>E}XH=O5}E zOp{Z;2U~XB%drSFroS3G-M27XR3t=y3jI9bWGdCWlHQT9A}>Z?#pH?K$(wWyfm(+`KbjShXyId>CC~tGEf~$KF z{l^H>e`{9fEFNTpO&R6&MR}n<$WiA#9*+NIrD3RAs7|RaUIdso7}u5xmTw!AJ71at zn$aoo$G8?aPUIBLngWF_t4s{s@3JUc)V4NN`FZ?g;Vfig3dhFj1t#TEon6I^~62G#l)@RBmv|7?j0mRH5# z>c!b9iscf>i{=GSMUJyowZC#-O3lWeQ?Jfh7xSre4D}NR3Vg*|Jk|RUOgVOoaLoYp zk*&jiE}Py#7_Kq=H#0%7o7bAsU&;XTaqV95K6^;jf}}p|yDlneGyK{ow_3k3 z^eWPB({rnGQ&i#!aMpOjSe{#~kZZmHM5 z8UkM$ashcWvfr�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⊃ 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%0D=$Y#NF>lkw3?V_3(Z7`K;~l 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 $qk8>r@wQR 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�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

PxG0{Qs&x~59dBqYd8!7o^(pL&fU)!LMz&Vt3 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 literal 0 HcmV?d00001 diff --git a/docs/.gitbook/assets/Verra_2 (1).png b/docs/.gitbook/assets/Verra_2 (1).png new file mode 100644 index 0000000000000000000000000000000000000000..380b9ce5c49b11fbefe5e648005fdb1f5aaa43f1 GIT binary patch literal 51067 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

PxG0{Qs&x~59dBqYd8!7o^(pL&fU)!LMz&Vt3 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 literal 0 HcmV?d00001 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 |

| +| 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