diff --git a/.github/workflows/frontend-deployment-dev.yml b/.github/workflows/frontend-deployment-dev.yml index e00c37953..aba4a77d3 100644 --- a/.github/workflows/frontend-deployment-dev.yml +++ b/.github/workflows/frontend-deployment-dev.yml @@ -11,7 +11,7 @@ jobs: deploy_front_end: runs-on: ubuntu-latest env: - REACT_APP_BACKEND: https://ck5kt5uaw1.execute-api.us-east-1.amazonaws.com/dev + REACT_APP_BACKEND: https://14p5hndhcf.execute-api.us-east-1.amazonaws.com/dev COUNTRY_NAME: 'CountryX' COUNTRY_FLAG_URL: 'https://carbon-common-dev.s3.amazonaws.com/flag.png' COUNTRY_CODE: 'NG' @@ -54,10 +54,40 @@ jobs: env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: carbon-web - IMAGE_TAG: latest + IMAGE_TAG: v1 + run: | + # Build a docker container and push it to ECR + docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f web/Dockerfile . --build-arg PORT=3030 --build-arg REACT_APP_BACKEND=https://test.carbreg.org:3000 --build-arg REACT_APP_STAT_URL=https://test.carbreg.org:3100 --build-arg COUNTRY_NAME="CountryX" --build-arg COUNTRY_FLAG_URL="https://carbon-common-dev.s3.amazonaws.com/flag.png" --build-arg COUNTRY_CODE="NG" --build-arg REACT_APP_MAP_TYPE="Mapbox" --build-arg REACT_APP_MAPBOXGL_ACCESS_TOKEN=${{ secrets.MAPBOXGL_ACCESS_TOKEN }} --build-arg NGINX_CONFIG="nginx_prod.conf" + echo "Pushing image to ECR..." + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" + - name: Build, tag, and push the QA-develop image to Amazon ECR + id: build-image-develop + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: carbon-web + IMAGE_TAG: develop run: | # Build a docker container and push it to ECR docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f web/Dockerfile . --build-arg PORT=3030 --build-arg REACT_APP_BACKEND=http://localhost:3000 --build-arg REACT_APP_STAT_URL=http://localhost:3100 --build-arg COUNTRY_NAME="CountryX" --build-arg COUNTRY_FLAG_URL="https://carbon-common-dev.s3.amazonaws.com/flag.png" --build-arg COUNTRY_CODE="NG" --build-arg REACT_APP_MAP_TYPE="Mapbox" --build-arg REACT_APP_MAPBOXGL_ACCESS_TOKEN=${{ secrets.MAPBOXGL_ACCESS_TOKEN }} echo "Pushing image to ECR..." docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" + - name: Deploy docker image to Amazon EC2 + if: github.ref == 'refs/heads/develop' + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: carbon-web + IMAGE_TAG: v1 + PRIVATE_KEY: ${{ secrets.AWS_SSH_KEY_PRIVATE }} + HOSTNAME: ${{secrets.HOST_IP}} + USER_NAME: ec2-user + run: | + echo "$PRIVATE_KEY" > private_key && chmod 600 private_key + ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} ' + cd repos/carbon-registry && + sudo $(aws ecr get-login --no-include-email --region us-east-1) && + sudo docker stop carbon-registry-web-1 || true && + sudo docker rm carbon-registry-web-1 && + sudo docker pull 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-web:v1 && + docker compose -f docker-compose-image.yml up -d web ' diff --git a/.github/workflows/server-deployments.yml b/.github/workflows/server-deployments.yml index 65faccff7..ddd49a085 100644 --- a/.github/workflows/server-deployments.yml +++ b/.github/workflows/server-deployments.yml @@ -6,7 +6,8 @@ on: - main paths: - backend/** - - libs/** + # - libs/** + - .github/workflows/server* env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} @@ -53,18 +54,18 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - name: Build Serial Generator Package - if: ${{ needs.check_dependency_change.outputs.deps_changed == 'True' }} - working-directory: ./libs/serial-number-gen - run: yarn run build - - name: Build Carbon Credit Package - if: ${{ needs.check_dependency_change.outputs.deps_changed == 'True' }} - working-directory: ./libs/carbon-credit-calculator - run: yarn run build + # - name: Build Serial Generator Package + # if: ${{ needs.check_dependency_change.outputs.deps_changed == 'True' }} + # working-directory: ./libs/serial-number-gen + # run: yarn run build + # - name: Build Carbon Credit Package + # if: ${{ needs.check_dependency_change.outputs.deps_changed == 'True' }} + # working-directory: ./libs/carbon-credit-calculator + # run: yarn run build - name: Copy package.json if: ${{ needs.check_dependency_change.outputs.deps_changed == 'True' }} working-directory: ./backend/layer/dependency_layer - run: cp ../../services/package.json ./ && cp ../../services/yarn.lock ./ && cp -r ../../../libs ../../ + run: cp ../../services/package.json ./ && cp ../../services/yarn.lock ./ - name: Install Dependency if: ${{ needs.check_dependency_change.outputs.deps_changed == 'True' }} working-directory: ./backend/layer/dependency_layer @@ -105,12 +106,12 @@ jobs: echo "ARN1=$(aws lambda list-layer-versions --layer-name service-dependencies-${{ needs.check_dependency_change.outputs.stage }}-1 --region us-east-1 --query 'LayerVersions[0].LayerVersionArn')" >> $GITHUB_OUTPUT echo "ARN2=$(aws lambda list-layer-versions --layer-name service-dependencies-${{ needs.check_dependency_change.outputs.stage }}-2 --region us-east-1 --query 'LayerVersions[0].LayerVersionArn')" >> $GITHUB_OUTPUT id: layerArn - - name: Build Serial Generator Package - working-directory: ./libs/serial-number-gen - run: yarn run build - - name: Build Carbon Credit Package - working-directory: ./libs/carbon-credit-calculator - run: yarn run build + # - name: Build Serial Generator Package + # working-directory: ./libs/serial-number-gen + # run: yarn run build + # - name: Build Carbon Credit Package + # working-directory: ./libs/carbon-credit-calculator + # run: yarn run build - name: serverless deploy develop if: github.ref == 'refs/heads/develop' uses: serverless/github-action@v3.1 @@ -140,13 +141,31 @@ jobs: env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} ECR_REPOSITORY: carbon-services - IMAGE_TAG: latest + IMAGE_TAG: develop run: | # Build a docker container and push it to ECR docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f backend/services/Dockerfile . echo "Pushing image to ECR..." docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" + - name: Deploy docker image to Amazon EC2 + if: github.ref == 'refs/heads/develop' + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: carbon-services + IMAGE_TAG: develop + PRIVATE_KEY: ${{ secrets.AWS_SSH_KEY_PRIVATE }} + HOSTNAME: ${{secrets.HOST_IP}} + USER_NAME: ec2-user + run: | + echo "$PRIVATE_KEY" > private_key && chmod 600 private_key + ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} ' + cd repos/carbon-registry && + sudo $(aws ecr get-login --no-include-email --region us-east-1) && + sudo docker stop carbon-registry-national-1 carbon-registry-replicator-1 carbon-registry-stats-1 || true && + sudo docker rm carbon-registry-national-1 carbon-registry-replicator-1 carbon-registry-stats-1 && + sudo docker pull 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-services:develop && + docker compose -f docker-compose-image.yml up -d national stats replicator ' # automated-api-tests: # runs-on: ubuntu-latest @@ -186,4 +205,4 @@ jobs: - \ No newline at end of file + diff --git a/.github/workflows/service-lib-update.yml b/.github/workflows/service-lib-update.yml new file mode 100644 index 000000000..ec03228be --- /dev/null +++ b/.github/workflows/service-lib-update.yml @@ -0,0 +1,33 @@ +name: Service Library Version Update +on: + workflow_dispatch + +jobs: + update_service_lib: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + token: ${{ secrets.PAT_TOKEN }} + - name: Cache modules + uses: actions/cache@v1 + id: yarn-cache + with: + path: node_modules + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: ${{ runner.os }}-yarn- + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Update Version + working-directory: ./backend/services + run: yarn upgrade carbon-services-lib --latest + - name: Commit Changes + working-directory: ./backend/services + run: | + git config --global user.name "System Generated" + git config --global user.email "palinda@xeptagon.com" + git add package.json yarn.lock + git commit -m "Update Service Lib Version" + git push origin HEAD diff --git a/.github/workflows/test-service-build.yml b/.github/workflows/test-service-build.yml new file mode 100644 index 000000000..9afe73f71 --- /dev/null +++ b/.github/workflows/test-service-build.yml @@ -0,0 +1,91 @@ +name: Test Services +on: + workflow_dispatch: + push: + branches: + - '**' # matches every branch + - '!develop' + - '!main' # excludes master + paths: + - web/** + - backend/** + - web/** + # - libs/** + - .github/workflows/test-service* + +env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: us-east-1 + +jobs: + deploy: + name: test deploy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + - name: Build, tag, and push the image to Amazon ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: carbon-services + IMAGE_TAG: ${{ github.head_ref || github.ref_name }} + run: | + # Build a docker container and push it to ECR + docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f backend/services/Dockerfile . + echo "Pushing image to ECR..." + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" + + # automated-api-tests: + # runs-on: ubuntu-latest + # needs: [deploy] + # steps: + # - uses: actions/checkout@v3 + # - name: Install Postman CLI + # run: | + # curl -o- "https://dl-cli.pstmn.io/install/linux64.sh" | sh + # - name: Login to Postman CLI + # run: postman login --with-api-key ${{ secrets.POSTMAN_API_KEY }} + # - name: Run User Create Tests + # if: always() + # run: | + # postman collection run "20428472-45dd524a-c260-44f4-b9c9-5f164db2264d" -e "20428472-778eb1c8-aac1-4484-a217-bcfd9a8d0df0" -d ./testing/api/user_onboarding_company4.csv + # - name: Run User Password Reset Tests + # if: always() + # run: | + # postman collection run "24647866-ba48ade2-732f-40c5-a304-509b44389ff6" -e "20428472-778eb1c8-aac1-4484-a217-bcfd9a8d0df0" -d ./testing/api/reset_password_3.csv + # - name: Run User View Tests + # if: always() + # run: | + # postman collection run "20428472-a9ecb4af-70a2-4997-a478-e554138ec3ea" -e "20428472-778eb1c8-aac1-4484-a217-bcfd9a8d0df0" -d ./testing/api/view_user_company4.csv + # - name: Run Programme Create Tests + # if: always() + # run: | + # postman collection run "24716950-471a5534-87f8-482d-93e2-6613e15d55e0" -e "20428472-778eb1c8-aac1-4484-a217-bcfd9a8d0df0" -d ./testing/api/create_project_7.csv + # - name: Run Programme Authorisation and Credit Transfer Tests + # if: always() + # run: | + # postman collection run "20428472-140d1d13-d387-4952-b956-a1a5ff7b01af" -e "20428472-778eb1c8-aac1-4484-a217-bcfd9a8d0df0" -d ./testing/api/credit_transfer_1.csv + # - name: Run Programme Certification and Certification Revocation Tests + # if: always() + # run: | + # postman collection run "20428472-d4e57d08-53ad-42a5-ba0e-3e85f449a1ed" -e "20428472-778eb1c8-aac1-4484-a217-bcfd9a8d0df0" -d ./testing/api/credit_transfer_certify_1.csv + + + + + diff --git a/.github/workflows/test-web-build.yml b/.github/workflows/test-web-build.yml new file mode 100644 index 000000000..0523be606 --- /dev/null +++ b/.github/workflows/test-web-build.yml @@ -0,0 +1,50 @@ +name: Test Web Build +on: + workflow_dispatch: + push: + branches: + - '**' # matches every branch + - '!develop' + - '!main' # excludes master + paths: + - web/** + - backend/** + - .github/workflows/test-web* + +jobs: + Test_web_build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Cache modules + uses: actions/cache@v1 + id: yarn-cache + with: + path: node_modules + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: ${{ runner.os }}-yarn- + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + - name: Build, tag, and push the image to Amazon ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: carbon-web + IMAGE_TAG: ${{ github.head_ref || github.ref_name }} + run: | + # Build a docker container and push it to ECR + docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f web/Dockerfile . --build-arg PORT=3030 --build-arg REACT_APP_BACKEND=http://localhost:3000 --build-arg REACT_APP_STAT_URL=http://localhost:3100 --build-arg COUNTRY_NAME="CountryX" --build-arg COUNTRY_FLAG_URL="https://carbon-common-dev.s3.amazonaws.com/flag.png" --build-arg COUNTRY_CODE="NG" --build-arg REACT_APP_MAP_TYPE="Mapbox" --build-arg REACT_APP_MAPBOXGL_ACCESS_TOKEN=${{ secrets.MAPBOXGL_ACCESS_TOKEN }} + echo "Pushing image to ECR..." + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" diff --git a/.github/workflows/web-lib-update.yml b/.github/workflows/web-lib-update.yml new file mode 100644 index 000000000..67fc08082 --- /dev/null +++ b/.github/workflows/web-lib-update.yml @@ -0,0 +1,33 @@ +name: Web Library Version Update +on: + workflow_dispatch + +jobs: + update_fe_lib: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + token: ${{ secrets.PAT_TOKEN }} + - name: Cache modules + uses: actions/cache@v1 + id: yarn-cache + with: + path: node_modules + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: ${{ runner.os }}-yarn- + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Update Version + working-directory: ./web + run: yarn upgrade @undp/carbon-library --latest + - name: Commit Changes + working-directory: ./web + run: | + git config --global user.name "System Generated" + git config --global user.email "palinda@xeptagon.com" + git add package.json yarn.lock + git commit -m "Update Web Lib Version" + git push origin HEAD diff --git a/.gitignore b/.gitignore index a30b3ca48..8b00252a1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ backend/services/.env.local **/coverage .env.local ./data/* -!./data/README.md \ No newline at end of file +!./data/README.md +.yalc +yalc.lock \ No newline at end of file diff --git a/backend/layer/serverless.yml b/backend/layer/serverless.yml index ec230c90d..2324cb1b7 100644 --- a/backend/layer/serverless.yml +++ b/backend/layer/serverless.yml @@ -35,4 +35,5 @@ layers: - 'node_modules/@*/**' - 'node_modules/a*/**' - 'node_modules/b*/**' - - 'node_modules/c*/**' \ No newline at end of file + - 'node_modules/c*/**' + - 'node_modules/typescript/**' \ No newline at end of file diff --git a/backend/services/.env.dev b/backend/services/.env.dev index 57f80e468..d0cb75de9 100644 --- a/backend/services/.env.dev +++ b/backend/services/.env.dev @@ -14,8 +14,9 @@ ASYNC_OPERATIONS_TYPE=Queue DISABLE_LOW_PRIORITY_EMAIL=false ASYNC_QUEUE_NAME=https://sqs.us-east-1.amazonaws.com/302213478610/AsyncQueuedev.fifo DOMAIN_MAP=false -EXPIRES_IN=7200 -REGISTRY_SYNC_ENABLE=true -MRV_ENDPOINT=https://u4h9swxm8b.execute-api.us-east-1.amazonaws.com/dev +EXPIRES_IN=3600 +SYNC_ENDPOINT=https://u4h9swxm8b.execute-api.us-east-1.amazonaws.com/dev SMTP_ENDPOINT=vpce-02cef9e74f152b675-b00ybiai.email-smtp.us-east-1.vpce.amazonaws.com -SMTP_USERNAME=AKIAUMXKTXDJLKSXTF3U \ No newline at end of file +SMTP_USERNAME=AKIAUMXKTXDJLKSXTF3U +SYSTEM_TYPE=CARBON_REGISTRY_SYSTEM +SYNC_ENABLE=true diff --git a/backend/services/Dockerfile b/backend/services/Dockerfile index b72d1dd69..f0bccc254 100644 --- a/backend/services/Dockerfile +++ b/backend/services/Dockerfile @@ -7,7 +7,7 @@ WORKDIR /app/backend/services COPY ./backend/services/package.json ./ COPY ./backend/services/yarn.lock ./ -COPY ./libs ../../libs +# COPY ./libs ../../libs # Install app dependencies RUN yarn run sls:installProd diff --git a/backend/services/fonts/Inter-Bold.ttf b/backend/services/fonts/Inter-Bold.ttf new file mode 100644 index 000000000..8e82c70d1 Binary files /dev/null and b/backend/services/fonts/Inter-Bold.ttf differ diff --git a/backend/services/fonts/Inter-Regular.ttf b/backend/services/fonts/Inter-Regular.ttf new file mode 100644 index 000000000..8d4eebf20 Binary files /dev/null and b/backend/services/fonts/Inter-Regular.ttf differ diff --git a/backend/services/package.json b/backend/services/package.json index 7b62cb37e..3bc551f20 100644 --- a/backend/services/package.json +++ b/backend/services/package.json @@ -1,6 +1,6 @@ { "name": "carbon-registry-services", - "version": "0.5.5", + "version": "0.5.6", "description": "Carbon Registry Framework", "author": "Xeptagon PVT LTD", "private": true, @@ -8,9 +8,8 @@ "scripts": { "prebuild": "rimraf dist", "build": "nest build", - "build:libs": "cd ../../libs/serial-number-gen/ && yarn install && yarn run build && cd ../../libs/carbon-credit-calculator && yarn install && yarn run devBuild && cd ../../backend/services", - "sls:install": "yarn run build:libs && cd ../../backend/services && yarn install --frozen-lockfile", - "sls:installProd": "yarn run build:libs && cd ../../backend/services && yarn install --production --frozen-lockfile", + "sls:install": "yarn install --frozen-lockfile", + "sls:installProd": "yarn install --production --frozen-lockfile", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", @@ -24,8 +23,8 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { - "@aws-sdk/client-qldb": "^3.209.0", - "@aws-sdk/client-qldb-session": "^3.204.0", + "@aws-sdk/client-qldb": "^3.408.0", + "@aws-sdk/client-qldb-session": "^3.408.0", "@casl/ability": "^6.3.2", "@drdgvhbh/postgres-error-codes": "^0.0.6", "@nestjs/common": "^9.0.0", @@ -36,13 +35,14 @@ "@nestjs/platform-express": "^9.0.0", "@nestjs/swagger": "^6.1.3", "@nestjs/typeorm": "^9.0.1", - "@undp/carbon-credit-calculator": "../../libs/carbon-credit-calculator", - "@undp/serial-number-gen": "../../libs/serial-number-gen", + "@undp/carbon-credit-calculator": "^1.0.0", + "@undp/serial-number-gen": "^1.0.0", "amazon-qldb-driver-nodejs": "^3.0.1", "aws-kinesis-agg": "^4.2.6", "aws-lambda": "^1.0.7", "aws-serverless-express": "^3.4.0", "axios": "^1.2.4", + "carbon-services-lib": "0.0.237", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "dotenv-flow": "^3.2.0", @@ -57,6 +57,7 @@ "passport-headerapikey": "^1.2.2", "passport-jwt": "^4.0.0", "passport-local": "^1.0.0", + "pdfkit": "^0.13.0", "pg": "^8.8.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", diff --git a/backend/services/serverless.yml b/backend/services/serverless.yml index 3f20f0b8a..f71287120 100644 --- a/backend/services/serverless.yml +++ b/backend/services/serverless.yml @@ -24,6 +24,7 @@ package: - "countries.json" - "regions.csv" - "src/i18n/**" + - "fonts/*" plugins: - "serverless-plugin-typescript" @@ -129,7 +130,7 @@ functions: ssmToEnvironment: - SMTP_PASSWORD - DB_PASSWORD - - MRV_API_TOKEN + - SYNC_API_TOKEN environment: NODE_PATH: "./:/opt/node_modules" layers: @@ -148,17 +149,17 @@ functions: - ${param:depLayerArn1} - ${param:depLayerArn2} - default: - handler: src/shared/handler.handler - events: - - http: - method: any - path: /{any+} - environment: - NODE_PATH: "./:/opt/node_modules" - layers: - - ${param:depLayerArn1} - - ${param:depLayerArn2} + # default: + # handler: src/shared/handler.handler + # events: + # - http: + # method: any + # path: /{any+} + # environment: + # NODE_PATH: "./:/opt/node_modules" + # layers: + # - ${param:depLayerArn1} + # - ${param:depLayerArn2} custom: optimize: external: ["swagger-ui-dist"] @@ -171,7 +172,7 @@ custom: ITMO_API_KEY: /${self:provider.stage}/ITMO_API_KEY~true ITMO_EMAIL: /${self:provider.stage}/ITMO_EMAIL~true ITMO_PASSWORD: /${self:provider.stage}/ITMO_PASSWORD~true - MRV_API_TOKEN: /${self:provider.stage}/MRV_API_TOKEN~true + SYNC_API_TOKEN: /MRV/${self:provider.stage}/SYNC_API_TOKEN~true # sesTemplates: # addStage: true # Specifies whether to add stage to template name (default false) # configFile: './src/shared/email/email.template.ts' # Config file path (default './ses-email-templates/index.js') diff --git a/backend/services/src/analytics-api/aggregate.api.service.ts b/backend/services/src/analytics-api/aggregate.api.service.ts deleted file mode 100644 index 2413fdd76..000000000 --- a/backend/services/src/analytics-api/aggregate.api.service.ts +++ /dev/null @@ -1,1641 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { InjectRepository } from "@nestjs/typeorm"; -import { DataCountResponseDto } from "../shared/dto/data.count.response"; -import { Programme } from "../shared/entities/programme.entity"; -import { Repository } from "typeorm"; -import { StatList } from "../shared/dto/stat.list.dto"; -import { StatType } from "../shared/enum/stat.type.enum"; -import { HelperService } from "../shared/util/helpers.service"; -import { ProgrammeTransferViewEntityQuery } from "../shared/entities/programmeTransfer.view.entity"; -import { QueryDto } from "../shared/dto/query.dto"; -import { FilterEntry } from "../shared/dto/filter.entry"; -import { SortEntry } from "../shared/dto/sort.entry"; -import { AggrEntry } from "../shared/dto/aggr.entry"; -import { Company } from "../shared/entities/company.entity"; -import { StatFilter } from "../shared/dto/stat.filter"; -import { ProgrammeStage } from "../shared/enum/programme-status.enum"; -import { Stat } from "../shared/dto/stat.dto"; -import { Sector } from "../shared/enum/sector.enum"; -import { - StatusGroupedByTimedata, - StatusGroupedByTimedataThere, -} from "../shared/dto/programmeStatus.timeGrouped.result"; -import { TransferStatus } from "../shared/enum/transform.status.enum"; -import { CompanyRole } from "../shared/enum/company.role.enum"; -import { PRECISION } from "@undp/carbon-credit-calculator/dist/esm/calculator"; - -@Injectable() -export class AggregateAPIService { - private timeDropFields = [ - "certifierId", - "companyId", - "revokedCertifierId", - "toCompanyId", - "fromCompanyId", - "programmeCertifierId", - "initiatorCompanyId", - "isRetirement", - "createdTime" - ] - - constructor( - private configService: ConfigService, - private helperService: HelperService, - @InjectRepository(Programme) private programmeRepo: Repository, - @InjectRepository(Company) private companyRepo: Repository, - @InjectRepository(ProgrammeTransferViewEntityQuery) - private programmeTransferRepo: Repository - ) {} - - private getFilterAndByStatFilter( - statFilter: StatFilter, - mineFilter: FilterEntry, - timeField: string - ) { - const filters: FilterEntry[] = []; - if (statFilter) { - if (statFilter.startTime) { - filters.push({ - key: timeField, - operation: ">=", - value: statFilter.startTime, - }); - } - if (statFilter.endTime) { - filters.push({ - key: timeField, - operation: "<=", - value: statFilter.endTime, - }); - } - if (statFilter.onlyMine == true && mineFilter) { - filters.push(mineFilter); - } - - return filters; - } else { - return null; - } - } - - private async getLastTime( - repo: Repository, - tableName: string, - whereC: string, - timeCol: string - ) { - console.log("getLastTime", whereC); - const resp = await repo - .createQueryBuilder(tableName) - .select(`"${timeCol}"`) - .where(whereC) - .orderBy(`"${timeCol}"`, "DESC", "NULLS LAST") - .limit(1) - .getRawOne(); - - console.log("Resp", resp); - if (resp) { - return resp[timeCol]; - } - return 0; - } - - private firstLower(lower) { - return (lower && lower[0].toLowerCase() + lower.slice(1)) || lower; - } - - private async getTimeGroupedDataStatusConverted(data) { - const passedResult = data; - let result: StatusGroupedByTimedata = { - awaitingAuthorization: [], - authorised: [], - rejected: [], - authorisedCredits: [], - issuedCredits: [], - transferredCredits: [], - retiredCredits: [], - frozenCredits: [], - }; - const groupedDataFiltered = passedResult?.filter( - (item) => String(item.time_group) !== "0" - ); - const groupedDatasObject = groupedDataFiltered.reduce((acc, curr) => { - const time_group = curr.time_group; - if (!acc[time_group]) { - acc[time_group] = []; - } - acc[time_group].push(curr); - return acc; - }, {}); - const timeLabel = Object.getOwnPropertyNames(groupedDatasObject); - timeLabel?.map((timeLabelItem) => { - const arrResultForTimeGroup = groupedDatasObject[timeLabelItem]; - let authorisedCreditsSum = 0; - let issuedCreditsSum = 0; - let transferredCreditsSum = 0; - let retiredCreditsSum = 0; - let frozenCreditsSum = 0; - let resultThere: StatusGroupedByTimedataThere = { - awaitingAuthorization: false, - authorised: false, - rejected: false, - }; - const statusArray = Object.values(ProgrammeStage); - arrResultForTimeGroup?.map((timeGroupItem) => { - console.log("status array ----- > ", statusArray); - if (timeGroupItem?.currentStage === ProgrammeStage.AUTHORISED) { - authorisedCreditsSum = - authorisedCreditsSum + - (parseFloat(timeGroupItem?.totalestcredit) - - parseFloat(timeGroupItem?.totalissuedcredit)); - } else { - authorisedCreditsSum = authorisedCreditsSum + 0; - } - issuedCreditsSum = - issuedCreditsSum + - parseFloat(timeGroupItem?.totalissuedcredit) - - parseFloat(timeGroupItem?.totalretiredcredit) - - parseFloat(timeGroupItem?.totaltxcredit) - - parseFloat(timeGroupItem?.totalfreezecredit); - transferredCreditsSum = - transferredCreditsSum + parseFloat(timeGroupItem?.totaltxcredit); - retiredCreditsSum = - retiredCreditsSum + parseFloat(timeGroupItem?.totalretiredcredit); - frozenCreditsSum = - frozenCreditsSum + parseFloat(timeGroupItem?.totalfreezecredit); - statusArray?.map((status) => { - if (timeGroupItem?.currentStage === status) { - resultThere[this.firstLower(timeGroupItem?.currentStage)] = true; - result[this.firstLower(timeGroupItem?.currentStage)]?.push( - parseInt(timeGroupItem?.count) - ); - } - }); - }); - statusArray?.map((status) => { - if (resultThere[this.firstLower(status)] === false) { - result[this.firstLower(status)]?.push(0); - } - }); - result["authorisedCredits"]?.push(authorisedCreditsSum); - result["issuedCredits"]?.push(issuedCreditsSum); - result["transferredCredits"]?.push(transferredCreditsSum); - result["retiredCredits"]?.push(retiredCreditsSum); - result["frozenCredits"]?.push(frozenCreditsSum); - }); - - const resultS = { - timeLabel, - ...result, - }; - return resultS; - } - - private async getTimeGroupedDataSectorConverted(data) { - const passedResult = data; - const groupedDataFiltered = passedResult?.filter( - (item) => String(item.time_group) !== "0" - ); - const groupedDatasObject = groupedDataFiltered.reduce((acc, curr) => { - const time_group = curr.time_group; - if (!acc[time_group]) { - acc[time_group] = []; - } - acc[time_group].push(curr); - return acc; - }, {}); - let result: any = {}; - const sectorsArray = Object.values(Sector); - sectorsArray?.map((sector) => { - result[this.firstLower(sector)] = []; - }); - const timeLabel = Object.getOwnPropertyNames(groupedDatasObject); - for (let timeIndex = 0; timeIndex < timeLabel.length; timeIndex++) { - const arrResultForTimeGroup = groupedDatasObject[timeLabel[timeIndex]]; - let resultThere: any = {}; - const sectorsArray = Object.values(Sector); - sectorsArray?.map((sector) => { - resultThere[this.firstLower(sector)] = false; - }); - for ( - let arrResultForTimeGroupIndex = 0; - arrResultForTimeGroupIndex < arrResultForTimeGroup.length; - arrResultForTimeGroupIndex++ - ) { - sectorsArray?.map((sector) => { - if ( - arrResultForTimeGroup[arrResultForTimeGroupIndex]?.sector === sector - ) { - resultThere[ - arrResultForTimeGroup[ - arrResultForTimeGroupIndex - ]?.sector?.toLowerCase() - ] = true; - result[ - arrResultForTimeGroup[ - arrResultForTimeGroupIndex - ]?.sector?.toLowerCase() - ]?.push( - parseInt(arrResultForTimeGroup[arrResultForTimeGroupIndex]?.count) - ); - } - }); - } - sectorsArray?.map((sector) => { - if (resultThere[sector?.toLocaleLowerCase()] === false) { - result[sector?.toLocaleLowerCase()]?.push(0); - } - }); - } - - const resultS = { - timeLabel, - ...result, - }; - - return resultS; - } - - private async programmeLocationDataFormatter(data) { - const locationData = [...data]; - let locationsGeoData: any = {}; - let features: any[] = []; - locationsGeoData.type = "FeatureCollection"; - locationData?.map((locationDataItem, index) => { - if (locationDataItem?.loc && locationDataItem !== null) { - let programmeGeoData: any = {}; - let location: any = locationDataItem?.loc; - programmeGeoData.type = "Feature"; - let properties: any = {}; - let geometry: any = {}; - properties.id = String(index); - properties.count = parseInt(locationDataItem?.count); - properties.stage = locationDataItem?.stage; - geometry.type = "Point"; - geometry.coordinates = location; - programmeGeoData.properties = properties; - programmeGeoData.geometry = geometry; - features.push(programmeGeoData); - } - }); - - locationsGeoData.features = [...features]; - return locationsGeoData; - } - - private async genAggregateTypeOrmQuery( - repo: Repository, - tableName: string, - groupBy: string[], - aggregates: AggrEntry[], - filterAnd: FilterEntry[], - filterOr: FilterEntry[], - sort: SortEntry, - abilityCondition: string, - lastTimeForWhere: any, - statCache: any, - timeCol: string[], - timeGroupingCol?: string, - timeGroupingAccuracy?: string, - keepTimeFields?: string[] - ) { - const query = new QueryDto(); - query.filterAnd = filterAnd; - query.filterOr = filterOr; - query.sort = sort; - - const timeFields = [ - ...timeCol - ]; - - for (const t of this.timeDropFields) { - if (keepTimeFields && keepTimeFields.indexOf(t) >= 0) { - continue; - } - timeFields.push(t) - } - - console.log('Time fields', timeFields) - - const whereC = this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQLWithTable( - tableName, - abilityCondition - ) - ); - - const timeWhere = this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQLWithTable( - tableName, - abilityCondition - ), - undefined, - timeFields - ); - - let queryBuild = repo.createQueryBuilder(tableName).where(whereC); - - if (aggregates) { - const selectQuery = aggregates - .map((a) => { - const fieldCol = `${ - a.outerQuery ? "(" + a.outerQuery + "(" : "" - }"${tableName}"."${a.key}"${a.outerQuery ? ")s )" : ""}`; - - let mineCompField = fieldCol; - if (a.mineCompanyId) { - mineCompField = [ - "creditTransferred", - "creditRetired", - "creditFrozen", - ].includes(a.key) - ? `"${tableName}"."${a.key}"[array_position("${tableName}"."companyId", ${a.mineCompanyId})]` - : `"${tableName}"."${ - a.key === "creditBalance" - ? "creditOwnerPercentage" - : "proponentPercentage" - }"[array_position("${tableName}"."companyId", ${ - a.mineCompanyId - })]*${fieldCol}/100`; - } - return `${a.operation}(${mineCompField}) as ${a.fieldName}`; - }) - .join(","); - queryBuild = queryBuild.select(selectQuery); - } - - if (sort) { - queryBuild = queryBuild.orderBy( - sort?.key && `"${sort?.key}"`, - sort?.order, - "NULLS LAST" - ); - } - - let grpByAll = undefined; - if (groupBy) { - const groupQuery = groupBy - .map((gb) => { - let val; - if (gb.includes("->>")) { - const parts = gb.split("->>"); - val = `"${parts[0]}"->>'${parts[1]}'`; - } else { - val = `"${gb}"`; - } - return `"${tableName}".${val}`; - }) - .join(","); - const groupSelectQuery = groupBy - .map((gb) => { - let val; - if (gb.includes("->>")) { - const parts = gb.split("->>"); - val = `"${parts[0]}"->>'${parts[1]}' as ${parts[1]}`; - } else { - val = `"${gb}"`; - } - return `"${tableName}".${val}`; - }) - .join(","); - queryBuild = queryBuild.addSelect(groupSelectQuery); - grpByAll = groupQuery; - } - if (timeGroupingCol && timeGroupingAccuracy) { - const groupQuery = `date_trunc('${timeGroupingAccuracy}', "${timeGroupingCol}") as time_group`; - queryBuild = queryBuild.addSelect(groupQuery); - if (!grpByAll) { - grpByAll = "time_group"; - } else { - grpByAll += ", time_group"; - } - } - if (grpByAll != "") { - queryBuild = queryBuild.groupBy(grpByAll); - } - - const key = - (grpByAll ? grpByAll : "") + " " + whereC + " from " + tableName + ' ' + timeWhere; - console.log('Stat cache key', key) - if (statCache[key]) { - return statCache[key]; - } - let d = await queryBuild.getRawMany(); - let dTimeGrouped; - - let lastTime: any; - if (timeCol) { - const allTimes = {}; - let maxTime = 0; - let colTime; - for (const tc of timeCol) { - const cacheKey = timeWhere + " " + tc + " from " + tableName; - console.log("Cache key", cacheKey); - if (lastTimeForWhere[cacheKey]) { - console.log("Last time hit from the cache"); - colTime = lastTimeForWhere[cacheKey]; - } else { - colTime = await this.getLastTime(repo, tableName, timeWhere, tc); - lastTimeForWhere[cacheKey] = colTime; - } - allTimes[tc] = colTime; - if (colTime > maxTime) { - maxTime = colTime; - } - lastTime = { - max: maxTime, - all: allTimes, - }; - } - } - for (const row of d) { - for (const k in row) { - if (row[k] === null) { - row[k] = 0; - } else if (row[k] !== undefined && !isNaN(row[k]) && row[k] % 1 !== 0) { - row[k] = parseFloat(Number(row[k]).toFixed(PRECISION)); - } - } - } - if (timeGroupingCol && timeGroupingAccuracy && groupBy) { - console.log("coming into this condition ---- groupBy[0]", groupBy[0]); - if (groupBy[0] === "currentStage") { - dTimeGrouped = await this.getTimeGroupedDataStatusConverted(d); - } else if (groupBy[0] === "sector") { - dTimeGrouped = await this.getTimeGroupedDataSectorConverted(d); - } - } else if (timeGroupingCol && timeGroupingAccuracy) { - console.log("coming into this condition ---- !groupBy[0]"); - const map = {}; - for (const en of d) { - if (!map[en.time_group]) { - map[en.time_group] = []; - } - map[en.time_group].push(en); - } - dTimeGrouped = map; - } - statCache[key] = { - data: timeGroupingCol && timeGroupingAccuracy ? dTimeGrouped : d, - last: lastTime.max, - }; - - if (lastTime.all && Object.keys(lastTime.all).length > 0) { - statCache[key]["all"] = lastTime.all; - } - - return statCache[key]; - } - - private async getAllAuthProgramme( - stat, - abilityCondition, - lastTimeForWhere, - statCache, - timeGroup: boolean, - companyId? - ) { - let filtAuth = this.getFilterAndByStatFilter( - stat.statFilter, - companyId - ? { - value: companyId, - key: "companyId", - operation: "ANY", - } - : undefined, - "createdTime" - ); - - if (!filtAuth) { - filtAuth = []; - } - filtAuth.push({ - value: ProgrammeStage.AUTHORISED, - key: "currentStage", - operation: "=", - }); - - return await this.genAggregateTypeOrmQuery( - this.programmeRepo, - "programme", - null, - [ - new AggrEntry("programmeId", "COUNT", "count"), - { - key: "creditEst", - operation: "SUM", - fieldName: "sum", - mineCompanyId: - stat?.statFilter?.onlyMine && companyId ? companyId : undefined, - }, - ], - filtAuth, - null, - timeGroup ? { key: "time_group", order: "ASC" } : null, - abilityCondition, - lastTimeForWhere, - statCache, - ["statusUpdateTime", "authTime"], - timeGroup ? "createdAt" : undefined, - timeGroup ? "day" : undefined - ); - } - - private async getCertifiedByMePrgrammes( - statFilter, - companyId, - certifyField, - abilityCondition, - lastTimeForWhere, - statCache, - companyRole, - timeGroup?: boolean - ) { - let filtC = this.getFilterAndByStatFilter( - statFilter, - { - value: companyId, - key: certifyField, - operation: "ANY", - }, - "createdTime" - ); - - if (!filtC) { - filtC = []; - } - filtC.push({ - value: ProgrammeStage.AUTHORISED, - key: "currentStage", - operation: "=", - }); - - return await this.genAggregateTypeOrmQuery( - this.programmeRepo, - "programme", - null, - [ - new AggrEntry("programmeId", "COUNT", "count"), - new AggrEntry("creditEst", "SUM", "sum"), - { - key: "creditEst", - operation: "SUM", - fieldName: "sum", - mineCompanyId: - statFilter?.onlyMine && - companyId && - companyRole === CompanyRole.PROGRAMME_DEVELOPER - ? companyId - : undefined, - }, - ], - filtC, - null, - null, - abilityCondition, - lastTimeForWhere, - statCache, - ["certifiedTime"], - timeGroup ? "createdAt" : undefined, - timeGroup ? "day" : undefined - ); - } - - private async getCertifiedProgrammes( - statFilter, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - cardinalityFilters: FilterEntry[], - frzAgg, - companyField: string, - companyRole: CompanyRole, - timeGroup?: boolean - ) { - let filters = this.getFilterAndByStatFilter( - statFilter, - null, - "createdTime" - ); - if (!filters) { - filters = []; - } - for (const fl of cardinalityFilters) { - filters.push({ - key: fl.key, - operation: fl.operation, - value: fl.value, - keyOperation: "cardinality", - }); - } - - filters.push({ - value: ProgrammeStage.AUTHORISED, - key: "currentStage", - operation: "=", - }); - - let filterOr = undefined; - if (statFilter && statFilter.onlyMine) { - filterOr = [ - { - value: companyId, - key: companyField, - operation: "ANY", - }, - { - value: companyId, - key: "companyId", - operation: "ANY", - }, - ]; - } - - frzAgg.mineCompanyId = - statFilter?.onlyMine && companyRole === CompanyRole.PROGRAMME_DEVELOPER - ? companyId - : undefined; - return await this.genAggregateTypeOrmQuery( - this.programmeRepo, - "programme", - null, - [ - new AggrEntry("programmeId", "COUNT", "count"), - { - key: "creditEst", - operation: "SUM", - fieldName: "totalEstCredit", - mineCompanyId: frzAgg.mineCompanyId, - }, - { - key: "creditIssued", - operation: "SUM", - fieldName: "totalIssuedCredit", - mineCompanyId: frzAgg.mineCompanyId, - }, - { - key: "creditBalance", - operation: "SUM", - fieldName: "totalBalanceCredit", - mineCompanyId: frzAgg.mineCompanyId, - }, - { - key: "creditRetired", - operation: "SUM", - fieldName: "totalRetiredCredit", - mineCompanyId: frzAgg.mineCompanyId, - outerQuery: "select sum(s) from unnest", - }, - { - key: "creditTransferred", - operation: "SUM", - fieldName: "totalTxCredit", - mineCompanyId: frzAgg.mineCompanyId, - outerQuery: "select sum(s) from unnest", - }, - frzAgg, - ], - filters, - filterOr, - timeGroup ? { key: "time_group", order: "ASC" } : null, - abilityCondition, - lastTimeForWhere, - statCache, - ["certifiedTime"], - timeGroup ? "createdAt" : undefined, - timeGroup ? "day" : undefined - ); - } - - async calcStat( - stat: Stat, - results, - frzAgg, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - companyRole - ) { - const key = stat.key ? stat.key : stat.type; - console.log(stat.type) - switch (stat.type) { - case StatType.AGG_PROGRAMME_BY_STATUS: - case StatType.AGG_PROGRAMME_BY_SECTOR: - case StatType.MY_AGG_PROGRAMME_BY_STATUS: - case StatType.MY_AGG_PROGRAMME_BY_SECTOR: - case StatType.AGG_AUTH_PROGRAMME_BY_STATUS: - case StatType.MY_AGG_AUTH_PROGRAMME_BY_STATUS: - results[key] = await this.generateProgrammeAggregates( - stat, - frzAgg, - abilityCondition, - lastTimeForWhere, - statCache, - companyId - ); - break; - - case StatType.MY_CREDIT: - results[key] = await this.getCompanyCredits(companyId); - break; - case StatType.PENDING_TRANSFER_INIT: - case StatType.PENDING_TRANSFER_RECV: - results[key] = await this.getPendingTxStats( - stat, - companyId, - abilityCondition, - lastTimeForWhere, - statCache - ); - break; - case StatType.CERTIFIED_BY_ME: - case StatType.REVOKED_BY_ME: - stat.statFilter - ? (stat.statFilter.onlyMine = true) - : (stat.statFilter = { onlyMine: true }); - const d1 = await this.getCertifiedByMePrgrammes( - stat.statFilter, - companyId, - stat.type === StatType.CERTIFIED_BY_ME - ? "certifierId" - : "revokedCertifierId", - abilityCondition, - lastTimeForWhere, - statCache, - undefined - ); - const d2 = await this.getCertifiedByMePrgrammes( - stat.statFilter, - companyId, - stat.type === StatType.CERTIFIED_BY_ME - ? "revokedCertifierId" - : "certifierId", - abilityCondition, - lastTimeForWhere, - statCache, - undefined - ); - d1.last = Math.max(d1.last, d2.last) - results[key] = d1; - break; - case StatType.CERTIFIED_REVOKED_BY_ME: - case StatType.UNCERTIFIED_BY_ME: - if (stat.statFilter) { - stat.statFilter.onlyMine = true; - } else { - stat.statFilter = { onlyMine: true }; - } - results[key] = await this.getCertifiedStatData( - results, - stat, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - StatType.UNCERTIFIED_BY_ME === stat.type, - companyRole - ); - break; - case StatType.ALL_AUTH_PROGRAMMES: - results[key] = await this.getAllAuthProgramme( - stat, - abilityCondition, - lastTimeForWhere, - statCache, - stat.statFilter.timeGroup - ); - break; - // case StatType.CERTIFIED_PROGRAMMES: - // case StatType.REVOKED_PROGRAMMES: - // if (!results[stat.type]) { - // results[stat.type] = await this.getCertifiedProgrammes( - // stat.statFilter, - // abilityCondition, - // lastTimeForWhere, - // statCache, - // companyId, - // stat.type === StatType.CERTIFIED_PROGRAMMES - // ? ["certifierId"] - // : ["revokedCertifierId"], - // frzAgg - // ); - // } - // break; - case StatType.CERTIFIED_REVOKED_PROGRAMMES: - case StatType.MY_CERTIFIED_REVOKED_PROGRAMMES: - if (stat.type === StatType.MY_CERTIFIED_REVOKED_PROGRAMMES) { - stat.statFilter - ? (stat.statFilter.onlyMine = true) - : (stat.statFilter = { onlyMine: true }); - } - results[key] = await this.getCertifiedRevokedAgg( - stat, - results, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - frzAgg, - companyRole - ); - break; - case StatType.CERTIFIED_BY_ME_BY_STATE: - case StatType.CERTIFIED_BY_ME_BY_SECTOR: - case StatType.AUTH_CERTIFIED_BY_ME_BY_STATE: - if (stat.statFilter) { - stat.statFilter.onlyMine = true; - } else { - stat.statFilter = { onlyMine: true }; - } - let filtCState = this.getFilterAndByStatFilter( - stat.statFilter, - { - value: companyId, - key: "certifierId", - operation: "ANY", - }, - "createdTime" - ); - - if (stat.type === StatType.AUTH_CERTIFIED_BY_ME_BY_STATE) { - if (!filtCState) { - filtCState = []; - } - filtCState.push({ - value: ProgrammeStage.AUTHORISED, - key: "currentStage", - operation: "=", - }); - } - - results[key] = await this.genAggregateTypeOrmQuery( - this.programmeRepo, - "programme", - [ - StatType.AUTH_CERTIFIED_BY_ME_BY_STATE, - StatType.CERTIFIED_BY_ME_BY_STATE, - ].includes(stat.type) - ? ["currentStage"] - : ["sector"], - [ - new AggrEntry("programmeId", "COUNT", "count"), - new AggrEntry("creditEst", "SUM", "totalEstCredit"), - new AggrEntry("creditIssued", "SUM", "totalIssuedCredit"), - new AggrEntry("creditBalance", "SUM", "totalBalanceCredit"), - { - key: "creditRetired", - operation: "SUM", - fieldName: "totalRetiredCredit", - outerQuery: "select sum(s) from unnest", - }, - { - key: "creditTransferred", - operation: "SUM", - fieldName: "totalTxCredit", - outerQuery: "select sum(s) from unnest", - }, - frzAgg, - ], - filtCState, - null, - null, - abilityCondition, - lastTimeForWhere, - statCache, - ["certifiedTime", "creditUpdateTime"], - stat.statFilter?.timeGroup ? "createdAt" : undefined, - stat.statFilter?.timeGroup ? "day" : undefined - ); - break; - case StatType.ALL_PROGRAMME_LOCATION: - case StatType.MY_PROGRAMME_LOCATION: - if (stat.type === StatType.MY_PROGRAMME_LOCATION) { - stat.statFilter - ? (stat.statFilter.onlyMine = true) - : (stat.statFilter = { onlyMine: true }); - } - const whereC = []; - whereC.push(`p."programmeId" != 'null'`); - if (stat.statFilter && stat.statFilter.onlyMine) { - whereC.push( - `(${companyId} = ANY(b."companyId") or ${companyId} = ANY(b."certifierId"))` - ); - } - if (stat.statFilter && stat.statFilter.startTime) { - whereC.push(`"createdTime" >= ${stat.statFilter.startTime}`); - } - if (stat.statFilter && stat.statFilter.endTime) { - whereC.push(`"createdTime" <= ${stat.statFilter.endTime}`); - } - const resultsProgrammeLocations = await this.programmeRepo.manager - .query(`SELECT p."programmeId" as loc, b."currentStage" as stage, count(*) AS count - FROM programme b, jsonb_array_elements(b."geographicalLocationCordintes") p("programmeId") - ${whereC.length > 0 ? " where " : " "} - ${whereC.join(" and ")} - GROUP BY p."programmeId", b."currentStage"`); - results[key] = await this.programmeLocationDataFormatter( - resultsProgrammeLocations - ); - break; - case StatType.ALL_TRANSFER_LOCATION: - case StatType.MY_TRANSFER_LOCATION: - if (stat.type === StatType.MY_TRANSFER_LOCATION) { - stat.statFilter - ? (stat.statFilter.onlyMine = true) - : (stat.statFilter = { onlyMine: true }); - } - - let filtCom = this.getFilterAndByStatFilter( - stat.statFilter, - null, - "txTime" - ); - if (!filtCom) { - filtCom = []; - } - filtCom.push({ - value: "0", - key: "retirementType", - operation: "=", - }); - filtCom.push({ - value: TransferStatus.RECOGNISED, - key: "status", - operation: "=", - }); - - let filterOr = undefined; - if (stat.statFilter && stat.statFilter.onlyMine) { - filterOr = []; - filterOr.push({ - value: companyId, - key: "fromCompanyId", - operation: "=", - }); - filterOr.push({ - value: companyId, - key: "programmeCertifierId", - operation: "ANY", - }); - } - results[key] = await this.genAggregateTypeOrmQuery( - this.programmeTransferRepo, - "transfer", - [`toCompanyMeta->>country`], - [new AggrEntry("requestId", "COUNT", "count")], - filtCom, - filterOr, - null, - abilityCondition, - lastTimeForWhere, - statCache, - ["authTime"] - ); - break; - } - console.log('Calc stat done', stat.type) - return results; - } - - async getCertifiedRevokedAgg( - stat: Stat, - results, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - frzAgg, - companyRole - ): Promise { - const revoked = await this.getCertifiedProgrammes( - stat.statFilter, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - [{ key: "certifierId", operation: "=", value: 0 }], - frzAgg, - "revokedCertifierId", - companyRole, - stat.statFilter?.timeGroup ? true : false - ); - - const allAuth = await this.getAllAuthProgramme( - stat, - abilityCondition, - lastTimeForWhere, - statCache, - stat.statFilter?.timeGroup ? true : false, - companyId - ); - - const certified = await this.getCertifiedProgrammes( - stat.statFilter, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - [{ key: "certifierId", operation: ">", value: 0 }], - frzAgg, - "certifierId", - companyRole, - stat.statFilter?.timeGroup ? true : false - ); - - if (!stat.statFilter || stat.statFilter.timeGroup != true) { - return { - last: Math.max(allAuth.all["authTime"], certified.last, revoked.last), - data: { - certifiedSum: Number( - certified && certified.data.length > 0 && certified?.data[0] - ? certified?.data[0]["totalestcredit"] - : 0 - ), - revokedSum: Number( - revoked && revoked.data.length > 0 && revoked?.data[0] - ? revoked.data[0]["totalestcredit"] - : 0 - ), - uncertifiedSum: - Number( - allAuth && allAuth.data.length > 0 && allAuth?.data[0] - ? allAuth?.data[0]["sum"] - : 0 - ) - - Number( - certified && certified?.data.length > 0 && certified?.data[0] - ? certified?.data[0]["totalestcredit"] - : 0 - ) - - Number( - revoked && revoked?.data.length > 0 && revoked?.data[0] - ? revoked.data[0]["totalestcredit"] - : 0 - ), - }, - }; - } else { - const groupedData = {}; - for (const d in certified.data) { - groupedData[d] = { - certifiedSum: Number( - certified && certified.data[d] && certified.data[d].length > 0 - ? certified.data[d][0]["totalestcredit"] - : 0 - ), - revokedSum: 0, - }; - } - for (const d in revoked.data) { - if (!groupedData[d]) { - groupedData[d] = { - revokedSum: Number( - revoked && revoked.data[d] && revoked.data[d].length > 0 - ? revoked.data[d][0]["totalestcredit"] - : 0 - ), - certifiedSum: 0, - }; - } else { - groupedData[d]["revokedSum"] = Number( - revoked && revoked.data[d] && revoked.data[d].length > 0 - ? revoked.data[d][0]["totalestcredit"] - : 0 - ); - } - } - for (const d in allAuth.data) { - if (!groupedData[d]) { - groupedData[d] = { - revokedSum: 0, - certifiedSum: 0, - uncertifiedSum: Number( - allAuth && allAuth.data[d] && allAuth.data[d].length > 0 - ? allAuth.data[d][0]["sum"] - : 0 - ), - }; - } else { - groupedData[d]["uncertifiedSum"] = - Number( - allAuth && allAuth.data[d] && allAuth.data[d].length > 0 - ? allAuth.data[d][0]["sum"] - : 0 - ) - - groupedData[d]["certifiedSum"] - - groupedData[d]["revokedSum"]; - } - } - - const timeLabel = Object.getOwnPropertyNames(groupedData); - timeLabel.sort((a: any, b: any) => { - let dateA: any = new Date(a); - let dateB: any = new Date(b); - return dateA - dateB; - }); - - const sortedGroupedData = {}; - timeLabel?.map((time) => { - if (!sortedGroupedData[time]) { - sortedGroupedData[time] = { - certifiedSum: groupedData[time]["certifiedSum"], - uncertifiedSum: groupedData[time]["uncertifiedSum"], - revokedSum: groupedData[time]["revokedSum"], - }; - } else { - sortedGroupedData[time]["certifiedSum"] = - groupedData[time]["certifiedSum"]; - sortedGroupedData[time]["uncertifiedSum"] = - groupedData[time]["uncertifiedSum"]; - sortedGroupedData[time]["revokedSum"] = - groupedData[time]["revokedSum"]; - } - }); - - const chartData = { - timeLabel: [], - certifiedSum: [], - uncertifiedSum: [], - revokedSum: [], - }; - for (const tg in sortedGroupedData) { - chartData.timeLabel.push(tg); - chartData.certifiedSum.push( - parseFloat(sortedGroupedData[tg]["certifiedSum"]) - ); - chartData.uncertifiedSum.push( - parseFloat(sortedGroupedData[tg]["uncertifiedSum"]) - ); - chartData.revokedSum.push( - parseFloat(sortedGroupedData[tg]["revokedSum"]) - ); - } - - return { - last: Math.max(allAuth.all["authTime"], certified.last, revoked.last), - data: chartData, - }; - } - } - - // async getMultipleStats(sourceStats: Stat[], newStat: Stat, results, frzAgg, abilityCondition, lastTimeForWhere, companyId, aggFunc: any) { - // for (const s of sourceStats) { - // if (!results[s.type]) { - // results = this.calcStat(s, results, frzAgg, abilityCondition, lastTimeForWhere, companyId); - // } - // } - // results[newStat.type] = aggFunc(results); - // } - - async getAggregateQuery( - abilityCondition: string, - query: StatList, - companyId: any, - companyRole: CompanyRole - ): Promise { - let results = {}; - let lastTimeForWhere = {}; - let statCache = {}; - - const frzAgg = new AggrEntry("creditFrozen", "SUM", "totalFreezeCredit"); - frzAgg.outerQuery = "select sum(s) from unnest"; - - for (const stat of query.stats) { - await this.calcStat( - stat, - results, - frzAgg, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - companyRole - ); - } - return new DataCountResponseDto(results); - } - - async getCertifiedStatData( - results, - stat, - abilityCondition, - lastTimeForWhere, - statCache, - companyId, - onlyUncertified, - companyRole - ): Promise { - const allAuth = await this.getAllAuthProgramme( - stat, - abilityCondition, - lastTimeForWhere, - statCache, - stat.statFilter?.timeGroup ? true : false - ); - - console.log("Credit minus allAuth", allAuth); - const certified = await this.getCertifiedByMePrgrammes( - stat.statFilter, - companyId, - "certifierId", - abilityCondition, - lastTimeForWhere, - statCache, - companyRole, - stat.statFilter?.timeGroup ? true : false - ); - - const revoked = await this.getCertifiedByMePrgrammes( - stat.statFilter, - companyId, - "revokedCertifierId", - abilityCondition, - lastTimeForWhere, - statCache, - companyRole, - stat.statFilter?.timeGroup ? true : false - ); - - console.log("Credit minus certified", certified); - if (!onlyUncertified) { - - console.log("Credit minus revoked", revoked); - if (!stat.statFilter || stat.statFilter.timeGroup != true) { - return { - last: Math.max(allAuth.all["authTime"], certified.last, revoked.last), - countLast: Math.max(allAuth.all["statusUpdateTime"], certified.last, revoked.last), - data: { - certifiedCount: Number( - certified && certified.data.length > 0 - ? certified.data[0]["count"] - : 0 - ), - revokedCount: Number( - revoked && revoked.data.length > 0 ? revoked.data[0]["count"] : 0 - ), - uncertifiedCount: - Number( - allAuth && allAuth.data.length > 0 - ? allAuth.data[0]["count"] - : 0 - ) - - Number( - revoked && revoked.data.length > 0 - ? revoked.data[0]["count"] - : 0 - ) - - Number( - certified && certified.data.length > 0 - ? certified.data[0]["count"] - : 0 - ), - revokedSum: Number( - revoked && revoked.data.length > 0 ? revoked.data[0]["sum"] : 0 - ), - certifiedSum: Number( - certified && certified.data.length > 0 - ? certified.data[0]["sum"] - : 0 - ), - uncertifiedSum: - Number( - allAuth && allAuth.data.length > 0 ? allAuth.data[0]["sum"] : 0 - ) - - Number( - revoked && revoked.data.length > 0 ? revoked.data[0]["sum"] : 0 - ) - - Number( - certified && certified.data.length > 0 - ? certified.data[0]["sum"] - : 0 - ), - }, - }; - } else { - const groupedData = {}; - for (const d in certified.data) { - groupedData[d] = { - certifiedSum: Number( - certified && certified.data[d] && certified.data[d].length > 0 - ? certified.data[d][0]["sum"] - : 0 - ), - revokedSum: 0, - }; - } - for (const d in revoked.data) { - if (!groupedData[d]) { - groupedData[d] = { - revokedSum: Number( - revoked && revoked.data[d] && revoked.data[d].length > 0 - ? revoked.data[d][0]["sum"] - : 0 - ), - certifiedSum: 0, - }; - } else { - groupedData[d]["revokedSum"] = Number( - revoked && revoked.data[d] && revoked.data[d].length > 0 - ? revoked.data[d][0]["sum"] - : 0 - ); - } - } - for (const d in allAuth.data) { - if (!groupedData[d]) { - groupedData[d] = { - revokedSum: 0, - certifiedSum: 0, - uncertifiedSum: Number( - allAuth && allAuth.data[d] && allAuth.data[d].length > 0 - ? allAuth.data[d][0]["sum"] - : 0 - ), - }; - } else { - groupedData[d]["uncertifiedSum"] = - Number( - allAuth && allAuth.data[d] && allAuth.data[d].length > 0 - ? allAuth.data[d][0]["sum"] - : 0 - ) - - groupedData[d]["certifiedSum"] - - groupedData[d]["revokedSum"]; - } - } - - const timeLabel = Object.getOwnPropertyNames(groupedData); - timeLabel.sort((a: any, b: any) => { - let dateA: any = new Date(a); - let dateB: any = new Date(b); - return dateA - dateB; - }); - - const sortedGroupedData = {}; - timeLabel?.map((time) => { - if (!sortedGroupedData[time]) { - sortedGroupedData[time] = { - certifiedSum: groupedData[time]["certifiedSum"], - uncertifiedSum: groupedData[time]["uncertifiedSum"], - revokedSum: groupedData[time]["revokedSum"], - }; - } else { - sortedGroupedData[time]["certifiedSum"] = - groupedData[time]["certifiedSum"]; - sortedGroupedData[time]["uncertifiedSum"] = - groupedData[time]["uncertifiedSum"]; - sortedGroupedData[time]["revokedSum"] = - groupedData[time]["revokedSum"]; - } - }); - - const chartData = { - timeLabel: [], - certifiedSum: [], - uncertifiedSum: [], - revokedSum: [], - }; - for (const tg in sortedGroupedData) { - chartData.timeLabel.push(tg); - chartData.certifiedSum.push( - parseFloat(sortedGroupedData[tg]["certifiedSum"]) - ); - chartData.uncertifiedSum.push( - parseFloat(sortedGroupedData[tg]["uncertifiedSum"]) - ); - chartData.revokedSum.push( - parseFloat(sortedGroupedData[tg]["revokedSum"]) - ); - } - - return { - last: Math.max(allAuth.all["authTime"], certified.last, revoked.last), - countLast: Math.max(allAuth.all["statusUpdateTime"], certified.last, revoked.last), - data: chartData, - }; - } - } else { - return { - last: Math.max(allAuth.all["authTime"], certified.last, revoked.last), - countLast: Math.max(certified.last, allAuth.all["statusUpdateTime"], revoked.last), - data: { - uncertifiedSum: - Number( - allAuth && allAuth.data.length > 0 ? allAuth.data[0]["sum"] : 0 - ) - - Number( - certified && certified.data.length > 0 - ? certified.data[0]["sum"] - : 0 - ), - uncertifiedCount: - Number( - allAuth && allAuth.data.length > 0 ? allAuth.data[0]["count"] : 0 - ) - - Number( - certified && certified.data.length > 0 - ? certified.data[0]["count"] - : 0 - ), - }, - }; - } - } - - async getCompanyCredits(companyId: any) { - const comp = await this.companyRepo.findOne({ - where: { - companyId: companyId, - }, - }); - return { - data: { - primary: comp ? comp.creditBalance : 0, - secondary: comp ? comp.secondaryAccountBalance : 0, - }, - last: comp.creditTxTime, - }; - } - async getPendingTxStats( - stat, - companyId, - abilityCondition, - lastTimeForWhere, - statCache - ) { - if (stat.statFilter) { - stat.statFilter.onlyMine = false; - } else { - stat.statFilter = { onlyMine: false }; - } - let filt = this.getFilterAndByStatFilter(stat.statFilter, null, "txTime"); - - if (filt == null) { - filt = []; - } - filt.push({ - key: "status", - operation: "=", - value: TransferStatus.PENDING, - }); - filt.push({ - key: "isRetirement", - operation: "!=", - value: true, - }); - - filt.push( { - value: companyId, - key: - stat.type === StatType.PENDING_TRANSFER_INIT - ? "initiatorCompanyId" - : "fromCompanyId", - operation: "=", - }) - - return await this.genAggregateTypeOrmQuery( - this.programmeTransferRepo, - "transfer", - null, - [new AggrEntry("requestId", "COUNT", "count")], - filt, - null, - null, - abilityCondition, - lastTimeForWhere, - statCache, - ["txTime"] - ); - } - async generateProgrammeAggregates( - stat, - frzAgg, - abilityCondition, - lastTimeForWhere, - statCache, - companyId - ) { - if ( - [ - StatType.MY_AGG_PROGRAMME_BY_SECTOR, - StatType.MY_AGG_PROGRAMME_BY_STATUS, - StatType.MY_AGG_AUTH_PROGRAMME_BY_STATUS, - ].includes(stat.type) - ) { - stat.statFilter - ? (stat.statFilter.onlyMine = true) - : (stat.statFilter = { onlyMine: true }); - } - - let filterAnd = this.getFilterAndByStatFilter( - stat.statFilter, - { - value: companyId, - key: "companyId", - operation: "ANY", - }, - "createdTime" - ); - - if ( - [ - StatType.AGG_AUTH_PROGRAMME_BY_STATUS, - StatType.MY_AGG_AUTH_PROGRAMME_BY_STATUS, - ].includes(stat.type) - ) { - if (!filterAnd) { - filterAnd = []; - } - filterAnd.push({ - value: ProgrammeStage.AUTHORISED, - key: "currentStage", - operation: "=", - }); - } - - frzAgg.mineCompanyId = stat?.statFilter?.onlyMine ? companyId : undefined; - - return await this.genAggregateTypeOrmQuery( - this.programmeRepo, - "programme", - [ - StatType.AGG_PROGRAMME_BY_STATUS, - StatType.MY_AGG_PROGRAMME_BY_STATUS, - StatType.MY_AGG_AUTH_PROGRAMME_BY_STATUS, - StatType.AGG_AUTH_PROGRAMME_BY_STATUS, - ].includes(stat.type) - ? ["currentStage"] - : ["sector"], - [ - new AggrEntry("programmeId", "COUNT", "count"), - { - key: "creditEst", - operation: "SUM", - fieldName: "totalEstCredit", - mineCompanyId: stat?.statFilter?.onlyMine ? companyId : undefined, - }, - { - key: "creditIssued", - operation: "SUM", - fieldName: "totalIssuedCredit", - mineCompanyId: stat?.statFilter?.onlyMine ? companyId : undefined, - }, - { - key: "creditBalance", - operation: "SUM", - fieldName: "totalBalanceCredit", - mineCompanyId: stat?.statFilter?.onlyMine ? companyId : undefined, - }, - { - key: "creditRetired", - operation: "SUM", - fieldName: "totalRetiredCredit", - mineCompanyId: stat?.statFilter?.onlyMine ? companyId : undefined, - outerQuery: "select sum(s) from unnest", - }, - { - key: "creditTransferred", - operation: "SUM", - fieldName: "totalTxCredit", - mineCompanyId: stat?.statFilter?.onlyMine ? companyId : undefined, - outerQuery: "select sum(s) from unnest", - }, - frzAgg, - ], - filterAnd, - null, - stat.statFilter?.timeGroup ? { key: "time_group", order: "ASC" } : null, - abilityCondition, - lastTimeForWhere, - statCache, - [([ - StatType.AGG_PROGRAMME_BY_STATUS, - StatType.MY_AGG_PROGRAMME_BY_STATUS, - StatType.MY_AGG_AUTH_PROGRAMME_BY_STATUS, - StatType.AGG_AUTH_PROGRAMME_BY_STATUS, - ].includes(stat.type) - ? "statusUpdateTime" - : "createdTime"), "creditUpdateTime"], - stat.statFilter?.timeGroup ? "createdAt" : undefined, - stat.statFilter?.timeGroup ? "day" : undefined - ); - } - - private groupByStatus(key: string, data: any) { - const mapping = {}; - for (const d of data) { - if (!mapping[d[key]]) { - mapping[d[key]] = []; - } - mapping[d[key]].push(d); - } - - return data; - } -} diff --git a/backend/services/src/analytics-api/analytics.api.module.ts b/backend/services/src/analytics-api/analytics.api.module.ts deleted file mode 100644 index 0733239de..000000000 --- a/backend/services/src/analytics-api/analytics.api.module.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Logger, Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { ProgrammeController } from "./programme.controller"; -import { AnalyticsAPIService } from "./analytics.api.service"; -import configuration from "../shared/configuration"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import { TypeOrmConfigService } from "../shared/typeorm.config.service"; -import { Programme } from "../shared/entities/programme.entity"; -import { ProgrammeTransfer } from "../shared/entities/programme.transfer"; -import { ProgrammeTransferViewEntityQuery } from "../shared/entities/programmeTransfer.view.entity"; -import { ProgrammeLedgerModule } from "../shared/programme-ledger/programme-ledger.module"; -import { CaslModule } from "../shared/casl/casl.module"; -import { AuthModule } from "../shared/auth/auth.module"; -import { UtilModule } from "../shared/util/util.module"; -import { AggregateAPIService } from "./aggregate.api.service"; -import { Company } from "../shared/entities/company.entity"; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - imports: undefined, - }), - TypeOrmModule.forFeature([ - Programme, - ProgrammeTransfer, - ProgrammeTransferViewEntityQuery, - Company - ]), - AuthModule, - CaslModule, - UtilModule, - ProgrammeLedgerModule, - ], - controllers: [ProgrammeController], - providers: [AnalyticsAPIService, Logger, AggregateAPIService], -}) -export class AnalyticsAPIModule {} diff --git a/backend/services/src/analytics-api/analytics.api.service.ts b/backend/services/src/analytics-api/analytics.api.service.ts deleted file mode 100644 index 460e5180e..000000000 --- a/backend/services/src/analytics-api/analytics.api.service.ts +++ /dev/null @@ -1,891 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { InjectRepository } from "@nestjs/typeorm"; -import { DataCountResponseDto } from "../shared/dto/data.count.response"; -import { Programme } from "../shared/entities/programme.entity"; -import { ProgrammeTransfer } from "../shared/entities/programme.transfer"; -import { Repository } from "typeorm"; -import { StatList } from "../shared/dto/stat.list.dto"; -import { StatType } from "../shared/enum/stat.type.enum"; -import { ChartStatList } from "../shared/dto/chartStats.list.dto"; -import { ChartType } from "../shared/enum/chart.type.enum"; -import { HelperService } from "../shared/util/helpers.service"; -import { ProgrammeStage } from "../shared/enum/programme-status.enum"; -import { programmeStatusRequestDto } from "../shared/dto/programmeStatus.request.dto"; -import { CreditStatType } from "../shared/enum/credit.stat.type.enum"; -import { chartStatsRequestDto } from "../shared/dto/chartStats.request.dto"; -import { ChartStatsResponseDto } from "../shared/dto/charts.stats.response"; -import { - chartStatsResultInMonths, - chartStatsResultInitialValueInMonths, - chartStatsResultSend, - chartStatsResultInitialValueSend, -} from "../shared/dto/chart.stats.result"; -import { ProgrammeTransferViewEntityQuery } from "../shared/entities/programmeTransfer.view.entity"; - -@Injectable() -export class AnalyticsAPIService { - constructor( - private configService: ConfigService, - private helperService: HelperService, - @InjectRepository(Programme) private programmeRepo: Repository, - @InjectRepository(ProgrammeTransferViewEntityQuery) - private programmeTransferRepo: Repository - ) {} - - async programmesStaticChartsDetails( - abilityCondition: string, - query: ChartStatList, - companyId: any - ): Promise { - let result: chartStatsResultSend = chartStatsResultInitialValueSend; - let resultsX: chartStatsResultSend = chartStatsResultInitialValueSend; - let userCompanyId = companyId; - let category = query?.category; - let results = {}; - for (const stat of query.stats) { - switch (stat.type) { - case ChartType.TOTAL_PROGRAMS: - const startTime = query.startTime; - const endTime = query.endTime; - // const startTime = 1672531200000; - // const endTime = 1703894400000; - const duration = endTime - startTime; - const durationInDays = Math.ceil(duration / 1000 / 60 / 60 / 24); - let sTime = startTime; - let params: chartStatsRequestDto = { - type: "TOTAL_PROGRAMS", - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startDate: startTime, - endDate: endTime, - }; - let totalProgrammesResponse = await this.programmeRepo - .createQueryBuilder() - .select([ - `"programmeId"`, - `"currentStage"`, - `"companyId"`, - `"createdTime"`, - ]) - .where( - this.helperService.generateWhereSQLChartStastics( - params, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawMany(); - let duraion: number; - let durationCounts: number; - if (durationInDays > 365) { - duraion = 31104000000; - durationCounts = Math.ceil(duration / 1000 / 60 / 60 / 24 / 365); - } else if (durationInDays > 31) { - duraion = 2592000000; - durationCounts = Math.ceil(duration / 1000 / 60 / 60 / 24 / 30); - } else if (durationInDays > 7) { - duraion = 604800000; - durationCounts = Math.ceil(duration / 1000 / 60 / 60 / 24 / 7); - } else if (durationInDays > 1) { - duraion = 86400000; - durationCounts = Math.ceil(duration / 1000 / 60 / 60 / 24); - } - let data = { - awaitingAuthorization: [], - authorised: [], - rejected: [], - programmes: [], - }; - for (let index = 1; index <= durationCounts; index++) { - let eTime = sTime + duraion; - let pendingC = 0; - let authorisedC = 0; - let rejectedC = 0; - let programmesC = 0; - // console.log("week count ---- ", index, { sTime, eTime }); - for ( - let indexProgramme = 0; - indexProgramme < totalProgrammesResponse.length; - indexProgramme++ - ) { - if ( - totalProgrammesResponse[indexProgramme]?.createdTime >= sTime && - totalProgrammesResponse[indexProgramme]?.createdTime < eTime - ) { - programmesC++; - totalProgrammesResponse[indexProgramme]?.currentStage === - "AwaitingAuthorization" && pendingC++; - totalProgrammesResponse[indexProgramme]?.currentStage === - "Authorised" && authorisedC++; - totalProgrammesResponse[indexProgramme]?.currentStage === - "Rejected" && rejectedC++; - } - if (indexProgramme === totalProgrammesResponse.length - 1) { - data?.awaitingAuthorization.push({ - [sTime]: Math.round(pendingC), - }); - data?.authorised.push({ [sTime]: Math.round(authorisedC) }); - data?.rejected.push({ [sTime]: Math.round(rejectedC) }); - } - } - sTime = eTime; - } - console.log("data ----------- > ", data); - results[stat.type] = data; - break; - - case ChartType.TOTAL_PROGRAMS_SECTOR: - const startTimeSector = query.startTime; - const endTimeSector = query.endTime; - const durationSector = endTimeSector - startTimeSector; - const durationSectorInDays = Math.ceil( - durationSector / 1000 / 60 / 60 / 24 - ); - let sTimeSector = startTimeSector; - let paramsSector: chartStatsRequestDto = { - type: "TOTAL_PROGRAMS", - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startDate: startTimeSector, - endDate: endTimeSector, - }; - let totalProgrammesResponseSector = await this.programmeRepo - .createQueryBuilder() - .select([ - `"programmeId"`, - `"sector"`, - `"companyId"`, - `"createdTime"`, - ]) - .where( - this.helperService.generateWhereSQLChartStastics( - paramsSector, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawMany(); - let duraionSectorT: number; - let durationSectorCounts: number; - if (durationSectorInDays > 31) { - duraionSectorT = 2592000000; - durationSectorCounts = Math.ceil( - durationSector / 1000 / 60 / 60 / 24 / 30 - ); - } else if (durationSectorInDays > 7) { - duraionSectorT = 604800000; - durationSectorCounts = Math.ceil( - durationSector / 1000 / 60 / 60 / 24 / 7 - ); - } else if (durationSectorInDays > 1) { - duraionSectorT = 86400000; - durationSectorCounts = Math.ceil( - durationSector / 1000 / 60 / 60 / 24 - ); - } - let dataSector = { - energy: [], - health: [], - education: [], - transport: [], - manufacturing: [], - hospitality: [], - forestry: [], - waste: [], - agriculture: [], - other: [], - programmes: [], - }; - for (let index = 1; index <= durationSectorCounts; index++) { - let eTime = sTimeSector + duraionSectorT; - let energyC = 0; - let healthC = 0; - let educationC = 0; - let transportC = 0; - let manufacturingC = 0; - let hospitalityC = 0; - let forestryC = 0; - let wasteC = 0; - let agricultureC = 0; - let otherC = 0; - let programmesC = 0; - // console.log("week count ---- ", index, { sTimeSector, eTime }); - for ( - let indexProgramme = 0; - indexProgramme < totalProgrammesResponseSector.length; - indexProgramme++ - ) { - if ( - totalProgrammesResponseSector[indexProgramme]?.createdTime >= - sTimeSector && - totalProgrammesResponseSector[indexProgramme]?.createdTime < - eTime - ) { - let prgramme = - totalProgrammesResponseSector[indexProgramme]?.programmeId; - programmesC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Energy" && energyC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Health" && healthC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Education" && educationC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Transport" && transportC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Manufacturing" && manufacturingC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Hospitality" && hospitalityC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Forestry" && forestryC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Waste" && wasteC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Agriculture" && agricultureC++; - totalProgrammesResponseSector[indexProgramme]?.sector === - "Other" && otherC++; - } - if (indexProgramme === totalProgrammesResponseSector.length - 1) { - dataSector?.energy.push({ [sTimeSector]: energyC }); - dataSector?.health.push({ [sTimeSector]: healthC }); - dataSector?.education.push({ [sTimeSector]: educationC }); - dataSector?.transport.push({ [sTimeSector]: transportC }); - dataSector?.manufacturing.push({ - [sTimeSector]: manufacturingC, - }); - dataSector?.hospitality.push({ [sTimeSector]: hospitalityC }); - dataSector?.forestry.push({ [sTimeSector]: forestryC }); - dataSector?.waste.push({ [sTimeSector]: wasteC }); - dataSector?.agriculture.push({ [sTimeSector]: agricultureC }); - dataSector?.other.push({ [sTimeSector]: otherC }); - } - } - sTimeSector = eTime; - } - console.log("dataSector ----------- > ", dataSector); - results[stat.type] = dataSector; - break; - - case ChartType.TOTAL_CREDITS: - const startTimeCredit = query.startTime; - const endTimeCredit = query.endTime; - const durationCredit = endTimeCredit - startTimeCredit; - const durationCreditInDays = Math.ceil( - durationCredit / 1000 / 60 / 60 / 24 - ); - let sTimeCredit = startTimeCredit; - let paramsCredit: chartStatsRequestDto = { - type: "TOTAL_PROGRAMS", - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startDate: startTimeCredit, - endDate: endTimeCredit, - }; - let totalResponseCredit = await this.programmeRepo - .createQueryBuilder() - .select([ - `"programmeId"`, - `"companyId"`, - `"creditIssued"`, - `"creditEst"`, - `"creditBalance"`, - `"creditTransferred"`, - `"creditRetired"`, - `"creditFrozen"`, - `"createdTime"`, - ]) - .where( - this.helperService.generateWhereSQLChartStastics( - paramsCredit, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawMany(); - let duraionCreditT: number; - let durationCreditCounts: number; - if (durationCreditInDays > 31) { - duraionCreditT = 2592000000; - durationCreditCounts = Math.ceil( - durationCredit / 1000 / 60 / 60 / 24 / 30 - ); - } else if (durationCreditInDays > 7) { - duraionCreditT = 604800000; - durationCreditCounts = Math.ceil( - durationCredit / 1000 / 60 / 60 / 24 / 7 - ); - } else if (durationCreditInDays > 1) { - duraionCreditT = 86400000; - durationCreditCounts = Math.ceil( - durationCredit / 1000 / 60 / 60 / 24 - ); - } - let dataCredits = { - authorized: [], - issued: [], - transferred: [], - retired: [], - }; - for (let index = 1; index <= durationCreditCounts; index++) { - let eTimeCredit = sTimeCredit + duraionCreditT; - let availableS = 0; - let estimatedS = 0; - let issuedS = 0; - let transferredS = 0; - let retiredS = 0; - let frozenS = 0; - // console.log("week count ---- ", index, { sTime, eTime }); - for ( - let indexProgramme = 0; - indexProgramme < totalResponseCredit.length; - indexProgramme++ - ) { - if ( - totalResponseCredit[indexProgramme]?.createdTime >= - sTimeCredit && - totalResponseCredit[indexProgramme]?.createdTime < eTimeCredit - ) { - if ( - totalResponseCredit[indexProgramme]?.creditBalance !== null - ) { - availableS = - availableS + - parseFloat( - totalResponseCredit[indexProgramme]?.creditBalance - ); - } - if ( - totalResponseCredit[indexProgramme]?.creditIssued !== null - ) { - issuedS = - issuedS + - parseFloat( - totalResponseCredit[indexProgramme]?.creditIssued - ); - } - if ( - totalResponseCredit[indexProgramme]?.creditTransferred !== - null - ) { - transferredS = - transferredS + - parseFloat( - totalResponseCredit[indexProgramme]?.creditTransferred - ); - } - if ( - totalResponseCredit[indexProgramme]?.creditRetired !== null - ) { - retiredS = - retiredS + - parseFloat( - totalResponseCredit[indexProgramme]?.creditRetired - ); - } - if ( - totalResponseCredit[indexProgramme]?.creditFrozen !== null - ) { - let sum: any = 0; - let creditFrozen: any[] = - totalResponseCredit[indexProgramme]?.creditFrozen; - for (let cF = 0; cF < creditFrozen.length; cF++) { - sum = sum + creditFrozen[cF]; - } - frozenS = frozenS + parseFloat(sum); - } - if (totalResponseCredit[indexProgramme]?.creditEst !== null) { - estimatedS = - estimatedS + - parseFloat(totalResponseCredit[indexProgramme]?.creditEst); - } - } - if (indexProgramme === totalResponseCredit.length - 1) { - dataCredits?.authorized.push({ - [sTimeCredit]: (estimatedS - issuedS).toFixed(1), - }); - dataCredits?.issued.push({ - [sTimeCredit]: availableS.toFixed(1), - }); - dataCredits?.transferred.push({ - [sTimeCredit]: transferredS.toFixed(1), - }); - dataCredits?.retired.push({ - [sTimeCredit]: retiredS.toFixed(1), - }); - } - } - sTimeCredit = eTimeCredit; - } - results[stat.type] = dataCredits; - break; - - case ChartType.TOTAL_CREDITS_CERTIFIED: - const startTimeCreditsCertified = query.startTime; - const endTimeCreditsCertified = query.endTime; - const durationCreditCertified = - endTimeCreditsCertified - startTimeCreditsCertified; - const durationCreditInDaysCertified = Math.ceil( - durationCreditCertified / 1000 / 60 / 60 / 24 - ); - let sTimeCreditCertified = startTimeCreditsCertified; - let paramsCreditsCertified: chartStatsRequestDto = { - type: "TOTAL_CREDITS_CERTIFIED", - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startDate: startTimeCreditsCertified, - endDate: endTimeCreditsCertified, - }; - let totalResponseCreditsCertified = await this.programmeRepo - .createQueryBuilder() - .select([ - `"programmeId"`, - `"companyId"`, - `"creditBalance"`, - `"certifierId"`, - `"createdTime"`, - ]) - .where( - this.helperService.generateWhereSQLChartStastics( - paramsCreditsCertified, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawMany(); - let duraionCreditCertifiedT: number; - let durationCreditCertifiedCounts: number; - if (durationCreditInDaysCertified > 31) { - duraionCreditCertifiedT = 2592000000; - durationCreditCertifiedCounts = Math.ceil( - durationCreditCertified / 1000 / 60 / 60 / 24 / 30 - ); - } else if (durationCreditInDaysCertified > 7) { - duraionCreditCertifiedT = 604800000; - durationCreditCertifiedCounts = Math.ceil( - durationCreditCertified / 1000 / 60 / 60 / 24 / 7 - ); - } else if (durationCreditInDaysCertified > 1) { - duraionCreditCertifiedT = 86400000; - durationCreditCertifiedCounts = Math.ceil( - durationCreditCertified / 1000 / 60 / 60 / 24 - ); - } - let dataCreditsCertified = { - certified: [], - uncertified: [], - revoked: [], - }; - for (let index = 1; index <= durationCreditCertifiedCounts; index++) { - let eTimeCreditCertified = - sTimeCreditCertified + duraionCreditCertifiedT; - let certifiedS = 0; - let unCertifiedS = 0; - let revokedS = 0; - // console.log(week count ---- ", index, { sTime, eTime }); - for ( - let indexProgramme = 0; - indexProgramme < totalResponseCreditsCertified.length; - indexProgramme++ - ) { - if ( - totalResponseCreditsCertified[indexProgramme]?.createdTime >= - sTimeCreditCertified && - totalResponseCreditsCertified[indexProgramme]?.createdTime < - eTimeCreditCertified - ) { - if ( - totalResponseCreditsCertified[indexProgramme] - ?.creditBalance !== null && - totalResponseCreditsCertified[indexProgramme]?.certifierId !== - null && - totalResponseCreditsCertified[indexProgramme]?.certifierId - ?.length > 0 - ) { - certifiedS = - certifiedS + - parseFloat( - totalResponseCreditsCertified[indexProgramme] - ?.creditBalance - ); - } else if ( - totalResponseCreditsCertified[indexProgramme] - ?.creditBalance !== null && - totalResponseCreditsCertified[indexProgramme]?.certifierId !== - null - ) { - revokedS = - revokedS + - parseFloat( - totalResponseCreditsCertified[indexProgramme] - ?.creditBalance - ); - } - if ( - totalResponseCreditsCertified[indexProgramme] - ?.creditBalance !== null && - totalResponseCreditsCertified[indexProgramme]?.certifierId === - null - ) { - unCertifiedS = - unCertifiedS + - parseFloat( - totalResponseCreditsCertified[indexProgramme] - ?.creditBalance - ); - } - } - if (indexProgramme === totalResponseCreditsCertified.length - 1) { - dataCreditsCertified?.certified.push({ - [sTimeCreditCertified]: certifiedS.toFixed(1), - }); - dataCreditsCertified?.uncertified.push({ - [sTimeCreditCertified]: unCertifiedS.toFixed(1), - }); - dataCreditsCertified?.revoked.push({ - [sTimeCreditCertified]: revokedS.toFixed(1), - }); - } - } - sTimeCreditCertified = eTimeCreditCertified; - } - results[stat.type] = dataCreditsCertified; - break; - - case ChartType.PROGRAMME_LOCATIONS: - const startTimeProgrammeLocations = query.startTime; - const endTimeProgrammeLocations = query.endTime; - let paramsProgrammeLocations: chartStatsRequestDto = { - type: "TOTAL_PROGRAMS", - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startDate: startTimeProgrammeLocations, - endDate: endTimeProgrammeLocations, - }; - let totalResponseProgrammeLocation = await this.programmeRepo - .createQueryBuilder() - .select([ - `"programmeId"`, - `"companyId"`, - `"geographicalLocationCordintes"`, - `"createdTime"`, - ]) - .where( - this.helperService.generateWhereSQLChartStastics( - paramsProgrammeLocations, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawMany(); - let locationsGeoData: any = {}; - let features: any[] = []; - locationsGeoData.type = "FeatureCollection"; - for (let i = 0; i < totalResponseProgrammeLocation.length; i++) { - let programmeCordinates: any[] = - totalResponseProgrammeLocation[i]?.geographicalLocationCordintes; - if (programmeCordinates) { - for (let j = 0; j < programmeCordinates?.length; j++) { - if (programmeCordinates[j] !== null) { - console.log("cordinates ---- > ", programmeCordinates[j]); - let programmeGeoData: any = {}; - let location: any = programmeCordinates[j]; - programmeGeoData.type = "Feature"; - let properties: any = {}; - let geometry: any = {}; - properties.id = String(i) + String(j); - properties.count = 1; - geometry.type = "Point"; - geometry.coordinates = location; - programmeGeoData.properties = properties; - programmeGeoData.geometry = geometry; - features.push(programmeGeoData); - } - } - } - } - locationsGeoData.features = [...features]; - - results[stat.type] = locationsGeoData; - break; - - case ChartType.TRANSFER_LOCATIONS: - const startTimeTransferLocations = query.startTime; - const endTimeTransferLocations = query.endTime; - let paramsTransferLocations: chartStatsRequestDto = { - type: stat.type, - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startDate: startTimeTransferLocations, - endDate: endTimeTransferLocations, - }; - let totalResponseTransferLocation = await this.programmeTransferRepo - .createQueryBuilder() - .select([`"requestId"`, `"companyId"`, `"toCompanyMeta"`]) - .where( - this.helperService.generateWhereSQLChartStastics( - paramsTransferLocations, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawMany(); - let featuresTransfer: any[] = []; - let locations = {}; - let total = 0; - for (const t of totalResponseTransferLocation) { - if (t?.toCompanyMeta) { - let toCompanyMeta = t?.toCompanyMeta; - if (toCompanyMeta?.country) { - if (!locations[toCompanyMeta?.country]) { - locations[toCompanyMeta?.country] = 1; - } else { - locations[toCompanyMeta?.country] += 1; - } - total += 1; - } - } - } - for (const c in locations) { - featuresTransfer.push({ - code: c, - count: locations[c], - ratio: locations[c] / total, - }); - } - - // for ( - // let index = 0; - // index < totalResponseTransferLocation.length; - // index++ - // ) { - // if (totalResponseTransferLocation[index]?.toCompanyMeta) { - // let toCompanyMeta = - // totalResponseTransferLocation[index]?.toCompanyMeta; - // if (toCompanyMeta?.country) { - // if (!locations?.includes(toCompanyMeta?.country)) { - // locations.push(toCompanyMeta?.country); - // featuresTransfer.push({ - // code: toCompanyMeta?.country, - // hdi: - // index === 0 - // ? 1 - // : index / totalResponseTransferLocation.length, - // }); - // } - // } - // } - // } - - results[stat.type] = featuresTransfer; - break; - } - } - return new ChartStatsResponseDto(results); - } - - async programmesStaticDetails( - abilityCondition: string, - query: StatList, - companyId: any - ): Promise { - let userCompanyId = companyId; - let category = query?.category; - let results = {}; - for (const stat of query.stats) { - switch (stat.type) { - case StatType.TOTAL_PROGRAMS: - const startTimeProgramme = query.startTime; - const endTimeProgramme = query.endTime; - const valuesProgrammes: programmeStatusRequestDto = { - type: "TOTAL_PROGRAMS", - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startTime: startTimeProgramme, - endTime: endTimeProgramme, - }; - let totalProgrammesResponse = await this.programmeRepo - .createQueryBuilder() - .where( - this.helperService.generateWhereSQLStastics( - valuesProgrammes, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getCount(); - - results[stat.type] = totalProgrammesResponse; - break; - - case StatType.TOTAL_PROGRAMS_LAST_UPDATE: - let totalProgrammesResponseLatest = await this.programmeRepo - .createQueryBuilder() - .select([`"programmeId"`, `"createdTime"`]) - .where( - abilityCondition - ? this.helperService.parseMongoQueryToSQL(abilityCondition) - : "" - ) - .orderBy(`"createdTime"`, "DESC") - .limit(1) - .getRawMany(); - - results[stat.type] = totalProgrammesResponseLatest[0]?.createdTime - ? totalProgrammesResponseLatest[0]?.createdTime - : Math.round(Date.now() / 1000); - break; - - case StatType.PROGRAMS_BY_STATUS: - const startTimeProgrammeStatus = query.startTime; - const endTimeProgrammeStatus = query.endTime; - const values: programmeStatusRequestDto = { - type: "PROGRAMS_BY_STATUS", - value: stat.value, - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startTime: startTimeProgrammeStatus, - endTime: endTimeProgrammeStatus, - }; - let programmeByStatus = await this.programmeRepo - .createQueryBuilder() - .where( - this.helperService.generateWhereSQLStastics( - values, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getCount(); - results[stat.value] = programmeByStatus; - break; - - case StatType.TRANSFER_REQUEST: - let transferRequest = await this.programmeTransferRepo - .createQueryBuilder() - .where( - abilityCondition - ? this.helperService.parseMongoQueryToSQL(abilityCondition) - : "" - ) - .getCount(); - results[stat.type] = transferRequest; - break; - - case StatType.TRANSFER_REQUEST_SENT: - const valuesTransferRequestSent: programmeStatusRequestDto = { - type: stat.type, - }; - let transferRequestSent = await this.programmeTransferRepo - .createQueryBuilder() - .where( - this.helperService.generateWhereSQLChartStasticsWithoutTimeRange( - valuesTransferRequestSent, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getCount(); - results[stat.type] = transferRequestSent; - break; - - case StatType.PROGRAMS_CERTIFIED: - const valuesProgrammesCertified: programmeStatusRequestDto = { - type: stat.type, - }; - let programmesCertified = await this.programmeRepo - .createQueryBuilder() - .where( - this.helperService.generateWhereSQLChartStasticsWithoutTimeRange( - valuesProgrammesCertified, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getCount(); - results[stat.type] = programmesCertified; - break; - - case StatType.PROGRAMS_UNCERTIFIED: - const valuesProgrammesUnCertified: programmeStatusRequestDto = { - type: stat.type, - }; - let programmesUnCertified = await this.programmeRepo - .createQueryBuilder() - .where( - this.helperService.generateWhereSQLChartStasticsWithoutTimeRange( - valuesProgrammesUnCertified, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getCount(); - results[stat.type] = programmesUnCertified; - break; - - case StatType.TRANSFER_REQUEST_RECEIVED: - const valuesTransferRequestReceived: programmeStatusRequestDto = { - type: stat.type, - }; - let transferRequestReceived = await this.programmeTransferRepo - .createQueryBuilder() - .where( - this.helperService.generateWhereSQLChartStasticsWithoutTimeRange( - valuesTransferRequestReceived, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getCount(); - results[stat.type] = transferRequestReceived; - break; - - case StatType.CREDIT_STATS_BALANCE: - case StatType.CREDIT_STATS_TRANSFERRED: - case StatType.CREDIT_STATS_RETIRED: - case StatType.CREDIT_STATS_ISSUED: - case StatType.CREDIT_STATS_ESTIMATED: - case StatType.CREDIT_STATS_FROZEN: - const startTimeProgrammeCredits = query.startTime; - const endTimeProgrammeCredits = query.endTime; - const valuesCreditRequest: programmeStatusRequestDto = { - type: stat.type, - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startTime: startTimeProgrammeCredits, - endTime: endTimeProgrammeCredits, - }; - let creditStat = await this.programmeRepo - .createQueryBuilder() - .select(`SUM("${CreditStatType[stat.type]}")`) - .where( - this.helperService.generateWhereSQLStastics( - valuesCreditRequest, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawOne(); - results[stat.type] = creditStat; - break; - - // case StatType.CREDIT_CERTIFIED_BALANCE: - // case StatType.CREDIT_CERTIFIED_TRANSFERRED: - // case StatType.CREDIT_CERTIFIED_RETIRED: - // case StatType.CREDIT_CERTIFIED_ISSUED: - case StatType.CREDIT_CERTIFIED: - case StatType.CREDIT_UNCERTIFIED: - case StatType.CREDIT_REVOKED: - const startTimeProgrammeCreditsCertified = query.startTime; - const endTimeProgrammeCreditsCertified = query.endTime; - const certifiedRequestParams: programmeStatusRequestDto = { - type: stat.type, - companyId: - userCompanyId !== null && category === "mine" ? companyId : "", - startTime: startTimeProgrammeCreditsCertified, - endTime: endTimeProgrammeCreditsCertified, - }; - let creditCertifiedResponse = await this.programmeRepo - .createQueryBuilder() - .select(`SUM("${CreditStatType[stat.type]}")`) - .where( - this.helperService.generateWhereSQLStastics( - certifiedRequestParams, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .getRawOne(); - results[stat.type] = creditCertifiedResponse; - break; - } - } - return new DataCountResponseDto(results); - } -} diff --git a/backend/services/src/analytics-api/handler.ts b/backend/services/src/analytics-api/handler.ts index 3112581a8..0b833d7ec 100644 --- a/backend/services/src/analytics-api/handler.ts +++ b/backend/services/src/analytics-api/handler.ts @@ -2,8 +2,7 @@ import { Handler, Context } from "aws-lambda"; import { Server } from "http"; import { proxy } from "aws-serverless-express"; -import { bootstrapServer } from "../shared/server"; -import { AnalyticsAPIModule } from "./analytics.api.module"; +import { AnalyticsAPIModule, bootstrapServer } from "carbon-services-lib"; let cachedServer: Server; diff --git a/backend/services/src/analytics-api/programme.controller.ts b/backend/services/src/analytics-api/programme.controller.ts deleted file mode 100644 index f9b402e61..000000000 --- a/backend/services/src/analytics-api/programme.controller.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - Controller, - Get, - Logger, - Query, - UseGuards, - Request, - Post, - Body, -} from "@nestjs/common"; -import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; -import { StatList } from "../shared/dto/stat.list.dto"; -import { ApiKeyJwtAuthGuard } from "../shared/auth/guards/api-jwt-key.guard"; -import { Action } from "../shared/casl/action.enum"; -import { PoliciesGuardEx } from "../shared/casl/policy.guard"; -import { AnalyticsAPIService } from "./analytics.api.service"; -import { Stat } from "../shared/dto/stat.dto"; -import { ChartStatList } from "../shared/dto/chartStats.list.dto"; -import { Programme } from "../shared/entities/programme.entity"; -import { AggregateAPIService } from "./aggregate.api.service"; - -@ApiTags("Programme") -@ApiBearerAuth() -@Controller("programme") -export class ProgrammeController { - constructor( - private analyticsService: AnalyticsAPIService, - private aggService: AggregateAPIService, - private readonly logger: Logger - ) {} - - @ApiBearerAuth() - @UseGuards( - ApiKeyJwtAuthGuard, - PoliciesGuardEx(true, Action.Read, Stat, true, true) - ) - // @UseGuards(JwtAuthGuard, PoliciesGuardEx(true, Action.Read, User, true)) - @Post("dashboard") - async programmesStaticDetails(@Body() query: StatList, @Request() req) { - const companyId = - req?.user?.companyId !== null ? req?.user?.companyId : null; - console.log("user ---- > ", req?.user); - return this.analyticsService.programmesStaticDetails( - req.abilityCondition, - query, - companyId - ); - } - - @ApiBearerAuth() - @UseGuards( - ApiKeyJwtAuthGuard, - PoliciesGuardEx(true, Action.Read, Stat, true, true) - ) - // @UseGuards(JwtAuthGuard, PoliciesGuardEx(true, Action.Read, User, true)) - @Post("dashboardCharts") - async programmesStaticChartDetails( - @Body() query: ChartStatList, - @Request() req - ) { - const companyId = - req?.user?.companyId !== null ? req?.user?.companyId : null; - return this.analyticsService.programmesStaticChartsDetails( - req.abilityCondition, - query, - companyId - ); - } - - @ApiBearerAuth() - @UseGuards( - ApiKeyJwtAuthGuard, - PoliciesGuardEx(true, Action.Read, Stat, true, true) - ) - @Post("agg") - async aggQueries( - @Body() query: StatList, - @Request() req - ) { - const companyId = - req?.user?.companyId !== null ? req?.user?.companyId : null; - return this.aggService.getAggregateQuery( - req.abilityCondition, - query, - companyId, - req.user?.companyRole - ); - } -} diff --git a/backend/services/src/async-operations-handler/async-operations-database-handler.service.ts b/backend/services/src/async-operations-handler/async-operations-database-handler.service.ts deleted file mode 100644 index 8b7b4bac4..000000000 --- a/backend/services/src/async-operations-handler/async-operations-database-handler.service.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { AsyncActionEntity } from "src/shared/entities/async.action.entity"; -import { Counter } from "src/shared/entities/counter.entity"; -import { CounterType } from "src/shared/util/counter.type.enum"; -import { Repository } from "typeorm"; -import { AsyncOperationsHandlerInterface } from "./async-operations-handler-interface.service"; -import { AsyncOperationsHandlerService } from "./async-operations-handler.service"; - -@Injectable() -export class AsyncOperationsDatabaseHandlerService - implements AsyncOperationsHandlerInterface -{ - constructor( - private logger: Logger, - @InjectRepository(Counter) private counterRepo: Repository, - @InjectRepository(AsyncActionEntity) - private asyncActionRepo: Repository, - private asyncOperationsHandlerService: AsyncOperationsHandlerService - ) {} - - async asyncHandler(event: any): Promise { - this.logger.log("database asyncHandler started", JSON.stringify(event)); - - const seqObj = await this.counterRepo.findOneBy({ - id: CounterType.ASYNC_OPERATIONS, - }); - let lastSeq = 0; - if (seqObj) { - lastSeq = seqObj.counter; - } - - setInterval(async () => { - const asyncPromises = []; - - const notExecutedActions = await this.asyncActionRepo - .createQueryBuilder("asyncAction") - .where("asyncAction.actionId > :lastExecuted", { - lastExecuted: lastSeq, - }) - .select(['"actionId"', '"actionType"', '"actionProps"']) - .getRawMany(); - - if(notExecutedActions.length === 0) - return; - - const startedSeq = lastSeq; - notExecutedActions.forEach((action: any) => { - console.log('Processing action', action.actionId) - asyncPromises.push( - this.asyncOperationsHandlerService.handler( - action.actionType, - JSON.parse(action.actionProps) - ) - ); - lastSeq = action.actionId; - }); - - try { - await Promise.all(asyncPromises); - await this.counterRepo.save({ - id: CounterType.ASYNC_OPERATIONS, - counter: lastSeq, - }); - } catch (exception) { - this.logger.log("database asyncHandler failed", exception); - lastSeq = startedSeq; - } - }, 5000); - } -} diff --git a/backend/services/src/async-operations-handler/async-operations-handler-interface.service.ts b/backend/services/src/async-operations-handler/async-operations-handler-interface.service.ts deleted file mode 100644 index 70994fe20..000000000 --- a/backend/services/src/async-operations-handler/async-operations-handler-interface.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable } from "@nestjs/common"; - -@Injectable() -export abstract class AsyncOperationsHandlerInterface { - abstract asyncHandler(event): Promise; -} diff --git a/backend/services/src/async-operations-handler/async-operations-handler.service.ts b/backend/services/src/async-operations-handler/async-operations-handler.service.ts deleted file mode 100644 index ca1293acd..000000000 --- a/backend/services/src/async-operations-handler/async-operations-handler.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { RegistryClientService } from "../shared/registry-client/registry-client.service"; -import { AsyncActionType } from "../shared/enum/async.action.type.enum"; -import { EmailService } from "../shared/email/email.service"; -import { Injectable, Logger } from "@nestjs/common"; - -@Injectable() -export class AsyncOperationsHandlerService { - constructor( - private emailService: EmailService, - private registryClient: RegistryClientService, - private logger: Logger - ) {} - - async handler(actionType: any, dataObject: any) { - - this.logger.log("AsyncOperationsHandlerService started", actionType.toString()); - if (actionType) { - switch (actionType.toString()) { - case AsyncActionType.Email.toString(): - return await this.emailService.sendEmail(dataObject); - case AsyncActionType.RegistryCompanyCreate.toString(): - return await this.registryClient.createCompany(dataObject); - case AsyncActionType.AuthProgramme.toString(): - return await this.registryClient.authProgramme(dataObject); - case AsyncActionType.IssueCredit.toString(): - return await this.registryClient.issueCredit(dataObject); - case AsyncActionType.RejectProgramme.toString(): - return await this.registryClient.rejectProgramme(dataObject); - } - } - } -} diff --git a/backend/services/src/async-operations-handler/async-operations-queue-handler.service.ts b/backend/services/src/async-operations-handler/async-operations-queue-handler.service.ts deleted file mode 100644 index c950367a6..000000000 --- a/backend/services/src/async-operations-handler/async-operations-queue-handler.service.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { AsyncOperationsHandlerInterface } from "./async-operations-handler-interface.service"; -import { SQSEvent } from "aws-lambda"; -import { AsyncOperationsHandlerService } from "./async-operations-handler.service"; -import { AsyncActionType } from "../shared/enum/async.action.type.enum"; - -type Response = { batchItemFailures: { itemIdentifier: string }[] }; - -@Injectable() -export class AsyncOperationsQueueHandlerService - implements AsyncOperationsHandlerInterface -{ - constructor( - private asyncOperationsHandlerService: AsyncOperationsHandlerService, - private logger: Logger - ) {} - - async asyncHandler(event: SQSEvent): Promise { - this.logger.log("Queue asyncHandler started"); - const response: Response = { batchItemFailures: [] }; - - for (const record of event.Records) { - const actionType = record.messageAttributes?.actionType?.stringValue; - try { - - await this.asyncOperationsHandlerService.handler( - actionType, - JSON.parse(record.body) - ); - } catch (exception) { - this.logger.log("queue asyncHandler failed", exception); - if (actionType?.toString() === AsyncActionType.Email.toString()) { - response.batchItemFailures.push({ itemIdentifier: record.messageId }); - } else { - throw exception; - } - } - } - return response; - } -} diff --git a/backend/services/src/async-operations-handler/async-operations.module.ts b/backend/services/src/async-operations-handler/async-operations.module.ts deleted file mode 100644 index 685cdb74a..000000000 --- a/backend/services/src/async-operations-handler/async-operations.module.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Logger, Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import { EmailModule } from "src/shared/email/email.module"; -import { AsyncActionEntity } from "src/shared/entities/async.action.entity"; -import { Counter } from "src/shared/entities/counter.entity"; -import configuration from "../shared/configuration"; -import { AsyncOperationType } from "../shared/enum/async.operation.type.enum"; -import { TypeOrmConfigService } from "../shared/typeorm.config.service"; -import { AsyncOperationsDatabaseHandlerService } from "./async-operations-database-handler.service"; -import { AsyncOperationsHandlerInterface } from "./async-operations-handler-interface.service"; -import { AsyncOperationsQueueHandlerService } from "./async-operations-queue-handler.service"; -import { RegistryClientModule } from "../shared/registry-client/registry-client.module"; -import { AsyncOperationsHandlerService } from "./async-operations-handler.service"; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - }), - TypeOrmModule.forFeature([AsyncActionEntity, Counter]), - RegistryClientModule, - EmailModule, - ], - providers: [ - { - provide: AsyncOperationsHandlerInterface, - useClass: - process.env.ASYNC_OPERATIONS_TYPE === AsyncOperationType.Queue - ? AsyncOperationsQueueHandlerService - : AsyncOperationsDatabaseHandlerService, - }, - Logger, - AsyncOperationsHandlerService, - ], -}) -export class AsyncOperationsModule {} diff --git a/backend/services/src/async-operations-handler/handler.ts b/backend/services/src/async-operations-handler/handler.ts index 5d4e36896..c4a7f17e5 100644 --- a/backend/services/src/async-operations-handler/handler.ts +++ b/backend/services/src/async-operations-handler/handler.ts @@ -1,14 +1,12 @@ import { NestFactory } from "@nestjs/core"; import { Handler, Context } from "aws-lambda"; -import { getLogger } from "src/shared/server"; -import { AsyncOperationsHandlerInterface } from "./async-operations-handler-interface.service"; -import { AsyncOperationsModule } from "./async-operations.module"; +import { AsyncOperationsHandlerInterface, AsyncOperationsModuleMain, getLogger } from "carbon-services-lib"; export const handler: Handler = async (event: any, context: Context) => { const app = await NestFactory.createApplicationContext( - AsyncOperationsModule, + AsyncOperationsModuleMain, { - logger: getLogger(AsyncOperationsModule), + logger: getLogger(AsyncOperationsModuleMain), } ); diff --git a/backend/services/src/data-importer/data-importer.module.ts b/backend/services/src/data-importer/data-importer.module.ts deleted file mode 100644 index 3f799c121..000000000 --- a/backend/services/src/data-importer/data-importer.module.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Logger, Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { Programme } from '../shared/entities/programme.entity'; -import configuration from '../shared/configuration'; -import { TypeOrmConfigService } from '../shared/typeorm.config.service'; -import { LedgerType } from '../shared/enum/ledger.type'; -import { ProgrammeModule } from '../shared/programme/programme.module'; -import { DataImporterService } from './data-importer.service'; -import { CompanyModule } from '../shared/company/company.module'; -import { UserModule } from '../shared/user/user.module'; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`] - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - }), - TypeOrmModule.forFeature([Programme]), - ProgrammeModule, - CompanyModule, - UserModule - ], - providers: [Logger, DataImporterService] -}) -export class DataImporterModule {} diff --git a/backend/services/src/data-importer/data-importer.service.spec.ts b/backend/services/src/data-importer/data-importer.service.spec.ts deleted file mode 100644 index 09feb7714..000000000 --- a/backend/services/src/data-importer/data-importer.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { DataImporterService } from './data-importer.service'; - -describe('DataImporterService', () => { - let service: DataImporterService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [DataImporterService], - }).compile(); - - service = module.get(DataImporterService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/data-importer/data-importer.service.ts b/backend/services/src/data-importer/data-importer.service.ts deleted file mode 100644 index 295ad7ff0..000000000 --- a/backend/services/src/data-importer/data-importer.service.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { ProgrammeService } from "../shared/programme/programme.service"; -import { CompanyService } from "../shared/company/company.service"; -import { ImporterInterface } from "./importer.interface"; -import { ITMOSystemImporter } from "./importers/itmo-system.service"; -import { UserService } from "../shared/user/user.service"; - -@Injectable() -export class DataImporterService { - constructor( - private logger: Logger, - private configService: ConfigService, - private companyService: CompanyService, - private userService: UserService, - private programmeService: ProgrammeService - ) {} - - private getImporter(type: string): ImporterInterface { - switch(type) { - case 'ITMO_SYSTEM': - return new ITMOSystemImporter(this.logger, this.configService, this.companyService, this.userService, this.programmeService); - } - return null; - } - - async importData(event): Promise { - this.logger.log("Event received", JSON.stringify(event)); - if (event.importTypes) { - const types = event.importTypes.split(','); - for (const type of types) { - await this.getImporter(type)?.start(type); - } - } - } -} diff --git a/backend/services/src/data-importer/handler.ts b/backend/services/src/data-importer/handler.ts index 87415d85c..c6b037434 100644 --- a/backend/services/src/data-importer/handler.ts +++ b/backend/services/src/data-importer/handler.ts @@ -2,9 +2,7 @@ import { Handler, Context } from 'aws-lambda'; import { Server } from 'http'; import { NestFactory } from '@nestjs/core'; -import { getLogger } from '../shared/server'; -import { DataImporterModule } from './data-importer.module'; -import { DataImporterService } from './data-importer.service'; +import { DataImporterModule, getLogger, DataImporterService } from 'carbon-services-lib'; export const handler: Handler = async (event: any, context: Context) => { const app = await NestFactory.createApplicationContext(DataImporterModule, { diff --git a/backend/services/src/data-importer/importer.interface.ts b/backend/services/src/data-importer/importer.interface.ts deleted file mode 100644 index 6a878f154..000000000 --- a/backend/services/src/data-importer/importer.interface.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; - -@Injectable() -export abstract class ImporterInterface { - abstract start(type: string): Promise; -} diff --git a/backend/services/src/data-importer/importers/itmo-system.service.ts b/backend/services/src/data-importer/importers/itmo-system.service.ts deleted file mode 100644 index 22c02b57b..000000000 --- a/backend/services/src/data-importer/importers/itmo-system.service.ts +++ /dev/null @@ -1,240 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import axios, { AxiosResponse } from "axios"; -import { ProgrammeService } from "../../shared/programme/programme.service"; -import { CompanyService } from "../../shared/company/company.service"; -import { ImporterInterface } from "../importer.interface"; -import { ProgrammeStage } from "../../shared/enum/programme-status.enum"; -import { CompanyRole } from "../../shared/enum/company.role.enum"; -import { SectoralScope } from "@undp/serial-number-gen"; -import { Sector } from "../../shared/enum/sector.enum"; -import { TypeOfMitigation } from "../../shared/enum/typeofmitigation.enum"; -import { UserService } from "../../shared/user/user.service"; -import { Role } from "../../shared/casl/role.enum"; -import { GHGs } from "../../shared/enum/ghgs.enum"; -import { Programme } from "../../shared/entities/programme.entity"; - -function flatten(ary) { - if (!ary) { - return ary; - } - return ary.reduce(function(a, b) { - if (Array.isArray(b)) { - return a.concat(flatten(b)) - } - return a.concat(b) - }, []) -} - -@Injectable() -export class ITMOSystemImporter implements ImporterInterface { - private endpoint; - private authToken; - private apiKey; - - constructor( - private logger: Logger, - private configService: ConfigService, - private companyService: CompanyService, - private userService: UserService, - private programmeService: ProgrammeService - ) { - this.endpoint = this.configService.get("ITMOSystem.endpoint"); - this.apiKey = this.configService.get("ITMOSystem.apiKey"); - } - - private async login(): Promise { - const resp = await axios.post( - this.endpoint + "auth/login", - { - email: this.configService.get("ITMOSystem.email"), - password: this.configService.get("ITMOSystem.password"), - }, - { - headers: { - "x-api-key": this.apiKey, - "Content-Type": "application/json", - }, - } - ); - if (resp.data && resp.data.statusCode == 200) { - return resp.headers["x-token-id"]; - } else { - this.logger.log(`Login failed ${JSON.stringify(resp)}`); - throw new Error("Failed to login to ITMO system. " + resp); - } - } - - private async sendGetReq(path: string): Promise { - return await axios.get(this.endpoint + path, { - headers: { - Authorization: this.authToken, - "x-api-key": this.apiKey, - "Content-Type": "application/json", - }, - }); - } - - private getSector( - itmoSector: string - ): [Sector, SectoralScope, TypeOfMitigation] { - switch (itmoSector) { - case "energy-distribution": - return [ - Sector.Energy, - SectoralScope.EnergyDistribution, - TypeOfMitigation.ENERGY_DISTRIBUTION, - ]; - case "agriculture": - return [ - Sector.Agriculture, - SectoralScope.Agriculture, - TypeOfMitigation.AGRICULTURE - ] - case "energy-industries": - return [ - Sector.Energy, - SectoralScope.EnergyIndustry, - TypeOfMitigation.EE_INDUSTRY - ] - default: - return [ - Sector.Other, - SectoralScope.EnergyIndustry, - TypeOfMitigation.EE_INDUSTRY, - ]; - } - } - - async start(type: string): Promise { - this.authToken = await this.login(); - const projects = await this.sendGetReq("me/projects"); - - const rootUser = await this.userService.getRoot(); - if (!rootUser) { - throw new Error(`Root user does not exist in the system`); - } - rootUser['companyName'] = (await this.companyService.findGovByCountry(this.configService.get("systemCountry")))?.name; - if (!projects || !projects.data || !projects.data.data) { - this.logger.log(`No projects received ${projects}`); - throw new Error(`No projects received ${projects}`); - } else { - for (const project of projects.data.data) { - const projectId = project.id; - - let programmeEvents = await this.programmeService.getProgrammeEventsByExternalId(projectId); - if (programmeEvents && programmeEvents.length > 0 && programmeEvents[programmeEvents.length - 1].data.currentStage == ProgrammeStage.REJECTED) { - continue; - } - - const projectData = await this.sendGetReq("me/projects/" + projectId); - const projectDetails = projectData?.data; - if (projectDetails?.steps) { - for (const step of projectDetails?.steps) { - if ( - (!programmeEvents || programmeEvents.length <= 0) && - step.name === - "ITMO-Design Document (DD) & Validation Report / Upload on National Public Registry" - ) { - const taxId = project.company; - const company = await this.companyService.findByTaxId(taxId); - if (!company) { - - const email = `nce.digital+${project.company}@undp.org`.replace(' ', ''); - await this.userService.create( - { - email: email, - role: Role.Admin, - name: project.company, - phoneNo: "00", - company: { - taxId: taxId, - companyId: undefined, - name: project.company, - email: email, - phoneNo: "00", - website: undefined, - address: this.configService.get("systemCountryName"), - logo: undefined, - country: this.configService.get("systemCountry"), - companyRole: CompanyRole.PROGRAMME_DEVELOPER, - nameOfMinister: undefined, - sectoralScope: undefined, - createdTime: undefined, - }, - password: undefined, - companyId: undefined, - }, - undefined, - CompanyRole.GOVERNMENT - ); - } - - const [sector, scope, mitigation] = this.getSector( - projectDetails.sector - ); - - const pr = { - title: projectDetails.name, - externalId: projectDetails.id, - sectoralScope: scope, - sector: sector, - typeOfMitigation: mitigation, - startTime: parseInt( - ( - new Date("2023-03-06T14:02:42.840Z").getTime() / 1000 - ).toFixed() - ), - endTime: parseInt( - ( - new Date("2023-03-06T14:02:42.840Z").getTime() / 1000 + - 87660 * 60 * 60 - ).toFixed() - ), - proponentTaxVatId: [taxId], - proponentPercentage: [100], - creditUnit: this.configService.get("defaultCreditUnit"), - programmeProperties: { - geographicalLocation: [projectDetails.country.name], - greenHouseGasses: [GHGs.CO2], - }, - creditEst: 100, - }; - - if (step.files && step.files.length > 0) { - pr.programmeProperties["programmeMaterials"] = step.files; - // pr.programmeProperties["projectMaterial"] = step.files; - } - - await this.programmeService.create(pr); - } else if ( - programmeEvents && programmeEvents.length > 0 && - programmeEvents[programmeEvents.length - 1].data.currentStage === ProgrammeStage.AUTHORISED && - !programmeEvents.map(e => e.data.txRef).join(' ').includes('ITMO system issue') - ) { - const flat = flatten(step.iterations) - - const list = flatten(flat?.map((e) => { - return e?.contents?.map((x) => x.name); - })) - - this.logger.log(`Issue list values: ${list}`) - if (list && list.includes("Upload Final Monitoring Report")) { - const resp = await this.programmeService.issueProgrammeCredit( - { - programmeId: programmeEvents[programmeEvents.length - 1].data.programmeId, - issueAmount: 10, - comment: "ITMO system issue", - }, - rootUser - ); - - this.logger.log(`Issue credit response ${resp}`) - } - } - } - } - } - } - } -} diff --git a/backend/services/src/ledger-replicator/handler.ts b/backend/services/src/ledger-replicator/handler.ts index c01183a8c..5ab60d666 100644 --- a/backend/services/src/ledger-replicator/handler.ts +++ b/backend/services/src/ledger-replicator/handler.ts @@ -2,9 +2,7 @@ import { Handler, Context } from 'aws-lambda'; import { Server } from 'http'; import { NestFactory } from '@nestjs/core'; -import { LedgerReplicatorModule } from './ledger-replicator.module'; -import { getLogger } from '../shared/server'; -import { LedgerReplicatorInterface } from './replicator-interface.service'; +import { LedgerReplicatorModule, getLogger, LedgerReplicatorInterface } from 'carbon-services-lib'; export const handler: Handler = async (event: any, context: Context) => { const app = await NestFactory.createApplicationContext(LedgerReplicatorModule, { diff --git a/backend/services/src/ledger-replicator/ledger-replicator.module.ts b/backend/services/src/ledger-replicator/ledger-replicator.module.ts deleted file mode 100644 index 6481eeee9..000000000 --- a/backend/services/src/ledger-replicator/ledger-replicator.module.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Logger, Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { Programme } from '../shared/entities/programme.entity'; -import configuration from '../shared/configuration'; -import { TypeOrmConfigService } from '../shared/typeorm.config.service'; -import { QLDBKinesisReplicatorService } from './qldb-kinesis-replicator.service'; -import { Company } from '../shared/entities/company.entity'; -import { LedgerReplicatorInterface } from './replicator-interface.service'; -import { PgSqlReplicatorService } from './pgsql-replicator.service'; -import { ProcessEventService } from './process.event.service'; -import { Counter } from '../shared/entities/counter.entity'; -import { LocationModule } from '../shared/location/location.module'; -import { LedgerType } from '../shared/enum/ledger.type'; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`] - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - }), - TypeOrmModule.forFeature([Programme, Company, Counter]), - LocationModule - ], - providers: [{ - provide: LedgerReplicatorInterface, - useClass: - process.env.LEDGER_TYPE === LedgerType.QLDB - ? QLDBKinesisReplicatorService - : PgSqlReplicatorService, - }, Logger, ProcessEventService] -}) -export class LedgerReplicatorModule {} diff --git a/backend/services/src/ledger-replicator/ledger-replicator.service.spec.ts b/backend/services/src/ledger-replicator/ledger-replicator.service.spec.ts deleted file mode 100644 index dc49ee7a0..000000000 --- a/backend/services/src/ledger-replicator/ledger-replicator.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { LedgerReplicatorService } from './qldb-kinesis-replicator.service'; - -describe('LedgerReplicatorService', () => { - let service: LedgerReplicatorService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [LedgerReplicatorService], - }).compile(); - - service = module.get(LedgerReplicatorService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/ledger-replicator/pgsql-replicator.service.ts b/backend/services/src/ledger-replicator/pgsql-replicator.service.ts deleted file mode 100644 index f4ab22154..000000000 --- a/backend/services/src/ledger-replicator/pgsql-replicator.service.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Repository } from "typeorm"; -import { ConfigService } from "@nestjs/config"; -import { LedgerReplicatorInterface } from "./replicator-interface.service"; -import { Counter } from "../shared/entities/counter.entity"; -import { CounterType } from "../shared/util/counter.type.enum"; -import { Pool } from "pg"; -import { Programme } from "../shared/entities/programme.entity"; -import { plainToClass } from "class-transformer"; -import { ProcessEventService } from "./process.event.service"; -import { CreditOverall } from "../shared/entities/credit.overall.entity"; - - -@Injectable() -export class PgSqlReplicatorService implements LedgerReplicatorInterface { - constructor( - private logger: Logger, - @InjectRepository(Counter) private counterRepo: Repository, - private configService: ConfigService, - private eventProcessor: ProcessEventService, - ) {} - - async replicate(event): Promise { - this.logger.log("Start received", JSON.stringify(event)); - - setInterval(async () => { - const seqObj = await this.counterRepo.findOneBy({ - id: CounterType.REPLICATE_SEQ, - }); - - let lastSeq = 0; - if (seqObj) { - lastSeq = seqObj.counter; - } - - const tableName = this.configService.get("ledger.table"); - const companyTableName = this.configService.get( - "ledger.companyTable" - ); - - let dbc = this.configService.get("database"); - - const config = { - host: dbc['host'], - port: dbc['port'], - user: dbc['username'], - password: dbc['password'], - database: dbc["database"] + "Events" - } - const dbCon = new Pool(config); - // const client = await dbCon.connect(); - const sql = `select data, hash from ${tableName} where hash > $1 order by hash` - const results = await dbCon.query( - sql, - [lastSeq] - ); - - this.logger.log(`Query for new data ${sql} ${lastSeq}`) - this.logger.log(`Periodical replicate check - last seq:${lastSeq} new events: ${results?.rows?.length}`); - - if (results) { - let newSeq = 0; - for (const row of results.rows) { - const data = row.data; - console.log('Data', data) - const programme: Programme = plainToClass( - Programme, - JSON.parse(JSON.stringify(data)) - ); - await this.eventProcessor.process(programme, undefined, 0, 0) - newSeq = row.hash - } - if (newSeq != 0) { - await this.counterRepo.save({ id: CounterType.REPLICATE_SEQ, counter: newSeq}) - } - } - - const seqObjComp = await this.counterRepo.findOneBy({ - id: CounterType.REPLICATE_SEQ_COMP, - }); - - let lastSeqComp = 0; - if (seqObjComp) { - lastSeqComp = seqObjComp.counter; - } - - const resultsCompany = await dbCon.query( - `select * from ${companyTableName} where hash > $1 order by hash`, - [lastSeqComp] - ); - - if (resultsCompany) { - let newSeq = 0; - for (const row of resultsCompany.rows) { - const data = row.data; - const creditOverall: CreditOverall = plainToClass( - CreditOverall, - JSON.parse(JSON.stringify(data)) - ); - newSeq = row.hash - await this.eventProcessor.process(undefined, creditOverall, row.hash, new Date(row.meta.txTime).getTime()) - } - if (newSeq != 0) { - await this.counterRepo.save({ id: CounterType.REPLICATE_SEQ_COMP, counter: newSeq}) - } - } - }, 1000); - } -} diff --git a/backend/services/src/ledger-replicator/process.event.service.ts b/backend/services/src/ledger-replicator/process.event.service.ts deleted file mode 100644 index 5ffcc7ff5..000000000 --- a/backend/services/src/ledger-replicator/process.event.service.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { TxType } from "../shared/enum/txtype.enum"; -import { Repository } from "typeorm"; -import { Company } from "../shared/entities/company.entity"; -import { Programme } from "../shared/entities/programme.entity"; -import { CreditOverall } from "../shared/entities/credit.overall.entity"; -import { LocationInterface } from "../shared/location/location.interface"; -import { CompanyRole } from "src/shared/enum/company.role.enum"; -import { ProgrammeStage } from "src/shared/enum/programme-status.enum"; - -@Injectable() -export class ProcessEventService { - constructor( - private logger: Logger, - @InjectRepository(Programme) private programmeRepo: Repository, - @InjectRepository(Company) private companyRepo: Repository, - private locationService: LocationInterface, - ) {} - - async process(programme: Programme, overall: CreditOverall, version: number, txTime: number): Promise { - this.logger.log(`Processing message ${programme} ${overall} ${version} ${txTime}`) - if (programme) { - const previousProgramme = await this.programmeRepo.findOneBy({ - programmeId: programme.programmeId, - }); - - if ( - previousProgramme == null || - programme.txTime == undefined || - previousProgramme.txTime == undefined || - previousProgramme.txTime <= programme.txTime - ) { - try { - let address: any[] = []; - if (programme && programme.programmeProperties) { - if (programme.txType === TxType.CREATE) { - const programmeProperties = programme.programmeProperties; - if (programmeProperties.geographicalLocation) { - for ( - let index = 0; - index < programmeProperties.geographicalLocation.length; - index++ - ) { - address.push(programmeProperties.geographicalLocation[index]); - } - } - await this.locationService.getCoordinatesForRegion([...address]).then( - (response: any) => { - console.log( - "response from forwardGeoCoding function -> ", - response - ); - programme.geographicalLocationCordintes = [...response]; - } - ); - } else if ( - programme.txType === TxType.CERTIFY || - programme.txType === TxType.REVOKE - ) { - programme.certifiedTime = programme.txTime; - } else if (programme.txType === TxType.AUTH) { - programme.authTime = programme.txTime; - } else if (programme.txType === TxType.OWNERSHIP_UPDATE && programme.currentStage === ProgrammeStage.AUTHORISED) { - const updatedOwnerId = - programme.companyId[programme.companyId.length - 1]; - const company = await this.companyRepo.findOneBy({ - companyId: updatedOwnerId, - }); - const response = await this.companyRepo - .update( - { - companyId: updatedOwnerId, - }, - { - programmeCount: - company.companyRole === CompanyRole.GOVERNMENT - ? null - : Number(company.programmeCount) + 1, - } - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - } - - if ( - [TxType.AUTH, TxType.REJECT, TxType.CREATE].includes( - programme.txType - ) - ) { - programme.statusUpdateTime = programme.txTime; - } - if ( - [TxType.ISSUE, TxType.RETIRE, TxType.TRANSFER, TxType.AUTH, TxType.FREEZE, TxType.UNFREEZE].includes( - programme.txType - ) - ) { - programme.creditUpdateTime = programme.txTime; - } - } - } catch (error) { - console.log( - "Getting cordinates with forward geocoding failed -> ", - error - ); - } finally { - programme.updatedAt = new Date(programme.txTime); - programme.createdAt = new Date(programme.createdTime); - const columns = - this.programmeRepo.manager.connection.getMetadata( - "Programme" - ).columns; - // const columnNames = columns - // .filter(function (item) { - // return ( - // item.propertyName !== "programmeId" && - // item.propertyName !== "geographicalLocationCordintes" - // ); - // }) - // .map((e) => e.propertyName); - const columnNames = columns - .filter(function (item) { - return programme[item.propertyName] != undefined; - }) - .map((e) => e.propertyName); - - this.logger.debug(`${columnNames} ${JSON.stringify(programme)}`); - return await this.programmeRepo - .createQueryBuilder() - .insert() - .values(programme) - .orUpdate(columnNames, ["programmeId"]) - .execute(); - } - } else { - this.logger.error( - `Skipping the programme due to old record ${JSON.stringify( - programme - )} ${previousProgramme}` - ); - } - } - - if (overall) { - const parts = overall.txId.split("#"); - const companyId = parseInt(parts[0]); - let account; - if (parts.length > 1) { - account = parts[1]; - } - const company = await this.companyRepo.findOneBy({ - companyId: companyId, - }); - - if (company) { - // const meta = JSON.parse( - // JSON.stringify( - // ionRecord.get("payload").get("revision").get("metadata") - // ) - // ); - - // if (company && meta["version"]) { - // if (company.lastUpdateVersion >= parseInt(meta["version"])) { - // return; - // } - // } - - let updateObj; - if (account) { - if ( - company.secondaryAccountBalance && - company.secondaryAccountBalance[account] - ) { - company.secondaryAccountBalance[account]["total"] = overall.credit; - company.secondaryAccountBalance[account]["count"] += 1; - } else { - company.secondaryAccountBalance = { - account: { total: overall.credit, count: 1 }, - }; - } - - updateObj = { - secondaryAccountBalance: company.secondaryAccountBalance, - lastUpdateVersion: version, - }; - } else { - updateObj = { - creditBalance: overall.credit, - programmeCount: - company.companyRole === CompanyRole.GOVERNMENT - ? null - : Number(company.programmeCount) + - (overall.txType == TxType.AUTH ? 1 : 0), - lastUpdateVersion: version, - creditTxTime: [ - TxType.ISSUE, - TxType.TRANSFER, - TxType.RETIRE, - TxType.FREEZE, - TxType.UNFREEZE, - ].includes(overall.txType) - ? txTime - : undefined, - }; - } - - const response = await this.companyRepo - .update( - { - companyId: parseInt(overall.txId), - }, - updateObj - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - } else { - this.logger.error( - "Unexpected programme. Company does not found", - companyId - ); - } - } - } -} diff --git a/backend/services/src/ledger-replicator/qldb-kinesis-replicator.service.ts b/backend/services/src/ledger-replicator/qldb-kinesis-replicator.service.ts deleted file mode 100644 index 1ab102928..000000000 --- a/backend/services/src/ledger-replicator/qldb-kinesis-replicator.service.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import axios from "axios"; -import { Programme } from "../shared/entities/programme.entity"; -import { dom } from "ion-js"; -import { plainToClass } from "class-transformer"; -import { ConfigService } from "@nestjs/config"; -import { CreditOverall } from "../shared/entities/credit.overall.entity"; -import { LedgerReplicatorInterface } from "./replicator-interface.service"; -import { ProcessEventService } from "./process.event.service"; - -const computeChecksums = true; -const REVISION_DETAILS = "REVISION_DETAILS"; -const deagg = require("aws-kinesis-agg"); - -@Injectable() -export class QLDBKinesisReplicatorService implements LedgerReplicatorInterface{ - constructor( - private logger: Logger, - private eventProcessor: ProcessEventService, - private configService: ConfigService - ) {} - - async processRecords(records) { - return await Promise.all( - records.map(async (record) => { - // Kinesis data is base64 encoded so decode here - const payload = Buffer.from(record.data, "base64"); - - // payload is the actual ion binary record published by QLDB to the stream - const ionRecord = dom.load(payload); - // Only process records where the record type is REVISION_DETAILS - if (ionRecord.get("recordType").stringValue() !== REVISION_DETAILS) { - this.logger.log( - `Skipping record of type ${ionRecord - .get("recordType") - .stringValue()}` - ); - } else { - this.logger.log("ION Record", JSON.stringify(ionRecord)); - const tableName = ionRecord - .get("payload") - .get("tableInfo") - .get("tableName"); - if (tableName == this.configService.get("ledger.table")) { - const payload = ionRecord - .get("payload") - .get("revision") - .get("data"); - - const programme: Programme = plainToClass( - Programme, - JSON.parse(JSON.stringify(payload)) - ); - await this.eventProcessor.process(programme, undefined, 0, 0) - } else if ( - tableName == this.configService.get("ledger.companyTable") - ) { - - const meta = JSON.parse( - JSON.stringify( - ionRecord.get("payload").get("revision").get("metadata") - ) - ); - - const payload = ionRecord - .get("payload") - .get("revision") - .get("data"); - - const overall: CreditOverall = plainToClass( - CreditOverall, - JSON.parse(JSON.stringify(payload)) - ); - - await this.eventProcessor.process(undefined, overall, parseInt(meta["version"]), new Date(meta.txTime).getTime()) - } - } - }) - ); - } - - async promiseDeaggregate(record) { - return new Promise((resolve, reject) => { - deagg.deaggregateSync(record, computeChecksums, (err, responseObject) => { - if (err) { - //handle/report error - return reject(err); - } - return resolve(responseObject); - }); - }); - } - - async replicate(event): Promise { - this.logger.log("Event received", JSON.stringify(event)); - return await Promise.all( - event.Records.map(async (kinesisRecord) => { - const records = await this.promiseDeaggregate(kinesisRecord.kinesis); - return await this.processRecords(records); - }) - ); - } -} diff --git a/backend/services/src/ledger-replicator/replicator-interface.service.ts b/backend/services/src/ledger-replicator/replicator-interface.service.ts deleted file mode 100644 index 83c41a73a..000000000 --- a/backend/services/src/ledger-replicator/replicator-interface.service.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; - -@Injectable() -export abstract class LedgerReplicatorInterface { - abstract replicate(event): Promise; -} diff --git a/backend/services/src/main.ts b/backend/services/src/main.ts index 525287aa9..b046633b2 100644 --- a/backend/services/src/main.ts +++ b/backend/services/src/main.ts @@ -1,11 +1,10 @@ -import { AnalyticsAPIModule } from "./analytics-api/analytics.api.module"; import { handler } from "./ledger-replicator/handler"; import { handler as asyncHandler } from "./async-operations-handler/handler"; import { handler as importHandler } from "./data-importer/handler"; import * as setupHandler from "./setup/handler"; import { NationalAPIModule } from "./national-api/national.api.module"; -import { buildNestApp } from "./shared/server"; import { join } from "path"; +import { AnalyticsAPIModule, buildNestApp } from "carbon-services-lib"; const fs = require("fs"); async function bootstrap() { @@ -33,7 +32,7 @@ async function bootstrap() { console.log("Module initiated", moduleName); continue; case "data-importer": - await importHandler({ importTypes: "ITMO_SYSTEM" }); + await importHandler({ importTypes: process.env.DATA_IMPORT_TYPES }); console.log("Module initiated", moduleName); continue; default: diff --git a/backend/services/src/national-api/auth.controller.ts b/backend/services/src/national-api/auth.controller.ts index fa7c9acd4..3ff6a1ace 100644 --- a/backend/services/src/national-api/auth.controller.ts +++ b/backend/services/src/national-api/auth.controller.ts @@ -15,14 +15,7 @@ import { HttpStatus, } from "@nestjs/common"; import { ApiTags } from "@nestjs/swagger"; -import { LoginDto } from "../shared/dto/login.dto"; -import { AuthService } from "../shared/auth/auth.service"; -import { JwtAuthGuard } from "../shared/auth/guards/jwt-auth.guard"; -import { LocalAuthGuard } from "../shared/auth/guards/local-auth.guard"; -import { ForgotPasswordDto } from "../shared/dto/forgotPassword.dto"; -import { PasswordResetDto } from "../shared/dto/passwordReset.dto"; -import { PasswordResetService } from "../shared/util/passwordReset.service"; -import { HelperService } from "../shared/util/helpers.service"; +import { AuthService, PasswordResetService, HelperService, LoginDto, ForgotPasswordDto, PasswordResetDto } from "carbon-services-lib"; @ApiTags("Auth") @Controller("auth") diff --git a/backend/services/src/national-api/company.controller.ts b/backend/services/src/national-api/company.controller.ts index 06e7d2526..84cc7f67b 100644 --- a/backend/services/src/national-api/company.controller.ts +++ b/backend/services/src/national-api/company.controller.ts @@ -11,19 +11,8 @@ import { Body, } from "@nestjs/common"; import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; -import { Company } from "../shared/entities/company.entity"; -import { Action } from "../shared/casl/action.enum"; -import { PoliciesGuardEx } from "../shared/casl/policy.guard"; -import { QueryDto } from "../shared/dto/query.dto"; -import { CompanyService } from "../shared/company/company.service"; -import { CaslAbilityFactory } from "../shared/casl/casl-ability.factory"; -import { JwtAuthGuard } from "../shared/auth/guards/jwt-auth.guard"; -import { OrganisationSuspendDto } from "../shared/dto/organisation.suspend.dto"; -import { FindOrganisationQueryDto } from "../shared/dto/find.organisation.dto"; -import { OrganisationUpdateDto } from "../shared/dto/organisation.update.dto"; -import { CountryService } from "../shared/util/country.service"; -import { HelperService } from "../shared/util/helpers.service"; -import { ApiKeyJwtAuthGuard } from "../shared/auth/guards/api-jwt-key.guard"; +import { CompanyService, CountryService, ApiKeyJwtAuthGuard, CaslAbilityFactory, HelperService, JwtAuthGuard, PoliciesGuardEx, Action, Company, QueryDto, OrganisationSuspendDto, FindOrganisationQueryDto, OrganisationUpdateDto } from "carbon-services-lib"; + @ApiTags("Organisation") @ApiBearerAuth() @@ -41,7 +30,7 @@ export class CompanyController { @Post("query") query(@Body() query: QueryDto, @Request() req) { console.log(req.abilityCondition); - return this.companyService.query(query, req.abilityCondition); + return this.companyService.query(query, req.abilityCondition, req.user.companyRole); } @ApiBearerAuth() @@ -103,6 +92,36 @@ export class CompanyController { ); } + @ApiBearerAuth() + @UseGuards(JwtAuthGuard, PoliciesGuardEx(true, Action.Approve, Company)) + @Put("approve") + approve( + @Query("id") companyId: number, + @Body() body: OrganisationSuspendDto, + @Request() req + ) { + return this.companyService.approve( + companyId, + req.abilityCondition + ); + } + + @ApiBearerAuth() + @UseGuards(JwtAuthGuard, PoliciesGuardEx(true, Action.Reject, Company)) + @Put("reject") + reject( + @Query("id") companyId: number, + @Body() body: OrganisationSuspendDto, + @Request() req + ) { + return this.companyService.reject( + companyId, + req.user, + body.remarks, + req.abilityCondition + ); + } + @ApiBearerAuth() @ApiBearerAuth('api_key') @UseGuards(ApiKeyJwtAuthGuard, PoliciesGuardEx(true, Action.Read, Company)) diff --git a/backend/services/src/national-api/handler.ts b/backend/services/src/national-api/handler.ts index 46b9030f3..f8a8c59d1 100644 --- a/backend/services/src/national-api/handler.ts +++ b/backend/services/src/national-api/handler.ts @@ -2,8 +2,8 @@ import { Handler, Context } from 'aws-lambda'; import { Server } from 'http'; import { proxy } from 'aws-serverless-express'; -import { bootstrapServer } from '../shared/server' import { NationalAPIModule } from './national.api.module'; +import { bootstrapServer } from 'carbon-services-lib'; let cachedServer: Server; diff --git a/backend/services/src/national-api/national.api.module.ts b/backend/services/src/national-api/national.api.module.ts index dba16c1e4..ceb158b60 100644 --- a/backend/services/src/national-api/national.api.module.ts +++ b/backend/services/src/national-api/national.api.module.ts @@ -2,27 +2,20 @@ import { Logger, Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { NationalAPIController } from './national.api.controller'; import { NationalAPIService } from './national.api.service'; -import configuration from '../shared/configuration'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { TypeOrmConfigService } from '../shared/typeorm.config.service'; // import { Programme } from './entities/programme.entity'; -import { AuthModule } from '../shared/auth/auth.module'; -import { CaslModule } from '../shared/casl/casl.module'; -import { ProgrammeModule } from '../shared/programme/programme.module'; -import { CompanyModule } from '../shared/company/company.module'; -import { CompanyController } from './company.controller'; -import { UserModule } from '../shared/user/user.module'; import { UserController } from './user.controller'; import { AuthController } from './auth.controller'; import { ProgrammeController } from './programme.controller'; -import { UtilModule } from '../shared/util/util.module'; import { SettingsController } from './settings.controller'; +import { configuration, TypeOrmConfigService, AuthModule, UserModule, CaslModule, ProgrammeModule, CompanyModule, UtilModule } from 'carbon-services-lib'; +import { CompanyController } from './company.controller'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, - load: [configuration], + load: [configuration.default], envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`] }), TypeOrmModule.forRootAsync({ diff --git a/backend/services/src/national-api/programme.controller.ts b/backend/services/src/national-api/programme.controller.ts index 48f30183d..3ad8729bd 100644 --- a/backend/services/src/national-api/programme.controller.ts +++ b/backend/services/src/national-api/programme.controller.ts @@ -1,34 +1,6 @@ import { Body, Controller, Get, Post, Put, Query, UseGuards, Request } from '@nestjs/common'; import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; -import { Programme } from '../shared/entities/programme.entity'; -import { Action } from '../shared/casl/action.enum'; -import { AppAbility } from '../shared/casl/casl-ability.factory'; -import { CheckPolicies } from '../shared/casl/policy.decorator'; -import { PoliciesGuard, PoliciesGuardEx } from '../shared/casl/policy.guard'; -import { ProgrammeDto } from '../shared/dto/programme.dto'; -import { ProgrammeService } from '../shared/programme/programme.service'; -import { QueryDto } from '../shared/dto/query.dto'; -import { ConstantUpdateDto } from '../shared/dto/constants.update.dto'; -import { ProgrammeStage } from '../shared/enum/programme-status.enum'; -import { ProgrammeApprove } from '../shared/dto/programme.approve'; -import { ProgrammeReject } from '../shared/dto/programme.reject'; -import { ProgrammeRetire } from '../shared/dto/programme.retire'; -import { ApiKeyJwtAuthGuard } from '../shared/auth/guards/api-jwt-key.guard'; -import { ProgrammeTransferRequest } from '../shared/dto/programme.transfer.request'; -import { ProgrammeTransfer } from '../shared/entities/programme.transfer'; -import { ProgrammeTransferApprove } from '../shared/dto/programme.transfer.approve'; -import { ProgrammeTransferReject } from '../shared/dto/programme.transfer.reject'; -import { JwtAuthGuard } from '../shared/auth/guards/jwt-auth.guard'; -import { ProgrammeCertify } from '../shared/dto/programme.certify'; -import { ProgrammeTransferCancel } from '../shared/dto/programme.transfer.cancel'; -import { ProgrammeIssue } from '../shared/dto/programme.issue'; -import { ProgrammeRevoke } from '../shared/dto/programme.revoke'; -import { TransferFreezeGuard } from '../shared/auth/guards/transfer-freeze.guard'; -import { ProgrammeDocumentDto } from '../shared/dto/programme.document.dto'; -import { MitigationProperties } from '../shared/dto/mitigation.properties'; -import { OwnershipUpdateDto } from '../shared/dto/ownership.update'; -import { MitigationAddDto } from '../shared/dto/mitigation.add.dto'; -import { ProgrammeAcceptedDto } from '../shared/dto/programme.accepted.dto'; +import { ProgrammeService, ApiKeyJwtAuthGuard, PoliciesGuard, CheckPolicies, AppAbility, Action, Programme, ProgrammeDto, ProgrammeDocumentRegistryDto, ProgrammeAcceptedDto, MitigationAddDto, OwnershipUpdateDto, PoliciesGuardEx, QueryDto, ConstantUpdateDto, ProgrammeApprove, ProgrammeIssue, ProgrammeReject, TransferFreezeGuard, ProgrammeTransferRequest, ProgrammeRetire, ProgrammeCertify, ProgrammeRevoke, ProgrammeTransferApprove, ProgrammeTransfer, ProgrammeTransferReject, ProgrammeTransferCancel } from 'carbon-services-lib'; @ApiTags('Programme') @ApiBearerAuth() @@ -44,8 +16,9 @@ export class ProgrammeController { @UseGuards(ApiKeyJwtAuthGuard, PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, Programme)) @Post('create') - async addProgramme(@Body()programme: ProgrammeDto) { - return this.programmeService.create(programme) + async addProgramme(@Body()programme: ProgrammeDto, @Request() req) { + console.log('Programme create', programme) + return this.programmeService.create(programme, req.user) } @ApiBearerAuth('api_key') @@ -53,8 +26,8 @@ export class ProgrammeController { @UseGuards(ApiKeyJwtAuthGuard, PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, Programme)) @Post('addDocument') - async addDocument(@Body()document: ProgrammeDocumentDto) { - return this.programmeService.addDocument(document) + async addDocument(@Body()document: ProgrammeDocumentRegistryDto, @Request() req) { + return this.programmeService.addDocumentRegistry(document) } @ApiBearerAuth('api_key') @@ -71,7 +44,7 @@ export class ProgrammeController { @UseGuards(ApiKeyJwtAuthGuard, PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, Programme)) @Post('addMitigation') - async addMitigation(@Body()mitigation: MitigationAddDto) { + async addMitigation(@Body()mitigation: MitigationAddDto, @Request() req) { return this.programmeService.addMitigation(mitigation) } @@ -80,8 +53,8 @@ export class ProgrammeController { @UseGuards(ApiKeyJwtAuthGuard, PoliciesGuard) @CheckPolicies((ability: AppAbility) => ability.can(Action.Create, Programme)) @Post('updateOwnership') - async updateOwnership(@Body()update: OwnershipUpdateDto) { - return this.programmeService.updateOwnership(update) + async updateOwnership(@Body()update: OwnershipUpdateDto, @Request() req) { + return this.programmeService.updateOwnership(update, req.user) } @ApiBearerAuth() diff --git a/backend/services/src/national-api/settings.controller.ts b/backend/services/src/national-api/settings.controller.ts index 4cf92172a..03f9e1f75 100644 --- a/backend/services/src/national-api/settings.controller.ts +++ b/backend/services/src/national-api/settings.controller.ts @@ -8,12 +8,7 @@ import { UseGuards, } from "@nestjs/common"; import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; -import { Action } from "../shared/casl/action.enum"; -import { JwtAuthGuard } from "../shared/auth/guards/jwt-auth.guard"; -import { PoliciesGuardEx } from "../shared/casl/policy.guard"; -import { SettingsDto } from "../shared/dto/settings.dto"; -import { ConfigurationSettings } from "../shared/entities/configuration.settings"; -import { ConfigurationSettingsService } from "../shared/util/configurationSettings.service"; +import { ConfigurationSettingsService, JwtAuthGuard, PoliciesGuardEx, Action, ConfigurationSettings, SettingsDto } from "carbon-services-lib"; @ApiTags("Settings") @Controller("Settings") diff --git a/backend/services/src/national-api/user.controller.ts b/backend/services/src/national-api/user.controller.ts index 780debe98..2e711e6a6 100644 --- a/backend/services/src/national-api/user.controller.ts +++ b/backend/services/src/national-api/user.controller.ts @@ -12,24 +12,8 @@ import { Delete, Put, } from "@nestjs/common"; -import { Action } from "../shared/casl/action.enum"; -import { - AppAbility, - CaslAbilityFactory, -} from "../shared/casl/casl-ability.factory"; -import { CheckPolicies } from "../shared/casl/policy.decorator"; -import { PoliciesGuard, PoliciesGuardEx } from "../shared/casl/policy.guard"; -import { User } from "../shared/entities/user.entity"; -import { UserDto } from "../shared/dto/user.dto"; -import { UserService } from "../shared/user/user.service"; -import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; -import { QueryDto } from "../shared/dto/query.dto"; -import { UserUpdateDto } from "../shared/dto/user.update.dto"; -import { PasswordUpdateDto } from "../shared/dto/password.update.dto"; -import { Role } from "../shared/casl/role.enum"; -import { JwtAuthGuard } from "../shared/auth/guards/jwt-auth.guard"; -import { HelperService } from "../shared/util/helpers.service"; -import { ApiKeyJwtAuthGuard } from "../shared/auth/guards/api-jwt-key.guard"; +import { ApiTags, ApiBearerAuth } from "@nestjs/swagger"; +import { UserService, CaslAbilityFactory, HelperService, JwtAuthGuard, ApiKeyJwtAuthGuard, PoliciesGuard, CheckPolicies, Action, User, UserDto, Role, PoliciesGuardEx, UserUpdateDto, PasswordUpdateDto, QueryDto } from "carbon-services-lib"; @ApiTags("User") @ApiBearerAuth() @@ -70,6 +54,23 @@ export class UserController { ); } + @Post("register") + registerUser(@Body() user: UserDto, @Request() req) { + if (user.role == Role.Root) { + throw new HttpException( + this.helperService.formatReqMessagesString("user.rootCreatesRoot", []), + HttpStatus.FORBIDDEN + ); + } + global.baseUrl = `${req.protocol}://${req.get("Host")}`; + return this.userService.create( + user, + null, + user.company.companyRole, + true + ); + } + @ApiBearerAuth() @UseGuards(JwtAuthGuard, PoliciesGuardEx(true, Action.Update, User)) // @CheckPolicies((ability, body) => ability.can(Action.Update, Object.assign(new User(), body))) diff --git a/backend/services/src/setup/handler.ts b/backend/services/src/setup/handler.ts index c6be114f6..7df7a12b2 100644 --- a/backend/services/src/setup/handler.ts +++ b/backend/services/src/setup/handler.ts @@ -1,27 +1,7 @@ import { NestFactory } from "@nestjs/core"; -import { Role } from "../shared/casl/role.enum"; -import { UserDto } from "../shared/dto/user.dto"; -import { LedgerDbModule } from "../shared/ledger-db/ledger-db.module"; -import { QLDBLedgerService } from "../shared/ledger-db/qldb-ledger.service"; -import { getLogger } from "../shared/server"; -import { UtilModule } from "../shared/util/util.module"; -import { Country } from "../shared/entities/country.entity"; -import { CountryService } from "../shared/util/country.service"; -import { CreditOverall } from "../shared/entities/credit.overall.entity"; -import { CompanyModule } from "../shared/company/company.module"; -import { OrganisationDto as OrganisationDto } from "../shared/dto/organisation.dto"; -import { CompanyRole } from "../shared/enum/company.role.enum"; -import { CompanyService } from "../shared/company/company.service"; -import { UserModule } from "../shared/user/user.module"; -import { UserService } from "../shared/user/user.service"; -import { TxType } from "../shared/enum/txtype.enum"; -import { LedgerDBInterface } from "../shared/ledger-db/ledger.db.interface"; import { Handler } from "aws-lambda"; -import { LocationModule } from "../shared/location/location.module"; -import { LocationInterface } from "../shared/location/location.interface"; -import { ProgrammeModule } from "../shared/programme/programme.module"; -import { ProgrammeService } from "../shared/programme/programme.service"; import { ConfigService } from "@nestjs/config"; +import { UserModule, getLogger, UserService, CompanyRole, Role, CompanyModule, CompanyService, ProgrammeModule, ProgrammeService, LedgerDbModule, LedgerDBInterface, CreditOverall, TxType, OrganisationDto, UserDto, UtilModule, CountryService, Country, LocationModule, LocationInterface } from "carbon-services-lib"; const fs = require("fs"); export const handler: Handler = async (event) => { @@ -137,6 +117,7 @@ export const handler: Handler = async (event) => { const org = await companyService.create({ taxId: fields[4] !== "Ministry" ? fields[3] : undefined, companyId: undefined, + paymentId: undefined, name: fields[0], email: fields[1], phoneNo: fields[2], @@ -148,6 +129,8 @@ export const handler: Handler = async (event) => { createdTime: undefined, nameOfMinister: fields[5] || undefined, sectoralScope: secScope, + regions: [], + state: undefined //double check this }); console.log("Company created", org); } catch (e) { @@ -239,5 +222,6 @@ export const handler: Handler = async (event) => { } ); const locationInterface = locationApp.get(LocationInterface); - await locationInterface.init(); + const regionRawData = fs.readFileSync('regions.csv', 'utf8'); + await locationInterface.init(regionRawData); }; diff --git a/backend/services/src/shared/async-operations/async-operations-database.service.ts b/backend/services/src/shared/async-operations/async-operations-database.service.ts deleted file mode 100644 index f568ca7f9..000000000 --- a/backend/services/src/shared/async-operations/async-operations-database.service.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Repository } from "typeorm"; -import { AsyncActionEntity } from "../entities/async.action.entity"; -import { AsyncActionType } from "../enum/async.action.type.enum"; -import { HelperService } from "../util/helpers.service"; -import { - AsyncAction, - AsyncOperationsInterface, -} from "./async-operations.interface"; - -@Injectable() -export class AsyncOperationsDatabaseService - implements AsyncOperationsInterface -{ - private emailDisabled: boolean; - - constructor( - private configService: ConfigService, - private logger: Logger, - @InjectRepository(AsyncActionEntity) - private asyncActionRepo: Repository, - private helperService: HelperService - ) { - this.emailDisabled = this.configService.get("email.disabled"); - } - - public async AddAction(action: AsyncAction): Promise { - if (action.actionType === AsyncActionType.Email) { - if (this.emailDisabled) return false; - } - - let asyncActionEntity: AsyncActionEntity = {} as AsyncActionEntity; - asyncActionEntity.actionType = action.actionType; - asyncActionEntity.actionProps = JSON.stringify(action.actionProps); - await this.asyncActionRepo.save(asyncActionEntity).catch((err: any) => { - this.logger.error("error", err); - throw new HttpException( - this.helperService.formatReqMessagesString( - "common.addAsyncActionDatabaseFailed", - ["Email"] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - }); - - this.logger.log("Succefully added to the AsyncAction table", action); - - return true; - } -} diff --git a/backend/services/src/shared/async-operations/async-operations-queue.service.ts b/backend/services/src/shared/async-operations/async-operations-queue.service.ts deleted file mode 100644 index 61d285625..000000000 --- a/backend/services/src/shared/async-operations/async-operations-queue.service.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { AsyncActionType } from "../enum/async.action.type.enum"; -import { HelperService } from "../util/helpers.service"; -import { - AsyncAction, - AsyncOperationsInterface, -} from "./async-operations.interface"; - -var AWS = require("aws-sdk"); -var sqs = new AWS.SQS(); - -@Injectable() -export class AsyncOperationsQueueService implements AsyncOperationsInterface { - private emailDisabled: boolean; - - constructor( - private configService: ConfigService, - private logger: Logger, - private helperService: HelperService - ) { - this.emailDisabled = this.configService.get("email.disabled"); - } - - public async AddAction(action: AsyncAction): Promise { - var params = {}; - - if (action.actionType === AsyncActionType.Email) { - if (this.emailDisabled) { - return false; - } - } - - params = { - MessageAttributes: { - actionType: { - DataType: "Number", - StringValue: action.actionType.toString(), - }, - }, - MessageBody: JSON.stringify(action.actionProps), - MessageGroupId: action.actionType.toString() + new Date().getTime(), - QueueUrl: this.configService.get("asyncQueueName"), - }; - - try { - await sqs.sendMessage(params).promise(); - this.logger.log("Succefully added to the queue", action.actionType); - } catch (error) { - this.logger.error("Failed when adding to queue", action.actionType); - throw new HttpException( - this.helperService.formatReqMessagesString( - "common.addAsyncActionQueueFailed", - ["Email"] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - return true; - } -} diff --git a/backend/services/src/shared/async-operations/async-operations.interface.ts b/backend/services/src/shared/async-operations/async-operations.interface.ts deleted file mode 100644 index b3d39716e..000000000 --- a/backend/services/src/shared/async-operations/async-operations.interface.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Injectable } from "@nestjs/common"; - -export interface AsyncAction { - actionType: number; - actionProps: any; -} - -@Injectable() -export abstract class AsyncOperationsInterface { - public abstract AddAction(action: AsyncAction): Promise; -} diff --git a/backend/services/src/shared/async-operations/async-operations.module.ts b/backend/services/src/shared/async-operations/async-operations.module.ts deleted file mode 100644 index cc6f18481..000000000 --- a/backend/services/src/shared/async-operations/async-operations.module.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { forwardRef, Logger, Module } from "@nestjs/common"; -import { AsyncOperationsInterface } from "./async-operations.interface"; -import { AsyncOperationsQueueService } from "./async-operations-queue.service"; -import configuration from "../configuration"; -import { ConfigModule } from "@nestjs/config"; -import { AsyncOperationType } from "../enum/async.operation.type.enum"; -import { AsyncOperationsDatabaseService } from "./async-operations-database.service"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import { AsyncActionEntity } from "../entities/async.action.entity"; -import { TypeOrmConfigService } from "../typeorm.config.service"; -import { UtilModule } from "../util/util.module"; - -@Module({ - exports: [AsyncOperationsInterface], - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - }), - TypeOrmModule.forFeature([AsyncActionEntity]), - forwardRef(() => UtilModule) - ], - providers: [ - Logger, - { - provide: AsyncOperationsInterface, - useClass: - process.env.ASYNC_OPERATIONS_TYPE === AsyncOperationType.Queue - ? AsyncOperationsQueueService - : AsyncOperationsDatabaseService, - } - ] -}) -export class AsyncOperationsModule {} diff --git a/backend/services/src/shared/auth/auth.module.ts b/backend/services/src/shared/auth/auth.module.ts deleted file mode 100644 index 45251e8d0..000000000 --- a/backend/services/src/shared/auth/auth.module.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Logger, Module } from "@nestjs/common"; -import { ConfigModule, ConfigService } from "@nestjs/config"; -import { JwtModule } from "@nestjs/jwt"; -import { PassportModule } from "@nestjs/passport"; -import { AuthService } from "./auth.service"; -import { JwtStrategy } from "./strategies/jwt.strategy"; -import { LocalStrategy } from "./strategies/local.strategy"; -import { CaslModule } from "../casl/casl.module"; -import { ApiKeyStrategy } from "./strategies/apikey.strategy"; -import { CompanyModule } from "../company/company.module"; -import { UserModule } from "../user/user.module"; -import { UtilModule } from "../util/util.module"; -import { AsyncOperationsModule } from "../async-operations/async-operations.module"; -import { PasswordReset } from "../entities/userPasswordResetToken.entity"; - -@Module({ - imports: [ - UserModule, - PassportModule, - UtilModule, - JwtModule.registerAsync({ - useFactory: async (configService: ConfigService) => ({ - secretOrPrivateKey: configService.get("jwt.userSecret"), - signOptions: { - expiresIn: parseInt(configService.get("jwt.expiresIn")), - }, - }), - inject: [ConfigService], - imports: undefined, - }), - CaslModule, - CompanyModule, - AsyncOperationsModule, - ], - providers: [ - AuthService, - LocalStrategy, - JwtStrategy, - ApiKeyStrategy, - Logger, - PasswordReset, - ], - exports: [AuthService], -}) -export class AuthModule {} diff --git a/backend/services/src/shared/auth/auth.service.spec.ts b/backend/services/src/shared/auth/auth.service.spec.ts deleted file mode 100644 index 800ab6626..000000000 --- a/backend/services/src/shared/auth/auth.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AuthService } from './auth.service'; - -describe('AuthService', () => { - let service: AuthService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [AuthService], - }).compile(); - - service = module.get(AuthService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/auth/auth.service.ts b/backend/services/src/shared/auth/auth.service.ts deleted file mode 100644 index 81bdfcb8f..000000000 --- a/backend/services/src/shared/auth/auth.service.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; -import { JwtService } from "@nestjs/jwt"; -import { CompanyService } from "../company/company.service"; -import { instanceToPlain } from "class-transformer"; -import { CaslAbilityFactory } from "../casl/casl-ability.factory"; -import { API_KEY_SEPARATOR } from "../constants"; -import { JWTPayload } from "../dto/jwt.payload"; -import { UserService } from "../user/user.service"; -import { HelperService } from "../util/helpers.service"; -import { EmailTemplates } from "../email-helper/email.template"; -import { ConfigService } from "@nestjs/config"; -import { BasicResponseDto } from "../dto/basic.response.dto"; -import { Repository } from "typeorm"; -import { PasswordReset } from "../entities/userPasswordResetToken.entity"; -import { PasswordResetService } from "../util/passwordReset.service"; -import { AsyncAction, AsyncOperationsInterface } from "../async-operations/async-operations.interface"; -import { AsyncActionType } from "../enum/async.action.type.enum"; - -@Injectable() -export class AuthService { - constructor( - private readonly userService: UserService, - private readonly companyService: CompanyService, - private readonly jwtService: JwtService, - private configService: ConfigService, - private helperService: HelperService, - private passwordReset: PasswordResetService, - public caslAbilityFactory: CaslAbilityFactory, - private asyncOperationsInterface: AsyncOperationsInterface, - ) {} - - async validateUser(username: string, pass: string): Promise { - const user = await this.userService.getUserCredentials(username?.toLowerCase()); - if (user && user.password === pass) { - const { password, ...result } = user; - return result; - } - return null; - } - - async validateApiKey(apiKey: string): Promise { - const parts = Buffer.from(apiKey, "base64") - .toString("utf-8") - .split(API_KEY_SEPARATOR); - if (parts.length != 2) { - return null; - } - const user = await this.userService.getUserCredentials(parts[0]?.toLowerCase()); - if (user && user.apiKey === apiKey) { - const { password, apiKey, ...result } = user; - return result; - } - return null; - } - - async login(user: any) { - const organisationDetails = await this.companyService.findByCompanyId( - user.companyId - ); - const payload = new JWTPayload( - organisationDetails.name, - user.name, - user.id, - user.role, - user.companyId, - user.companyRole, - parseInt(organisationDetails.state) - ); - const ability = this.caslAbilityFactory.createForUser(user); - return { - access_token: this.jwtService.sign(instanceToPlain(payload)), - role: user.role, - id: user.id, - name: user.name, - companyId: user.companyId, - companyRole: user.companyRole, - companyName: organisationDetails.name, - companyLogo: organisationDetails.logo, - ability: JSON.stringify(ability), - companyState: parseInt(organisationDetails.state), - }; - } - - async forgotPassword(email: any) { - const hostAddress = this.configService.get("host"); - const userDetails = await this.userService.findOne(email); - if (userDetails) { - console.table(userDetails); - const requestId = this.helperService.generateRandomPassword(); - const date = Date.now(); - const expireDate = date + 3600 * 1000; // 1 hout expire time - const passwordResetD = { - email: email, - token: requestId, - expireTime: expireDate, - }; - await this.passwordReset.deletePasswordResetD(email); - await this.passwordReset.insertPasswordResetD(passwordResetD); - - const templateData = { - name: userDetails.name, - requestId: requestId, - home: hostAddress, - countryName: this.configService.get("systemCountryName"), - }; - - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: EmailTemplates.FORGOT_PASSOWRD.id, - sender: email, - subject: this.helperService.getEmailTemplateMessage( - EmailTemplates.FORGOT_PASSOWRD["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - EmailTemplates.FORGOT_PASSOWRD["html"], - templateData, - false - ), - }, - }; - - await this.asyncOperationsInterface.AddAction(action); - - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString("user.resetEmailSent", []) - ); - } else { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.forgotPwdUserNotFound", - [] - ), - HttpStatus.NOT_FOUND - ); - } - } -} \ No newline at end of file diff --git a/backend/services/src/shared/auth/guards/api-jwt-key.guard.ts b/backend/services/src/shared/auth/guards/api-jwt-key.guard.ts deleted file mode 100644 index 007834c23..000000000 --- a/backend/services/src/shared/auth/guards/api-jwt-key.guard.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; - -@Injectable() -export class ApiKeyJwtAuthGuard extends AuthGuard(["jwt", "api-key"]) { - -} \ No newline at end of file diff --git a/backend/services/src/shared/auth/guards/jwt-auth.guard.ts b/backend/services/src/shared/auth/guards/jwt-auth.guard.ts deleted file mode 100644 index 18588a5c7..000000000 --- a/backend/services/src/shared/auth/guards/jwt-auth.guard.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; - -@Injectable() -export class JwtAuthGuard extends AuthGuard('jwt') {} \ No newline at end of file diff --git a/backend/services/src/shared/auth/guards/local-auth.guard.ts b/backend/services/src/shared/auth/guards/local-auth.guard.ts deleted file mode 100644 index ccf962b67..000000000 --- a/backend/services/src/shared/auth/guards/local-auth.guard.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; - -@Injectable() -export class LocalAuthGuard extends AuthGuard('local') {} diff --git a/backend/services/src/shared/auth/guards/transfer-freeze.guard.ts b/backend/services/src/shared/auth/guards/transfer-freeze.guard.ts deleted file mode 100644 index dd5c48245..000000000 --- a/backend/services/src/shared/auth/guards/transfer-freeze.guard.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common"; -import { ConfigurationSettingsType } from "src/shared/enum/configuration.settings.type.enum"; -import { ConfigurationSettingsService } from "src/shared/util/configurationSettings.service"; - -@Injectable() -export class TransferFreezeGuard implements CanActivate { - constructor( - private configurationSettingsService: ConfigurationSettingsService - ) {} - - async canActivate(context: ExecutionContext) { - const result = await this.configurationSettingsService.getSetting( - ConfigurationSettingsType.isTransferFrozen, - "false" - ); - if (result == "true") return false; - else return true; - } -} diff --git a/backend/services/src/shared/auth/strategies/apikey.strategy.ts b/backend/services/src/shared/auth/strategies/apikey.strategy.ts deleted file mode 100644 index f442f5bff..000000000 --- a/backend/services/src/shared/auth/strategies/apikey.strategy.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { PassportStrategy } from '@nestjs/passport'; -import { HeaderAPIKeyStrategy } from 'passport-headerapikey'; -import { AuthService } from '../auth.service'; - -@Injectable() -export class ApiKeyStrategy extends PassportStrategy(HeaderAPIKeyStrategy, 'api-key') { - constructor(private authService: AuthService) { - const headerKeyApiKey = 'api_key'; - - super({ header: headerKeyApiKey, prefix: '' }, true, async (apiKey, done) => { - const user = this.authService.validateApiKey(apiKey) - if (user) { - done(null, user); - } - done(new UnauthorizedException(), null); - }); - } -} \ No newline at end of file diff --git a/backend/services/src/shared/auth/strategies/jwt.strategy.ts b/backend/services/src/shared/auth/strategies/jwt.strategy.ts deleted file mode 100644 index 3e2ff9424..000000000 --- a/backend/services/src/shared/auth/strategies/jwt.strategy.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { PassportStrategy } from '@nestjs/passport'; -import { plainToClass } from 'class-transformer'; -import { ExtractJwt, Strategy } from 'passport-jwt'; -import { JWTPayload } from '../../dto/jwt.payload'; - -@Injectable() -export class JwtStrategy extends PassportStrategy(Strategy) { - constructor(private configService: ConfigService, private logger: Logger) { - const secret = configService.get('jwt.userSecret'); - super({ - jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), - ignoreExpiration: false, - secretOrKey: secret, - }); - } - - async validate(payload: any) { - const jwtPayload: JWTPayload = plainToClass(JWTPayload, payload) - return { id: jwtPayload.sub, companyName: jwtPayload.cn, role: jwtPayload.r, companyId: jwtPayload.cid, companyRole: jwtPayload.cr, name: jwtPayload.n, companyState: jwtPayload.s }; - } -} diff --git a/backend/services/src/shared/auth/strategies/local.strategy.ts b/backend/services/src/shared/auth/strategies/local.strategy.ts deleted file mode 100644 index 79f85280f..000000000 --- a/backend/services/src/shared/auth/strategies/local.strategy.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Injectable, UnauthorizedException } from '@nestjs/common'; -import { PassportStrategy } from '@nestjs/passport'; -import { Strategy } from 'passport-local'; -import { AuthService } from '../auth.service'; - -@Injectable() -export class LocalStrategy extends PassportStrategy(Strategy) { - constructor(private readonly authService: AuthService) { - super(); - } - - async validate(username: string, password: string): Promise { - const user = await this.authService.validateUser(username, password); - if (!user) { - throw new UnauthorizedException(); - } - return user; - } -} diff --git a/backend/services/src/shared/casl/action.enum.ts b/backend/services/src/shared/casl/action.enum.ts deleted file mode 100644 index 398e8bf8b..000000000 --- a/backend/services/src/shared/casl/action.enum.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum Action { - Manage = 'manage', - Create = 'create', - Read = 'read', - Update = 'update', - Delete = 'delete', -} \ No newline at end of file diff --git a/backend/services/src/shared/casl/casl-ability.factory.spec.ts b/backend/services/src/shared/casl/casl-ability.factory.spec.ts deleted file mode 100644 index 613b677bb..000000000 --- a/backend/services/src/shared/casl/casl-ability.factory.spec.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { CaslAbilityFactory } from './casl-ability.factory'; - -describe('CaslAbilityFactory', () => { - it('should be defined', () => { - expect(new CaslAbilityFactory()).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/casl/casl-ability.factory.ts b/backend/services/src/shared/casl/casl-ability.factory.ts deleted file mode 100644 index 5840db7d5..000000000 --- a/backend/services/src/shared/casl/casl-ability.factory.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { - AbilityBuilder, - CreateAbility, - createMongoAbility, - ExtractSubjectType, - InferSubjects, - MongoAbility, -} from "@casl/ability"; -import { Injectable, ForbiddenException } from "@nestjs/common"; -import { User } from "../entities/user.entity"; -import { Action } from "./action.enum"; -import { Role } from "./role.enum"; -import { EntitySubject } from "../entities/entity.subject"; -import { Programme } from "../entities/programme.entity"; -import { ProgrammeStage } from "../enum/programme-status.enum"; -import { CompanyRole } from "../enum/company.role.enum"; -import { Company } from "../entities/company.entity"; -import { Stat } from "../dto/stat.dto"; -import { StatType } from "../enum/stat.type.enum"; -import { ProgrammeTransfer } from "../entities/programme.transfer"; -import { ProgrammeCertify } from "../dto/programme.certify"; -import { TransferStatus } from "../enum/transform.status.enum"; -import { ProgrammeTransferRequest } from "../dto/programme.transfer.request"; -import { ConfigurationSettings } from "../entities/configuration.settings"; - -type Subjects = InferSubjects | "all"; - -export type AppAbility = MongoAbility<[Action, Subjects]>; -export const createAppAbility = createMongoAbility as CreateAbility; - -const unAuthErrorMessage = "This action is unauthorised"; - -@Injectable() -export class CaslAbilityFactory { - createForUser(user: User) { - console.log("createForUser", user); - const { can, cannot, build } = new AbilityBuilder(createAppAbility); - if (user) { - if (user.role == Role.Root) { - can(Action.Manage, "all"); - cannot([Action.Update], Company, { - companyId: { $ne: user.companyId }, - }); - cannot([Action.Update], User, { - companyId: { $ne: user.companyId }, - }); - } else if ( - user.role == Role.Admin && - (user.companyRole == CompanyRole.GOVERNMENT || - user.companyRole == CompanyRole.MINISTRY) - ) { - can(Action.Manage, User, { role: { $ne: Role.Root } }); - can([Action.Manage], ConfigurationSettings); - can([Action.Manage], Company); - cannot([Action.Update, Action.Delete], User, { - companyId: { $ne: user.companyId }, - }); - cannot(Action.Update, Company, { companyId: { $ne: user.companyId } }); - if (user.companyRole === CompanyRole.MINISTRY) { - cannot([Action.Update, Action.Delete], User, { - companyId: { $ne: user.companyId }, - }); - cannot(Action.Delete, Company, { companyRole: { $eq: user.companyRole } }); - cannot(Action.Delete, Company, { companyId: { $eq: user.companyId } }); - } - } else if ( - user.role == Role.Admin && - user.companyRole != CompanyRole.GOVERNMENT - ) { - can(Action.Manage, User, { role: { $ne: Role.Root } }); - can(Action.Read, Company); - can(Action.Update, Company, { companyId: { $eq: user.companyId } }); - cannot([Action.Update, Action.Delete, Action.Read], User, { - companyId: { $ne: user.companyId }, - }); - cannot([Action.Create], Company); - } else { - if ( - user.companyRole == CompanyRole.GOVERNMENT - ) { - if (user.role === Role.Manager) { - can([Action.Delete], Company); - } - can(Action.Read, User); - } else { - if(user.companyRole == CompanyRole.MINISTRY) { - can(Action.Read, User); - if (user.role === Role.Manager) { - can([Action.Delete], Company); - cannot(Action.Delete, Company, { companyRole: { $eq: user.companyRole } }); - cannot(Action.Delete, Company, { companyId: { $eq: user.companyId } }); - } - } - else { - can(Action.Read, User, { companyId: { $eq: user.companyId } }); - } - } - - cannot([Action.Create], Company); - cannot(Action.Create, User); - } - - can(Action.Read, Company); - can(Action.Update, User, { id: { $eq: user.id } }); - can(Action.Delete, User, { id: { $eq: user.id } }); - cannot( - Action.Update, - User, - ["role", "apiKey", "password", "companyRole", "email"], - { id: { $eq: user.id } } - ); - - if (user.companyRole == CompanyRole.GOVERNMENT) { - if (user.role != Role.ViewOnly) { - can(Action.Manage, ProgrammeTransfer); - can(Action.Manage, Programme); - can(Action.Manage, ProgrammeTransferRequest); - } else { - can(Action.Read, ProgrammeTransfer); - can(Action.Read, Programme); - } - } - - if (user.companyRole == CompanyRole.MINISTRY) { - if (user.role != Role.ViewOnly) { - can(Action.Manage, ProgrammeTransfer); - can(Action.Manage, Programme); - can(Action.Manage, ProgrammeTransferRequest); - } else { - can(Action.Read, ProgrammeTransfer); - can(Action.Read, Programme); - } - } - - if ( - user.role != Role.ViewOnly && - user.companyRole != CompanyRole.PROGRAMME_DEVELOPER - ) { - can(Action.Manage, ProgrammeCertify); - } - - if (user.role == Role.Admin && user.companyRole == CompanyRole.API) { - can([Action.Create, Action.Read], Programme); - can([Action.Create, Action.Read], User); - can([Action.Create, Action.Read], Company); - } else if (user.companyRole == CompanyRole.CERTIFIER) { - can(Action.Read, Programme, { - currentStage: { $in: [ProgrammeStage.AUTHORISED] }, - }); - can(Action.Read, Programme, { - certifierId: { $elemMatch: { $eq: user.companyId } }, - }); - can(Action.Read, ProgrammeTransfer, { - status: { $in: [TransferStatus.APPROVED, TransferStatus.RECOGNISED] }, - }); - } else if (user.companyRole == CompanyRole.PROGRAMME_DEVELOPER) { - can(Action.Read, Programme, { - currentStage: { $eq: ProgrammeStage.AUTHORISED }, - }); - can(Action.Read, ProgrammeTransfer, { - status: { $in: [TransferStatus.APPROVED, TransferStatus.RECOGNISED] }, - }); - if (user.role != Role.ViewOnly) { - can(Action.Manage, Programme, { - companyId: { $elemMatch: { $eq: user.companyId } }, - }); - can(Action.Manage, ProgrammeTransfer, { - toCompanyId: { $eq: user.companyId }, - }); - can(Action.Manage, ProgrammeTransfer, { - fromCompanyId: { $eq: user.companyId }, - }); - can(Action.Manage, ProgrammeTransfer, { - initiatorCompanyId: { $eq: user.companyId }, - }); - can(Action.Manage, ProgrammeTransferRequest); - } else { - can(Action.Read, Programme, { - companyId: { $elemMatch: { $eq: user.companyId } }, - }); - can(Action.Read, ProgrammeTransfer, { - toCompanyId: { $eq: user.companyId }, - }); - can(Action.Read, ProgrammeTransfer, { - fromCompanyId: { $eq: user.companyId }, - }); - can(Action.Read, ProgrammeTransfer, { - initiatorCompanyId: { $eq: user.companyId }, - }); - } - } - - if (user.companyRole == CompanyRole.CERTIFIER) { - can(Action.Read, Stat); - } else { - can(Action.Read, Stat); - } - - cannot([Action.Delete], Company, { - companyRole: { $eq: CompanyRole.GOVERNMENT }, - }); - - if (user.companyState === 0) { - cannot(Action.Create, "all"); - cannot(Action.Delete, "all"); - cannot(Action.Update, User, { id: { $ne: user.id } }); - cannot(Action.Update, Programme); - cannot(Action.Update, Company); - } - } - - return build({ - detectSubjectType: (item) => - item.constructor as ExtractSubjectType, - }); - } -} diff --git a/backend/services/src/shared/casl/casl.module.ts b/backend/services/src/shared/casl/casl.module.ts deleted file mode 100644 index 24035b438..000000000 --- a/backend/services/src/shared/casl/casl.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from "@nestjs/common"; -import { CaslAbilityFactory } from "./casl-ability.factory"; -import { UtilModule } from "../util/util.module"; - -@Module({ - imports: [UtilModule], - providers: [CaslAbilityFactory], - exports: [CaslAbilityFactory], -}) -export class CaslModule {} diff --git a/backend/services/src/shared/casl/policy.decorator.ts b/backend/services/src/shared/casl/policy.decorator.ts deleted file mode 100644 index abdfbfed0..000000000 --- a/backend/services/src/shared/casl/policy.decorator.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { SetMetadata } from "@nestjs/common"; -import { PolicyHandler } from "./policy.handler"; - -export const CHECK_POLICIES_KEY = 'check_policy'; -export const CheckPolicies = (...handlers: PolicyHandler[]) => - SetMetadata(CHECK_POLICIES_KEY, handlers); \ No newline at end of file diff --git a/backend/services/src/shared/casl/policy.guard.ts b/backend/services/src/shared/casl/policy.guard.ts deleted file mode 100644 index 35feb048f..000000000 --- a/backend/services/src/shared/casl/policy.guard.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { - CanActivate, - ExecutionContext, - ForbiddenException, - Injectable, - mixin, -} from "@nestjs/common"; -import { Reflector } from "@nestjs/core"; -import { plainToClass } from "class-transformer"; -import { Stat } from "../dto/stat.dto"; -import { EntitySubject } from "../entities/entity.subject"; -import { User } from "../entities/user.entity"; -import { Action } from "./action.enum"; -import { CaslAbilityFactory, AppAbility } from "./casl-ability.factory"; -import { CHECK_POLICIES_KEY } from "./policy.decorator"; -import { PolicyHandler } from "./policy.handler"; -import { HelperService } from "../util/helpers.service"; -const { rulesToQuery } = require("@casl/ability/extra"); - -@Injectable() -export class PoliciesGuard implements CanActivate { - constructor( - public reflector: Reflector, - public caslAbilityFactory: CaslAbilityFactory, - public helperService: HelperService - ) {} - - async canActivate(context: ExecutionContext): Promise { - const policyHandlers = - this.reflector.get( - CHECK_POLICIES_KEY, - context.getHandler() - ) || []; - - const { user, body } = context.switchToHttp().getRequest(); - const ability = this.caslAbilityFactory.createForUser(user); - - const pHandlers = policyHandlers.every((handler) => - this.execPolicyHandler(handler, ability, body) - ); - if (pHandlers) { - return pHandlers; - } else { - throw new ForbiddenException( - this.helperService.formatReqMessagesString("user.userUnAUth", []) - ); - } - } - - public execPolicyHandler( - handler: PolicyHandler, - ability: AppAbility, - body: any - ) { - if (typeof handler === "function") { - return handler(ability, body); - } - return handler.handle(ability, body); - } -} - -export const PoliciesGuardEx = ( - injectQuery: boolean, - action?: Action, - subject?: typeof EntitySubject, - onlyInject?: boolean, - dropArrayFields?: boolean -) => { - @Injectable() - class PoliciesGuardMixin implements CanActivate { - constructor( - public reflector: Reflector, - public caslAbilityFactory: CaslAbilityFactory, - public helperService: HelperService - ) {} - - parseMongoQueryToSQL(mongoQuery, isNot = false, key = undefined) { - let final = undefined; - for (let operator in mongoQuery) { - if (operator.startsWith("$")) { - if (operator == "$and" || operator == "$or") { - const val = mongoQuery[operator].map(st => this.parseMongoQueryToSQL(st)).join(` ${operator.replace("$", '')} `) - final = final == undefined ? val : `${final} and ${val}` - } else if (operator == "$not") { - return this.parseMongoQueryToSQL(mongoQuery["$not"], !isNot) - } else if (operator == "$eq") { - const value = (typeof mongoQuery["$eq"] === "number") ? String(mongoQuery["$eq"]) : `'${mongoQuery["$eq"]}'` - return `"${key}" ${isNot ? "!=" : "="} ${value}` - } else if (operator == "$ne") { - const value = (typeof mongoQuery["$ne"] === "number") ? String(mongoQuery["$ne"]) : `'${mongoQuery["$ne"]}'` - return `"${key}" ${isNot ? "=" : "!="} ${value}` - } - } else { - return this.parseMongoQueryToSQL(mongoQuery[operator], isNot, operator) - } - } - return final; - } - - async canActivate(context: ExecutionContext): Promise { - const policyHandlers = - this.reflector.get( - CHECK_POLICIES_KEY, - context.getHandler() - ) || []; - - const { user, body } = context.switchToHttp().getRequest(); - const ability = this.caslAbilityFactory.createForUser(user); - - if (injectQuery) { - context.switchToHttp().getRequest()['ability'] = ability; - - const mongoQuery = JSON.stringify(rulesToQuery(ability, action, subject, rule => { - return rule.inverted ? { $not: rule.conditions } : rule.conditions - })) - console.log(JSON.stringify(mongoQuery)) - - if (mongoQuery && mongoQuery != "" && mongoQuery != "{}" && mongoQuery != '{"$or":[{}]}') { - // const whereQuery = this.parseMongoQueryToSQL(JSON.parse(mongoQuery)); - // console.log("Where", whereQuery) - context.switchToHttp().getRequest()['abilityCondition'] = JSON.parse(mongoQuery); - } - } - - if (dropArrayFields) { - const obj = Object.assign(new subject(), body); - let abilityCan: boolean = true; - for (const key in obj) { - const possible = []; - if (obj[key] instanceof Array) { - console.log(obj[key]); - for (const en of obj[key]) { - for (const key2 in en) { - console.log(action, en, key2); - if (ability.can(action, plainToClass(Stat, en), key2)) { - possible.push(en); - } - } - } - obj[key] = possible; - context.switchToHttp().getRequest()["body"] = obj; - abilityCan = possible.length > 0; - if (abilityCan) { - return abilityCan; - } else { - throw new ForbiddenException( - this.helperService.formatReqMessagesString( - "user.userUnAUth", - [] - ) - ); - } - } - } - } - - if (policyHandlers.length == 0 && action && subject && !onlyInject) { - const obj = Object.assign(new subject(), body); - let abilityCan: boolean = true; - console.log(obj); - if (action == Action.Update) { - if (obj instanceof User && obj.companyId == undefined) { - obj.companyId = user.companyId; - } - for (const key in obj) { - if (!ability.can(action, obj, key)) { - console.log( - "Failed due to", - JSON.stringify(ability), - action, - obj, - key - ); - abilityCan = false; - } - } - } else if (action == Action.Delete) { - abilityCan = ability.can(action, subject); - } else { - abilityCan = ability.can(action, obj); - } - if (abilityCan) { - return abilityCan; - } else { - throw new ForbiddenException( - this.helperService.formatReqMessagesString("user.userUnAUth", []) - ); - } - } - - const pHandler = policyHandlers.every((handler) => - this.execPolicyHandler(handler, ability, body) - ); - if (pHandler) { - return pHandler; - } else { - throw new ForbiddenException( - this.helperService.formatReqMessagesString("user.userUnAUth", []) - ); - } - } - - public execPolicyHandler( - handler: PolicyHandler, - ability: AppAbility, - body: any - ) { - if (typeof handler === "function") { - return handler(ability, body); - } - return handler.handle(ability, body); - } - } - - const guard = mixin(PoliciesGuardMixin); - return guard; -}; diff --git a/backend/services/src/shared/casl/policy.handler.ts b/backend/services/src/shared/casl/policy.handler.ts deleted file mode 100644 index 440ab9c2b..000000000 --- a/backend/services/src/shared/casl/policy.handler.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { AppAbility } from '../casl/casl-ability.factory'; - -interface IPolicyHandler { - handle(ability: AppAbility, req: any): boolean; -} - -type PolicyHandlerCallback = (ability: AppAbility, req: any) => boolean; - -export type PolicyHandler = IPolicyHandler | PolicyHandlerCallback; diff --git a/backend/services/src/shared/casl/role.enum.ts b/backend/services/src/shared/casl/role.enum.ts deleted file mode 100644 index 768bdab93..000000000 --- a/backend/services/src/shared/casl/role.enum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum Role { - Root = 'Root', - Admin = 'Admin', - Manager = 'Manager', - ViewOnly = 'ViewOnly' -} \ No newline at end of file diff --git a/backend/services/src/shared/company/company.module.ts b/backend/services/src/shared/company/company.module.ts deleted file mode 100644 index e5b42bc63..000000000 --- a/backend/services/src/shared/company/company.module.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { forwardRef, Logger, Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import { Company } from "../entities/company.entity"; -import { CaslModule } from "../casl/casl.module"; -import configuration from "../configuration"; -import { TypeOrmConfigService } from "../typeorm.config.service"; -import { CompanyService } from "./company.service"; -import { UtilModule } from "../util/util.module"; -import { ProgrammeLedgerModule } from "../programme-ledger/programme-ledger.module"; -import { ProgrammeTransfer } from "../entities/programme.transfer"; -import { EmailHelperModule } from "../email-helper/email-helper.module"; -import { FileHandlerModule } from "../file-handler/filehandler.module"; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - imports: undefined, - }), - TypeOrmModule.forFeature([Company, ProgrammeTransfer]), - CaslModule, - UtilModule, - ProgrammeLedgerModule, - FileHandlerModule, - forwardRef(() => EmailHelperModule), - ], - providers: [CompanyService, Logger], - exports: [CompanyService], -}) -export class CompanyModule {} diff --git a/backend/services/src/shared/company/company.service.spec.ts b/backend/services/src/shared/company/company.service.spec.ts deleted file mode 100644 index 0a42ab0e9..000000000 --- a/backend/services/src/shared/company/company.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { CompanyService } from './company.service'; - -describe('CompanyService', () => { - let service: CompanyService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [CompanyService], - }).compile(); - - service = module.get(CompanyService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/company/company.service.ts b/backend/services/src/shared/company/company.service.ts deleted file mode 100644 index d5a0ff1cf..000000000 --- a/backend/services/src/shared/company/company.service.ts +++ /dev/null @@ -1,493 +0,0 @@ -import { PG_UNIQUE_VIOLATION } from "@drdgvhbh/postgres-error-codes"; -import { - forwardRef, - HttpException, - HttpStatus, - Inject, - Injectable, - Logger, -} from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { InjectRepository } from "@nestjs/typeorm"; -import { OrganisationDto } from "../dto/organisation.dto"; -import { QueryFailedError, Repository } from "typeorm"; -import { Company } from "../entities/company.entity"; -import { CompanyRole } from "../enum/company.role.enum"; -import { QueryDto } from "../dto/query.dto"; -import { DataListResponseDto } from "../dto/data.list.response"; -import { BasicResponseDto } from "../dto/basic.response.dto"; -import { CompanyState } from "../enum/company.state.enum"; -import { HelperService } from "../util/helpers.service"; -import { FindOrganisationQueryDto } from "../dto/find.organisation.dto"; -import { ProgrammeLedgerService } from "../programme-ledger/programme-ledger.service"; -import { OrganisationUpdateDto } from "../dto/organisation.update.dto"; -import { DataResponseDto } from "../dto/data.response.dto"; -import { ProgrammeTransfer } from "../entities/programme.transfer"; -import { TransferStatus } from "../enum/transform.status.enum"; -import { User } from "../entities/user.entity"; -import { EmailHelperService } from "../email-helper/email-helper.service"; -import { Programme } from "../entities/programme.entity"; -import { EmailTemplates } from "../email-helper/email.template"; -import { SystemActionType } from "../enum/system.action.type"; -import { FileHandlerInterface } from "../file-handler/filehandler.interface"; -import { CounterType } from "../util/counter.type.enum"; -import { CounterService } from "../util/counter.service"; - -@Injectable() -export class CompanyService { - constructor( - @InjectRepository(Company) private companyRepo: Repository, - private logger: Logger, - private configService: ConfigService, - private helperService: HelperService, - private programmeLedgerService: ProgrammeLedgerService, - @Inject(forwardRef(() => EmailHelperService)) - private emailHelperService: EmailHelperService, - @InjectRepository(ProgrammeTransfer) - private programmeTransferRepo: Repository, - private fileHandler: FileHandlerInterface, - private counterService: CounterService - ) {} - - async suspend( - companyId: number, - user: any, - remarks: string, - abilityCondition: string - ): Promise { - this.logger.verbose("Suspend company", companyId); - const company = await this.companyRepo - .createQueryBuilder() - .where( - `"companyId" = '${companyId}' and state = '1' ${ - abilityCondition - ? " AND (" + - this.helperService.parseMongoQueryToSQL(abilityCondition) + - ")" - : "" - }` - ) - .getOne(); - if(user.companyRole === CompanyRole.MINISTRY) { - const companyDetails = await this.findByCompanyId(companyId); - if(companyDetails.companyRole === CompanyRole.GOVERNMENT || companyDetails.companyRole === CompanyRole.MINISTRY) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.userUnAUth", - [] - ), - HttpStatus.FORBIDDEN - ); - } - } - if (!company) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "company.noActiveCompany", - [] - ), - HttpStatus.UNAUTHORIZED - ); - } - const result = await this.companyRepo - .update( - { - companyId: companyId, - }, - { - state: CompanyState.SUSPENDED, - remarks: remarks, - } - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - - if (result.affected > 0) { - // TODO: Currently there can be unfreezed credits after company suspend if transactions failed - if (company.companyRole === CompanyRole.PROGRAMME_DEVELOPER) { - await this.programmeLedgerService.freezeCompany( - companyId, - this.getUserRefWithRemarks(user, `${remarks}#${company.name}`), - true - ); - await this.companyTransferCancel( - companyId, - `${remarks}#${user.companyId}#${user.id}#${SystemActionType.SUSPEND_AUTO_CANCEL}#${company.name}#${user.companyName}` - ); - await this.emailHelperService.sendEmail( - company.email, - EmailTemplates.PROGRAMME_DEVELOPER_ORG_DEACTIVATION, - {}, - user.companyId - ); - } else if (company.companyRole === CompanyRole.CERTIFIER) { - await this.programmeLedgerService.revokeCompanyCertifications( - companyId, - this.getUserRefWithRemarks( - user, - `${remarks}#${SystemActionType.SUSPEND_REVOKE}#${company.name}` - ), - async (programme: Programme) => { - const hostAddress = this.configService.get("host"); - await this.emailHelperService.sendEmailToProgrammeOwnerAdmins( - programme.programmeId, - EmailTemplates.PROGRAMME_CERTIFICATION_REVOKE_BY_SYSTEM, - { - organisationName: company.name, - programmeName: programme.title, - credits: programme.creditBalance, - serialNumber: programme.serialNo, - pageLink: - hostAddress + - `/programmeManagement/view?id=${programme.programmeId}`, - } - ); - } - ); - - await this.emailHelperService.sendEmail( - company.email, - EmailTemplates.CERTIFIER_ORG_DEACTIVATION, - {}, - user.companyId - ); - } - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString( - "company.suspendCompanySuccess", - [] - ) - ); - } - throw new HttpException( - this.helperService.formatReqMessagesString("company.suspendFailed", []), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - async activate( - companyId: number, - user: User, - remarks: string, - abilityCondition: string - ): Promise { - this.logger.verbose("revoke company", companyId); - const company = await this.companyRepo - .createQueryBuilder() - .where( - `"companyId" = '${companyId}' and state = '0' ${ - abilityCondition - ? " AND (" + - this.helperService.parseMongoQueryToSQL(abilityCondition) + - ")" - : "" - }` - ) - .getOne(); - if(user.companyRole === CompanyRole.MINISTRY) { - const companyDetails = await this.findByCompanyId(companyId); - if(companyDetails.companyRole === CompanyRole.GOVERNMENT || companyDetails.companyRole === CompanyRole.MINISTRY) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.userUnAUth", - [] - ), - HttpStatus.FORBIDDEN - ); - } - } - if (!company) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "company.noSuspendedCompany", - [] - ), - HttpStatus.UNAUTHORIZED - ); - } - const result = await this.companyRepo - .update( - { - companyId: companyId, - }, - { - state: CompanyState.ACTIVE, - } - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - - if (result.affected > 0) { - await this.programmeLedgerService.freezeCompany( - companyId, - this.getUserRefWithRemarks(user, `${remarks}#${company.name}`), - false - ); - await this.emailHelperService.sendEmail( - company.email, - EmailTemplates.ORG_REACTIVATION, - {}, - user.companyId - ); - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString( - "company.companyActivationSuccess", - [] - ) - ); - } - throw new HttpException( - this.helperService.formatReqMessagesString( - "company.companyActivationFailed", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - async query(query: QueryDto, abilityCondition: string): Promise { - const resp = await this.companyRepo - .createQueryBuilder() - .where( - this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .orderBy( - query?.sort?.key && `"${query?.sort?.key}"`, - query?.sort?.order, - query?.sort?.nullFirst !== undefined - ? query?.sort?.nullFirst === true - ? "NULLS FIRST" - : "NULLS LAST" - : undefined - ) - .offset(query.size * query.page - query.size) - .limit(query.size) - .getManyAndCount(); - - return new DataListResponseDto( - resp.length > 0 ? resp[0] : undefined, - resp.length > 1 ? resp[1] : undefined - ); - } - - async queryNames(query: QueryDto, abilityCondition: string): Promise { - const resp = await this.companyRepo - .createQueryBuilder() - .select(['"companyId"', '"name"', '"state"']) - .where( - this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQL(abilityCondition) - ) - ) - .orderBy(query?.sort?.key && `"${query?.sort?.key}"`, query?.sort?.order) - .offset(query.size * query.page - query.size) - .limit(query.size) - .getRawMany(); - - console.log(resp); - return new DataListResponseDto(resp, undefined); - } - - async findByTaxId(taxId: string): Promise { - if (!taxId) { - return null; - } - const companies = await this.companyRepo.find({ - where: { - taxId: taxId, - }, - }); - return companies && companies.length > 0 ? companies[0] : undefined; - } - - async findByCompanyId(companyId: number): Promise { - const companies = await this.companyRepo.find({ - where: { - companyId: companyId, - }, - }); - return companies && companies.length > 0 ? companies[0] : undefined; - } - - async findByCompanyIds( - req: FindOrganisationQueryDto - ): Promise { - const data: Company[] = []; - - if (!(req.companyIds instanceof Array)) { - throw new HttpException("Invalid companyId list", HttpStatus.BAD_REQUEST); - } - for (let i = 0; i < req.companyIds.length; i++) { - const companies = await this.companyRepo.find({ - where: { - companyId: req.companyIds[i], - }, - }); - data.push(companies[0]); - } - return data && data.length > 0 ? data : undefined; - } - - async findGovByCountry(countryCode: string): Promise { - const companies = await this.companyRepo.find({ - where: { - country: countryCode, - companyRole: CompanyRole.GOVERNMENT, - }, - }); - return companies && companies.length > 0 ? companies[0] : undefined; - } - - async findMinByCountry(countryCode: string): Promise { - const companies = await this.companyRepo.find({ - where: { - country: countryCode, - companyRole: CompanyRole.MINISTRY, - }, - }); - return companies && companies.length > 0 ? companies[0] : undefined; - } - - async create(companyDto: OrganisationDto): Promise { - this.logger.verbose("Company create received", companyDto.email); - - if (!companyDto.companyId) { - companyDto.companyId = parseInt( - await this.counterService.incrementCount(CounterType.COMPANY, 3) - ); - } - - return await this.companyRepo.save(companyDto).catch((err: any) => { - if (err instanceof QueryFailedError) { - switch (err.driverError.code) { - case PG_UNIQUE_VIOLATION: - throw new HttpException( - this.helperService.formatReqMessagesString( - "company.companyTaxIdExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - } - return err; - }); - } - - async update( - companyUpdateDto: OrganisationUpdateDto, - abilityCondition: string - ): Promise { - const company = await this.companyRepo - .createQueryBuilder() - .where( - `"companyId" = '${companyUpdateDto.companyId}' ${ - abilityCondition - ? " AND (" + - this.helperService.parseMongoQueryToSQL(abilityCondition) + - ")" - : "" - }` - ) - .getOne(); - if (!company) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "company.noActiveCompany", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (companyUpdateDto.logo) { - const response: any = await this.fileHandler.uploadFile( - `profile_images/${ - companyUpdateDto.companyId - }_${new Date().getTime()}.png`, - companyUpdateDto.logo - ); - - if (response) { - companyUpdateDto.logo = response; - } else { - throw new HttpException( - this.helperService.formatReqMessagesString( - "company.companyUpdateFailed", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - } - - const { companyId, ...companyUpdateFields } = companyUpdateDto; - if (!companyUpdateFields.hasOwnProperty("website")) { - companyUpdateFields["website"] = ""; - } - - const result = await this.companyRepo - .update( - { - companyId: company.companyId, - }, - companyUpdateFields - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - - if (result.affected > 0) { - return new DataResponseDto( - HttpStatus.OK, - await this.findByCompanyId(company.companyId) - ); - } - - throw new HttpException( - this.helperService.formatReqMessagesString( - "company.companyUpdateFailed", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - async companyTransferCancel(companyId: number, remark: string) { - await this.programmeTransferRepo - .createQueryBuilder() - .update(ProgrammeTransfer) - .set({ - status: TransferStatus.CANCELLED, - txRef: remark, - txTime: new Date().getTime(), - }) - .where( - "(fromCompanyId = :companyId OR toCompanyId = :companyId) AND status = :status", - { - companyId: companyId, - status: TransferStatus.PENDING, - } - ) - .execute() - .catch((err: any) => { - this.logger.error(err); - return err; - }); - } - - private getUserRefWithRemarks = (user: any, remarks: string) => { - return `${user.companyId}#${user.companyName}#${user.id}#${remarks}`; - }; -} diff --git a/backend/services/src/shared/configuration.ts b/backend/services/src/shared/configuration.ts deleted file mode 100644 index c7c29a786..000000000 --- a/backend/services/src/shared/configuration.ts +++ /dev/null @@ -1,68 +0,0 @@ -export default () => ({ - stage: process.env.STAGE || "local", - systemCountry: process.env.systemCountryCode || "NG", - systemCountryName: process.env.systemCountryName || "CountryX", - defaultCreditUnit: process.env.defaultCreditUnit || "ITMO", - dateTimeFormat: "DD LLLL yyyy @ HH:mm", - dateFormat: "DD LLLL yyyy", - database: { - type: "postgres", - host: process.env.DB_HOST || "localhost", - port: parseInt(process.env.DB_PORT) || 5432, - username: process.env.DB_USER || "hquser", - password: process.env.DB_PASSWORD || "", - database: process.env.DB_NAME || "carbondev", - synchronize: process.env.NODE_ENV == "prod" ? true : true, - autoLoadEntities: true, - logging: ["error"], - }, - jwt: { - expiresIn: process.env.EXPIRES_IN || "7200", - userSecret: process.env.USER_JWT_SECRET || "1324", - adminSecret: process.env.ADMIN_JWT_SECRET || "8654", - }, - ledger: { - name: "carbon-registry-" + (process.env.NODE_ENV || "dev"), - table: "programmes", - overallTable: "overall", - companyTable: "company", - }, - email: { - source: process.env.SOURCE_EMAIL || "info@xeptagon.com", - endpoint: - process.env.SMTP_ENDPOINT || - "vpce-02cef9e74f152b675-b00ybiai.email-smtp.us-east-1.vpce.amazonaws.com", - username: process.env.SMTP_USERNAME || "AKIAUMXKTXDJIOFY2QXL", - password: process.env.SMTP_PASSWORD, - disabled: process.env.IS_EMAIL_DISABLED === "true" ? true : false, - disableLowPriorityEmails: - process.env.DISABLE_LOW_PRIORITY_EMAIL === "true" ? true : false, - }, - s3CommonBucket: { - name: "carbon-common-" + (process.env.NODE_ENV || "dev"), - }, - host: process.env.HOST || "https://test.carbreg.org", - liveChat: "https://undp2020cdo.typeform.com/to/emSWOmDo", - mapbox: { - key: process.env.MAPBOX_PK, - }, - openstreet: { - retrieve: process.env.OPENSTREET_QUERY === "true" || false, - }, - asyncQueueName: - process.env.ASYNC_QUEUE_NAME || - "https://sqs.us-east-1.amazonaws.com/302213478610/AsyncQueuedev.fifo", - ITMOSystem: { - endpoint: - process.env.ITMO_ENDPOINT || - "https://dev-digital-carbon-finance-webapp-api-rxloyxnj3dbso.azurewebsites.net/api/v1/", - apiKey: process.env.ITMO_API_KEY, - email: process.env.ITMO_EMAIL, - password: process.env.ITMO_PASSWORD, - }, - registry: { - syncEnable: process.env.REGISTRY_SYNC_ENABLE || false, - endpoint: process.env.MRV_ENDPOINT || 'https://u4h9swxm8b.execute-api.us-east-1.amazonaws.com/dev', - apiToken: process.env.MRV_API_TOKEN - } -}); diff --git a/backend/services/src/shared/constants.ts b/backend/services/src/shared/constants.ts deleted file mode 100644 index 4c3dec83f..000000000 --- a/backend/services/src/shared/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const API_KEY_SEPARATOR = '___' \ No newline at end of file diff --git a/backend/services/src/shared/dto/aggr.entry.ts b/backend/services/src/shared/dto/aggr.entry.ts deleted file mode 100644 index 1d4c18500..000000000 --- a/backend/services/src/shared/dto/aggr.entry.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsInt, IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString } from "class-validator"; - -export class AggrEntry { - - @IsNotEmpty() - @ApiPropertyOptional() - @IsOptional() - key: any; - - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - @IsOptional() - operation: any; - - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - @IsOptional() - fieldName: string; - - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - @IsOptional() - outerQuery?: string; - - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - @IsOptional() - mineCompanyId?: boolean; - - // @IsNotEmpty() - // @IsString() - // @ApiPropertyOptional() - // @IsOptional() - // keyOperation?: any; - - // @IsNotEmpty() - // @IsString() - // @ApiPropertyOptional() - // @IsOptional() - // keyOperationAttr?: any; - - constructor(key: any, operation: any, fieldName: string) { - this.key = key; - this.operation = operation; - this.fieldName = fieldName; - } -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/agriculture.constants.dto.ts b/backend/services/src/shared/dto/agriculture.constants.dto.ts deleted file mode 100644 index 13e525092..000000000 --- a/backend/services/src/shared/dto/agriculture.constants.dto.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNumber, IsString } from "class-validator"; - -export class AgricultureConstantsDto { - - @ApiProperty() - @IsNumber() - emissionFactor: number; - - @ApiProperty() - @IsString() - emissionFactorUnit: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/agriculture.properties.ts b/backend/services/src/shared/dto/agriculture.properties.ts deleted file mode 100644 index feeff60e8..000000000 --- a/backend/services/src/shared/dto/agriculture.properties.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsPositive, IsNumber, IsString } from "class-validator"; -import { MitigationProperties } from "./mitigation.properties"; - -export class AgricultureProperties extends MitigationProperties { - - @ApiProperty() - @IsNotEmpty() - @IsPositive() - @IsNumber() - landArea: number; - - @ApiProperty({default: "ha"}) - @IsNotEmpty() - @IsString() - landAreaUnit: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/basic.organisation.dto.ts b/backend/services/src/shared/dto/basic.organisation.dto.ts deleted file mode 100644 index 11f848ee1..000000000 --- a/backend/services/src/shared/dto/basic.organisation.dto.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { - IsEmail, - isNotEmpty, - IsNotEmpty, - IsNumber, - IsOptional, - IsString, -} from "class-validator"; -import { IsValidCountry } from "../util/validcountry.decorator"; - -export class BasicOrgInfo { - @IsString() - @IsNotEmpty() - @ApiPropertyOptional() - @IsOptional() - name: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - @IsValidCountry() - country: string; -} diff --git a/backend/services/src/shared/dto/basic.response.dto.ts b/backend/services/src/shared/dto/basic.response.dto.ts deleted file mode 100644 index e3cc8030d..000000000 --- a/backend/services/src/shared/dto/basic.response.dto.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class BasicResponseDto { - constructor(public statusCode: number, public message: string) { - - } -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/chart.stats.result.ts b/backend/services/src/shared/dto/chart.stats.result.ts deleted file mode 100644 index 56be42ef2..000000000 --- a/backend/services/src/shared/dto/chart.stats.result.ts +++ /dev/null @@ -1,109 +0,0 @@ -interface chartMonthProgrammeStageResult { - awaitingAuthorization?: number; - issued?: number; - rejected?: number; - retired?: number; - transferred?: number; -} - -interface chartMonthProgrammeStageResultSend { - awaitingAuthorization?: number[]; - issued?: number[]; - rejected?: number[]; -} - -interface chartTotalProgramsResultInMonths { - jan?: chartMonthProgrammeStageResult; - feb?: chartMonthProgrammeStageResult; - mar?: chartMonthProgrammeStageResult; - apr?: chartMonthProgrammeStageResult; - may?: chartMonthProgrammeStageResult; - jun?: chartMonthProgrammeStageResult; - jul?: chartMonthProgrammeStageResult; - aug?: chartMonthProgrammeStageResult; - sep?: chartMonthProgrammeStageResult; - oct?: chartMonthProgrammeStageResult; - nov?: chartMonthProgrammeStageResult; - dec?: chartMonthProgrammeStageResult; -} - -export interface chartStatsResultInMonths { - totalPrograms?: chartTotalProgramsResultInMonths; -} - -export interface chartStatsResultSend { - totalPrograms?: chartMonthProgrammeStageResultSend; -} - -export let chartStatsResultInitialValueSend: chartStatsResultSend = { - totalPrograms: { - awaitingAuthorization: [], - issued: [], - rejected: [], - }, -}; - -export let chartStatsResultInitialValueInMonths: chartStatsResultInMonths = { - totalPrograms: { - jan: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - feb: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - mar: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - apr: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - may: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - jun: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - jul: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - aug: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - sep: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - oct: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - nov: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - dec: { - awaitingAuthorization: 0, - issued: 0, - rejected: 0, - }, - }, -}; diff --git a/backend/services/src/shared/dto/chartStats.dto.ts b/backend/services/src/shared/dto/chartStats.dto.ts deleted file mode 100644 index 9040524e8..000000000 --- a/backend/services/src/shared/dto/chartStats.dto.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsEnum } from "class-validator"; -import { EntitySubject } from "../entities/entity.subject"; -import { ChartType } from "../enum/chart.type.enum"; - -export class ChartStat extends EntitySubject { - @ApiProperty({ enum: ChartType }) - @IsEnum(ChartType, { - message: - "Invalid stat type. Support following values:" + Object.values(ChartType), - }) - type: ChartType; - value?: any; - data?: any; -} diff --git a/backend/services/src/shared/dto/chartStats.list.dto.ts b/backend/services/src/shared/dto/chartStats.list.dto.ts deleted file mode 100644 index c229e8e98..000000000 --- a/backend/services/src/shared/dto/chartStats.list.dto.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { - IsNotEmptyObject, - IsNumber, - IsObject, - IsOptional, - IsPositive, - ValidateNested, -} from "class-validator"; -import { ChartStat } from "./chartStats.dto"; - -export class ChartStatList { - @ApiProperty({ isArray: true, type: ChartStat }) - @ValidateNested({ each: true }) - @Type(() => ChartStat) - stats: ChartStat[]; - - @ApiProperty() - category: string; - - @IsPositive() - @IsNumber() - @ApiPropertyOptional() - @IsOptional() - startTime: number; - - @IsPositive() - @IsNumber() - @ApiPropertyOptional() - @IsOptional() - endTime: number; -} diff --git a/backend/services/src/shared/dto/chartStats.request.dto.ts b/backend/services/src/shared/dto/chartStats.request.dto.ts deleted file mode 100644 index 6ced6cd40..000000000 --- a/backend/services/src/shared/dto/chartStats.request.dto.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { - IsEmail, - isNotEmpty, - IsNotEmpty, - IsNumber, - IsOptional, - IsString, -} from "class-validator"; - -export class chartStatsRequestDto { - type: string; - value?: string; - companyId?: any; - startDate?: number; - endDate?: number; -} diff --git a/backend/services/src/shared/dto/charts.stats.response.ts b/backend/services/src/shared/dto/charts.stats.response.ts deleted file mode 100644 index c2512c41b..000000000 --- a/backend/services/src/shared/dto/charts.stats.response.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class ChartStatsResponseDto { - stats: any; - lastUpdate: number; - - constructor(stats: any) { - this.stats = stats; - this.lastUpdate = Math.round(Date.now() / 1000); - } - } - \ No newline at end of file diff --git a/backend/services/src/shared/dto/constants.update.dto.ts b/backend/services/src/shared/dto/constants.update.dto.ts deleted file mode 100644 index 0d9110d2a..000000000 --- a/backend/services/src/shared/dto/constants.update.dto.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { AgricultureConstants, SolarConstants } from "@undp/carbon-credit-calculator"; -import { IsNotEmpty, IsEnum, ValidateIf, IsNotEmptyObject } from "class-validator"; -import { TypeOfMitigation } from "../enum/typeofmitigation.enum"; -import { AgricultureConstantsDto } from "./agriculture.constants.dto"; -import { SolarConstantsDto } from "./solar.constants.dto"; - -export class ConstantUpdateDto { - - @ApiProperty({ enum: TypeOfMitigation }) - @IsEnum(TypeOfMitigation, { - message: 'Invalid custom config group. Supported following values:' + Object.values(TypeOfMitigation) - }) - @IsNotEmpty() - type: TypeOfMitigation; - - @ApiProperty({ type: AgricultureConstantsDto }) - @IsNotEmptyObject() - @ValidateIf(o => o.type === TypeOfMitigation.AGRICULTURE) - @IsNotEmpty() - agricultureConstants: AgricultureConstantsDto; - - @ApiProperty({ type: SolarConstantsDto }) - @IsNotEmptyObject() - @ValidateIf(o => o.type === TypeOfMitigation.SOLAR) - @IsNotEmpty() - solarConstants: SolarConstantsDto; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/data.count.response.ts b/backend/services/src/shared/dto/data.count.response.ts deleted file mode 100644 index aa6307a84..000000000 --- a/backend/services/src/shared/dto/data.count.response.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class DataCountResponseDto { - stats: any; - lastUpdate: number; - - constructor(stats: any) { - this.stats = stats; - this.lastUpdate = Math.round(Date.now() / 1000); - } -} diff --git a/backend/services/src/shared/dto/data.list.response.ts b/backend/services/src/shared/dto/data.list.response.ts deleted file mode 100644 index 7ed9bb82d..000000000 --- a/backend/services/src/shared/dto/data.list.response.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsNumber, IsString } from "class-validator"; -import { ProgrammeStage } from "../enum/programme-status.enum"; - -export class DataListResponseDto { - data: any[]; - total: number; - - constructor(data: any[], total: number) { - this.total = total; - this.data = data - } -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/data.response.dto.ts b/backend/services/src/shared/dto/data.response.dto.ts deleted file mode 100644 index 95d6381d7..000000000 --- a/backend/services/src/shared/dto/data.response.dto.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class DataResponseDto { - constructor(public statusCode: number, public data: any) { - - } -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/data.response.message.ts b/backend/services/src/shared/dto/data.response.message.ts deleted file mode 100644 index eefd2eb0f..000000000 --- a/backend/services/src/shared/dto/data.response.message.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class DataResponseMessageDto { - constructor( - public statusCode: number, - public message: string, - public data: any - ) {} -} diff --git a/backend/services/src/shared/dto/filter.by.ts b/backend/services/src/shared/dto/filter.by.ts deleted file mode 100644 index 41dbd8c0f..000000000 --- a/backend/services/src/shared/dto/filter.by.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import {IsNotEmpty, IsOptional} from "class-validator"; - -export class FilterBy { - - @IsNotEmpty() - @ApiPropertyOptional() - @IsOptional() - key: any; - - @IsNotEmpty() - @ApiProperty() - value: any[]; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/filter.entry.ts b/backend/services/src/shared/dto/filter.entry.ts deleted file mode 100644 index 40ef2e57e..000000000 --- a/backend/services/src/shared/dto/filter.entry.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsInt, IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString } from "class-validator"; - -export class FilterEntry { - - @IsNotEmpty() - @ApiPropertyOptional() - @IsOptional() - key: any; - - @IsNotEmpty() - @ApiProperty() - value: any; - - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - @IsOptional() - operation: any; - - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - @IsOptional() - keyOperation?: any; - - // @IsNotEmpty() - // @IsString() - // @ApiPropertyOptional() - // @IsOptional() - // keyOperationAttr?: any; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/find.organisation.dto.ts b/backend/services/src/shared/dto/find.organisation.dto.ts deleted file mode 100644 index d324f52bc..000000000 --- a/backend/services/src/shared/dto/find.organisation.dto.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { - ApiProperty, - } from "@nestjs/swagger"; - import { - IsArray, - IsInt, - } from "class-validator"; - - export class FindOrganisationQueryDto { - @ApiProperty() - @IsArray() - @IsInt({ each: true }) - companyIds: number[]; - } - \ No newline at end of file diff --git a/backend/services/src/shared/dto/forgotPassword.dto.ts b/backend/services/src/shared/dto/forgotPassword.dto.ts deleted file mode 100644 index 74de211cd..000000000 --- a/backend/services/src/shared/dto/forgotPassword.dto.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { - IsEmail, - isNotEmpty, - IsNotEmpty, - IsNumber, - IsString, -} from "class-validator"; - -export class ForgotPasswordDto { - @IsEmail() - @IsNotEmpty() - @ApiProperty() - email: string; -} diff --git a/backend/services/src/shared/dto/jwt.payload.ts b/backend/services/src/shared/dto/jwt.payload.ts deleted file mode 100644 index ddd26d05e..000000000 --- a/backend/services/src/shared/dto/jwt.payload.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Role } from "../casl/role.enum" -import { CompanyRole } from "../enum/company.role.enum" - -export class JWTPayload { - constructor( - public cn: string, - public n: string, - public sub: number, - public r: Role, - public cid: number, - public cr: CompanyRole, - public s: number - ) { - - } -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/login.dto.ts b/backend/services/src/shared/dto/login.dto.ts deleted file mode 100644 index 3ec9fd2af..000000000 --- a/backend/services/src/shared/dto/login.dto.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsEmail, isNotEmpty, IsNotEmpty, IsNumber, IsString } from "class-validator"; - -export class LoginDto { - @IsEmail() - @IsNotEmpty() - @ApiProperty() - username: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - password: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/mitigation.add.dto.ts b/backend/services/src/shared/dto/mitigation.add.dto.ts deleted file mode 100644 index 5cb469f2f..000000000 --- a/backend/services/src/shared/dto/mitigation.add.dto.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsNotEmpty, IsNotEmptyObject, IsString, ValidateNested } from "class-validator"; -import { MitigationProperties } from "./mitigation.properties"; - -export class MitigationAddDto { - - @IsNotEmpty() - @IsString() - @ApiProperty() - externalId: string; - - @ApiProperty() - @IsNotEmptyObject() - @ValidateNested() - @Type(() => MitigationProperties) - mitigation: MitigationProperties; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/mitigation.properties.ts b/backend/services/src/shared/dto/mitigation.properties.ts deleted file mode 100644 index e505866ea..000000000 --- a/backend/services/src/shared/dto/mitigation.properties.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsEnum, IsOptional, IsNumber, IsString } from "class-validator"; -import { TypeOfMitigation } from "../enum/typeofmitigation.enum"; - -export class MitigationProperties { - - @ApiProperty({ enum: TypeOfMitigation }) - @IsEnum(TypeOfMitigation, { - message: 'Invalid mitigation type. Supported following values:' + Object.values(TypeOfMitigation) - }) - @IsNotEmpty() - typeOfMitigation: TypeOfMitigation; - - @ApiPropertyOptional() - @IsNotEmpty() - @IsOptional() - @IsNumber() - userEstimatedCredits: number; - - @ApiProperty() - @IsNotEmpty() - @IsNumber() - systemEstimatedCredits: number; - - @ApiProperty() - @IsString() - @IsNotEmpty() - actionId: string; - - @ApiPropertyOptional() - @IsOptional() - @IsNotEmpty() - projectMaterial?: any[]; - - @ApiPropertyOptional() - @IsOptional() - properties: any; - - @ApiProperty() - @IsString() - @IsNotEmpty() - constantVersion: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/organisation.dto.ts b/backend/services/src/shared/dto/organisation.dto.ts deleted file mode 100644 index 9199d07a0..000000000 --- a/backend/services/src/shared/dto/organisation.dto.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { - IsEmail, - IsEnum, - IsNotEmpty, - IsNumber, - IsOptional, - IsString, - IsUrl, - MaxLength, - ValidateIf, - IsArray, - ArrayMinSize, -} from "class-validator"; -import { Role } from "../casl/role.enum"; -import { CompanyRole } from "../enum/company.role.enum"; -import { IsValidCountry } from "../util/validcountry.decorator"; -import { SectoralScope } from "@undp/serial-number-gen"; - -export class OrganisationDto { - companyId: number; - - @ValidateIf( - (c) => - ![CompanyRole.GOVERNMENT, CompanyRole.API, CompanyRole.MINISTRY].includes( - c.companyRole - ) - ) - @IsNotEmpty() - @IsString() - @ApiProperty() - taxId: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - name: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsNotEmpty() - @IsEmail() - @ApiProperty() - email: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - phoneNo: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsNotEmpty() - @IsUrl() - @IsOptional() - @ApiPropertyOptional() - website: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsNotEmpty() - @IsString() - @ApiPropertyOptional() - address: string; - - @IsString() - @IsNotEmpty() - @ApiPropertyOptional() - @MaxLength(1048576, { message: "Logo cannot exceed 1MB" }) - logo: string; - - @IsValidCountry() - @IsOptional() - @ApiPropertyOptional() - country: string; - - @IsNotEmpty() - @ApiProperty({ enum: CompanyRole }) - @IsEnum(CompanyRole, { - message: - "Invalid role. Supported following roles:" + Object.values(CompanyRole), - }) - companyRole: CompanyRole; - - @ValidateIf((c) => c.companyRole === CompanyRole.MINISTRY) - @IsNotEmpty() - @IsString() - @ApiProperty() - nameOfMinister: string; - - @ValidateIf((c) => c.companyRole === CompanyRole.MINISTRY) - @IsArray() - @ArrayMinSize(1) - @MaxLength(100, { each: true }) - @IsNotEmpty({ each: true }) - @IsEnum(SectoralScope, { - each: true, - message: - "Invalid sectoral scope. Supported following sectoral scope:" + - Object.values(SectoralScope), - }) - @ApiProperty({ - type: [String], - enum: Object.values(SectoralScope), - }) - sectoralScope: SectoralScope[]; - - createdTime: number; -} diff --git a/backend/services/src/shared/dto/organisation.suspend.dto.ts b/backend/services/src/shared/dto/organisation.suspend.dto.ts deleted file mode 100644 index f5d54d251..000000000 --- a/backend/services/src/shared/dto/organisation.suspend.dto.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ApiPropertyOptional } from "@nestjs/swagger"; -import { IsOptional, IsString } from "class-validator"; - -export class OrganisationSuspendDto { - @ApiPropertyOptional() - @IsString() - @IsOptional() - remarks: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/organisation.update.dto.ts b/backend/services/src/shared/dto/organisation.update.dto.ts deleted file mode 100644 index 3a96ec40d..000000000 --- a/backend/services/src/shared/dto/organisation.update.dto.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { - IsEmail, - IsEnum, - IsNotEmpty, - IsOptional, - IsString, - IsUrl, - MaxLength, - ValidateIf, -} from "class-validator"; -import { CompanyRole } from "../enum/company.role.enum"; - -export class OrganisationUpdateDto { - @IsNotEmpty() - @ApiProperty() - companyId: number; - - @IsNotEmpty() - @IsString() - @ApiProperty() - name: string; - - @ValidateIf( - (c) => - ![CompanyRole.GOVERNMENT, CompanyRole.API, CompanyRole.MINISTRY].includes( - c.companyRole - ) - ) - @IsNotEmpty() - @IsString() - @ApiProperty() - taxId: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsNotEmpty() - @IsEmail() - @ApiProperty() - email: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsUrl() - @IsOptional() - @ApiPropertyOptional() - website: string; - - @ValidateIf((c) => c.logo) - @ApiPropertyOptional() - @MaxLength(1048576, { message: "Logo cannot exceed 1MB" }) - logo: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsString() - @ApiPropertyOptional() - phoneNo: string; - - @ValidateIf( - (c) => ![CompanyRole.GOVERNMENT, CompanyRole.API].includes(c.companyRole) - ) - @IsString() - @ApiPropertyOptional() - address: string; - - @IsNotEmpty() - @ApiProperty({ enum: CompanyRole }) - @IsEnum(CompanyRole, { - message: - "Invalid role. Supported following roles:" + Object.values(CompanyRole), - }) - companyRole: CompanyRole; -} diff --git a/backend/services/src/shared/dto/ownership.update.ts b/backend/services/src/shared/dto/ownership.update.ts deleted file mode 100644 index 03f813fe6..000000000 --- a/backend/services/src/shared/dto/ownership.update.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { ArrayMinSize, IsArray, IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString } from "class-validator"; - -export class OwnershipUpdateDto { - - @ApiProperty() - @IsNotEmpty() - @IsString() - externalId: string; - - @ApiProperty() - @IsNotEmpty({ each: true }) - @IsArray() - @IsString({ each: true }) - @ArrayMinSize(1) - proponentTaxVatId: string[]; - - @ApiProperty() - @IsNotEmpty({ each: true }) - @IsArray() - @IsPositive({ each: true }) - @ArrayMinSize(1) - proponentPercentage: number[]; - - @ApiProperty() - @IsNotEmpty() - @IsString() - ownerTaxId: string; - - @ApiProperty() - @IsNotEmpty() - @IsString() - investorTaxId: string; - - @ApiProperty() - @IsNotEmpty() - @IsNumber() - shareFromOwner: number; - - -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/password.update.dto.ts b/backend/services/src/shared/dto/password.update.dto.ts deleted file mode 100644 index 01ea90007..000000000 --- a/backend/services/src/shared/dto/password.update.dto.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsString } from "class-validator"; - -export class PasswordUpdateDto { - - @IsNotEmpty() - @IsString() - @ApiProperty() - newPassword: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - oldPassword: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/passwordReset.dto.ts b/backend/services/src/shared/dto/passwordReset.dto.ts deleted file mode 100644 index 8542cd193..000000000 --- a/backend/services/src/shared/dto/passwordReset.dto.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsString } from "class-validator"; - -export class PasswordResetDto { - @IsNotEmpty() - @IsString() - @ApiProperty() - newPassword: string; -} diff --git a/backend/services/src/shared/dto/programme.accepted.dto.ts b/backend/services/src/shared/dto/programme.accepted.dto.ts deleted file mode 100644 index 7a395538d..000000000 --- a/backend/services/src/shared/dto/programme.accepted.dto.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsEnum, IsNotEmpty, IsNumber, IsOptional, IsString } from "class-validator"; - -export class ProgrammeAcceptedDto { - - @IsNotEmpty() - @IsString() - @ApiProperty() - data: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - externalId: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - type: string; - - @IsOptional() - @ApiProperty() - @IsNumber() - creditEst: number; - - @IsOptional() - @ApiPropertyOptional() - @IsString() - certifierTaxId: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.approve.ts b/backend/services/src/shared/dto/programme.approve.ts deleted file mode 100644 index 8264ec322..000000000 --- a/backend/services/src/shared/dto/programme.approve.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsPositive, IsNumber, IsString, Length, IsOptional, Min } from "class-validator"; - -export class ProgrammeApprove { - - @ApiProperty() - @IsNotEmpty() - @IsString() - programmeId: string; - - @ApiPropertyOptional() - @IsNumber() - @IsOptional() - @Min(0) - issueAmount: number; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.certify.ts b/backend/services/src/shared/dto/programme.certify.ts deleted file mode 100644 index 07623de9b..000000000 --- a/backend/services/src/shared/dto/programme.certify.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsPositive, IsNumber, IsString, Length, IsBoolean, IsOptional } from "class-validator"; - -export class ProgrammeCertify { - - @ApiProperty() - @IsNotEmpty() - @IsString() - programmeId: string; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; - - @ApiPropertyOptional() - @IsNumber() - @IsOptional() - certifierId: number; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.document.dto.ts b/backend/services/src/shared/dto/programme.document.dto.ts deleted file mode 100644 index 97d4df82a..000000000 --- a/backend/services/src/shared/dto/programme.document.dto.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsEnum, IsNotEmpty, IsNumber, IsOptional, IsString } from "class-validator"; - -export class ProgrammeDocumentDto { - - @IsNotEmpty() - @IsString() - @ApiProperty() - data: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - externalId: string; - - @IsNotEmpty() - @IsString() - @ApiProperty() - type: string; - - @IsOptional() - @ApiPropertyOptional() - @IsString() - actionId: string; - - @IsOptional() - @ApiPropertyOptional() - @IsString() - certifierTaxId: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.dto.ts b/backend/services/src/shared/dto/programme.dto.ts deleted file mode 100644 index 8963755f3..000000000 --- a/backend/services/src/shared/dto/programme.dto.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { ApiProperty, ApiPropertyOptional, getSchemaPath } from "@nestjs/swagger"; -import { ArrayMinSize, IsArray, IsEnum, IsInt, IsNotEmpty, IsNotEmptyObject, IsNumber, IsOptional, IsPositive, IsString, ValidateIf, ValidateNested } from "class-validator"; -import { SectoralScope } from '@undp/serial-number-gen' -import { TypeOfMitigation } from "../enum/typeofmitigation.enum"; -import { AgricultureProperties } from "./agriculture.properties"; -import { SolarProperties } from "./solar.properties"; -import { ProgrammeProperties } from "./programme.properties"; -import { Sector } from "../enum/sector.enum"; -import { Type } from "class-transformer"; -import { MitigationProperties } from "./mitigation.properties"; - -export class ProgrammeDto { - - @ApiProperty() - @IsNotEmpty() - @IsString() - title: string; - - @ApiProperty() - @IsNotEmpty() - @IsString() - externalId: string; - - @ApiProperty({ enum: SectoralScope }) - @IsNotEmpty() - @IsEnum(SectoralScope, { - message: 'Invalid sectoral scope. Supported following sectoral scope:' + Object.values(SectoralScope) - }) - sectoralScope: SectoralScope; - - @ApiProperty({ enum: Sector }) - @IsNotEmpty() - @IsEnum(Sector, { - message: 'Invalid sector. Supported following sector:' + Object.values(Sector) - }) - sector: Sector; - - // @ApiProperty({ enum: TypeOfMitigation }) - // @IsEnum(TypeOfMitigation, { - // message: 'Invalid mitigation type. Supported following values:' + Object.values(TypeOfMitigation) - // }) - // @IsNotEmpty() - // typeOfMitigation: TypeOfMitigation; - - @ApiProperty() - @IsNotEmpty() - @IsPositive() - @IsInt() - startTime: number; - - @ApiProperty() - @IsNotEmpty() - @IsPositive() - @IsInt() - endTime: number; - - @ApiProperty() - @IsNotEmpty({ each: true }) - @IsArray() - @IsString({ each: true }) - @ArrayMinSize(1) - proponentTaxVatId: string[]; - - @ApiPropertyOptional() - @IsOptional() - @IsNotEmpty({ each: true }) - @IsArray() - @IsPositive({ each: true }) - @ArrayMinSize(1) - proponentPercentage: number[]; - - @IsNotEmpty() - @IsOptional() - @IsString() - creditUnit: string; - - @ApiProperty() - @IsNotEmptyObject() - @ValidateNested() - @Type(() => ProgrammeProperties) - programmeProperties: ProgrammeProperties; - - // @ApiProperty() - // @ValidateIf(o => o.typeOfMitigation === TypeOfMitigation.AGRICULTURE) - // @IsNotEmptyObject() - // @ValidateNested() - // @Type(() => AgricultureProperties) - // agricultureProperties?: AgricultureProperties; - - // @ApiProperty() - // @ValidateIf(o => o.typeOfMitigation === TypeOfMitigation.SOLAR) - // @IsNotEmptyObject() - // @ValidateNested() - // @Type(() => SolarProperties) - // solarProperties?: SolarProperties; - - @ApiPropertyOptional({ - type: "array", - items: { - $ref: getSchemaPath(MitigationProperties), - } - }) - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => MitigationProperties) - mitigationActions?: MitigationProperties[] - - @ApiPropertyOptional() - @IsNotEmpty() - @IsOptional() - @IsNumber() - creditEst: number; -} diff --git a/backend/services/src/shared/dto/programme.history.dto.ts b/backend/services/src/shared/dto/programme.history.dto.ts deleted file mode 100644 index 9110f52cb..000000000 --- a/backend/services/src/shared/dto/programme.history.dto.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsNumber, IsString } from "class-validator"; -import { Programme } from "../entities/programme.entity"; -import { ProgrammeStage } from "../enum/programme-status.enum"; -import { QldbMetadata } from "./qldb.metadata"; - -export class ProgrammeHistoryDto { - metadata: QldbMetadata; - data: Programme -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.id.ts b/backend/services/src/shared/dto/programme.id.ts deleted file mode 100644 index cba7ab388..000000000 --- a/backend/services/src/shared/dto/programme.id.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsNumber, IsString } from "class-validator"; -import { ProgrammeStage } from "../enum/programme-status.enum"; - -export class ProgrammeIdDto { - @ApiProperty() - @IsNotEmpty() - @IsString() - serial: string; -} diff --git a/backend/services/src/shared/dto/programme.issue.ts b/backend/services/src/shared/dto/programme.issue.ts deleted file mode 100644 index 3805aadbb..000000000 --- a/backend/services/src/shared/dto/programme.issue.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsPositive, IsNumber, IsString, Length, IsOptional, Min } from "class-validator"; - -export class ProgrammeIssue { - - @ApiProperty() - @IsNotEmpty() - @IsString() - programmeId: string; - - @ApiPropertyOptional() - @IsNumber() - @IsOptional() - @Min(0) - issueAmount: number; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.properties.ts b/backend/services/src/shared/dto/programme.properties.ts deleted file mode 100644 index de8ac133f..000000000 --- a/backend/services/src/shared/dto/programme.properties.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { - IsNotEmpty, - IsString, - IsPositive, - IsInt, - IsNumber, - IsEnum, - MaxLength, - IsOptional, - ArrayMinSize, - IsArray, - IsUrl, -} from "class-validator"; -import { GHGs } from "../enum/ghgs.enum"; -import { SourceOfFunding } from "../enum/sourceoffinding.enum"; - -export class ProgrammeProperties { - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty() - maxInternationalTransferAmount?: string; - - @ApiPropertyOptional() - @IsPositive() - @IsInt() - @IsOptional() - @IsNotEmpty() - creditingPeriodInYears?: number; - - @ApiProperty() - @IsPositive() - @IsNumber() - @IsNotEmpty() - estimatedProgrammeCostUSD?: number; - - @ApiPropertyOptional({ enum: SourceOfFunding }) - @IsEnum(SourceOfFunding, { - message: - "Invalid source of funding. Supported following values:" + - Object.values(SourceOfFunding), - }) - @IsNotEmpty() - @IsOptional() - sourceOfFunding?: SourceOfFunding; - - @ApiPropertyOptional() - @IsPositive() - @IsNumber() - @IsOptional() - grantEquivalentAmount?: number; - - @ApiPropertyOptional() - @IsPositive() - @IsNumber() - @IsOptional() - carbonPriceUSDPerTon?: number; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - @IsNotEmpty() - buyerCountryEligibility?: string; - - @ApiProperty() - @IsArray() - @ArrayMinSize(1) - @MaxLength(100, { each: true }) - @IsNotEmpty({ each: true }) - geographicalLocation: string[]; - - @ApiProperty({ enum: GHGs, isArray: true }) - @IsEnum(GHGs, { - message: - "Invalid green house gas. Supported following values:" + - Object.values(GHGs), - each: true, - }) - @IsNotEmpty() - greenHouseGasses: GHGs[]; - - creditYear?: number; - - @ApiPropertyOptional() - @IsOptional() - @IsNotEmpty() - programmeMaterials?: any[]; - - // @ApiPropertyOptional() - // @IsOptional() - // @IsNotEmpty() - // projectMaterial?: any[]; -} diff --git a/backend/services/src/shared/dto/programme.reject.ts b/backend/services/src/shared/dto/programme.reject.ts deleted file mode 100644 index 724ec50c3..000000000 --- a/backend/services/src/shared/dto/programme.reject.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsString, Length } from "class-validator"; - -export class ProgrammeReject { - - @ApiProperty() - @IsNotEmpty() - @IsString() - programmeId: string; - - @ApiProperty() - @IsString() - @Length(0, 200) - comment: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.retire.ts b/backend/services/src/shared/dto/programme.retire.ts deleted file mode 100644 index 322c9698a..000000000 --- a/backend/services/src/shared/dto/programme.retire.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsArray, IsEnum, IsInt, IsNotEmpty, IsNotEmptyObject, IsNumber, IsOptional, IsPositive, IsString, Length, Min, ValidateIf, ValidateNested } from "class-validator"; -import { RetireType } from "../enum/retire.type.enum"; -import { BasicOrgInfo } from "./basic.organisation.dto"; - -export class ProgrammeRetire { - - @ApiProperty() - @IsNotEmpty() - @IsString() - programmeId: string; - - @ApiPropertyOptional() - @IsArray() - @IsInt({ each: true }) - @IsOptional() - fromCompanyIds: number[]; - - @ApiPropertyOptional() - @IsArray() - @Min(0, { each: true }) - @IsOptional() - companyCredit: number[]; - - // @ApiPropertyOptional() - // @IsNotEmpty() - // @IsNotEmpty() - // @IsOptional() - // toAccount: string; - - @ApiPropertyOptional() - @ValidateIf(o => o.type === RetireType.CROSS_BORDER) - @IsNotEmptyObject() - @ValidateNested() - @Type(() => BasicOrgInfo) - toCompanyMeta: BasicOrgInfo; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; - - @ApiProperty({ enum: RetireType }) - @IsNotEmpty() - @IsEnum(RetireType, { - message: 'Invalid retire type. Supported following sector:' + Object.values(RetireType) - }) - type: RetireType; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.revoke.ts b/backend/services/src/shared/dto/programme.revoke.ts deleted file mode 100644 index 9472a7f56..000000000 --- a/backend/services/src/shared/dto/programme.revoke.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsPositive, IsNumber, IsString, Length, IsBoolean, IsOptional } from "class-validator"; - -export class ProgrammeRevoke { - - @ApiProperty() - @IsNotEmpty() - @IsString() - programmeId: string; - - @ApiProperty() - @IsString() - @Length(0, 200) - comment: string; - - @ApiPropertyOptional() - @IsNumber() - @IsOptional() - certifierId: number; - -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.transfer.approve.ts b/backend/services/src/shared/dto/programme.transfer.approve.ts deleted file mode 100644 index 21af66f77..000000000 --- a/backend/services/src/shared/dto/programme.transfer.approve.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsArray, IsInt, IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString, Length, Min } from "class-validator"; - -export class ProgrammeTransferApprove { - - @ApiProperty() - @IsNotEmpty() - @IsNumber() - requestId: number; - - // @ApiPropertyOptional() - // @IsArray() - // @IsInt({ each: true }) - // @IsOptional() - // companyIds: number[]; - - // @ApiPropertyOptional() - // @IsArray() - // @IsNumber({},{each: true}) - // @Min(0, { each: true }) - // @IsOptional() - // companyCredit: number[]; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.transfer.cancel.ts b/backend/services/src/shared/dto/programme.transfer.cancel.ts deleted file mode 100644 index 606d91c1b..000000000 --- a/backend/services/src/shared/dto/programme.transfer.cancel.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString, Length } from "class-validator"; - -export class ProgrammeTransferCancel { - - @ApiProperty() - @IsNotEmpty() - @IsNumber() - requestId: number; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.transfer.reject.ts b/backend/services/src/shared/dto/programme.transfer.reject.ts deleted file mode 100644 index 859f32d63..000000000 --- a/backend/services/src/shared/dto/programme.transfer.reject.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString, Length } from "class-validator"; - -export class ProgrammeTransferReject { - - @ApiProperty() - @IsNotEmpty() - @IsNumber() - requestId: number; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programme.transfer.request.ts b/backend/services/src/shared/dto/programme.transfer.request.ts deleted file mode 100644 index e03d3c0eb..000000000 --- a/backend/services/src/shared/dto/programme.transfer.request.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsArray, IsInt, IsNotEmpty, IsNumber, IsOptional, IsPositive, IsString, Length, Min } from "class-validator"; - -export class ProgrammeTransferRequest { - - @ApiProperty() - @IsNotEmpty() - @IsString() - programmeId: string; - - @ApiPropertyOptional() - @IsArray() - @IsInt({ each: true }) - @IsOptional() - fromCompanyIds: number[]; - - @ApiPropertyOptional() - @IsArray() - @IsNumber({},{each: true}) - @Min(0, { each: true }) - @IsOptional() - companyCredit: number[]; - - @ApiProperty() - @IsNotEmpty() - @IsNumber() - toCompanyId: number; - - @ApiPropertyOptional() - @IsNotEmpty() - @IsNotEmpty() - @IsOptional() - toAccount: string; - - @ApiPropertyOptional() - @IsString() - @IsOptional() - comment: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/programmeStatus.request.dto.ts b/backend/services/src/shared/dto/programmeStatus.request.dto.ts deleted file mode 100644 index 32d251d9c..000000000 --- a/backend/services/src/shared/dto/programmeStatus.request.dto.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { - IsEmail, - isNotEmpty, - IsNotEmpty, - IsNumber, - IsOptional, - IsString, -} from "class-validator"; - -export class programmeStatusRequestDto { - type: any; - value?: string; - companyId?: any; - startTime?: any; - endTime?: any; -} diff --git a/backend/services/src/shared/dto/programmeStatus.timeGrouped.result.ts b/backend/services/src/shared/dto/programmeStatus.timeGrouped.result.ts deleted file mode 100644 index 2bd6b6203..000000000 --- a/backend/services/src/shared/dto/programmeStatus.timeGrouped.result.ts +++ /dev/null @@ -1,16 +0,0 @@ -export class StatusGroupedByTimedata { - awaitingAuthorization: any[]; - authorised: any[]; - rejected: any[]; - authorisedCredits: any[]; - issuedCredits: any[]; - transferredCredits: any[]; - retiredCredits: any[]; - frozenCredits: any[]; -} - -export class StatusGroupedByTimedataThere { - awaitingAuthorization: boolean; - authorised: boolean; - rejected: boolean; -} diff --git a/backend/services/src/shared/dto/qldb.metadata.ts b/backend/services/src/shared/dto/qldb.metadata.ts deleted file mode 100644 index 020b55a7c..000000000 --- a/backend/services/src/shared/dto/qldb.metadata.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsNumber, IsString } from "class-validator"; -import { ProgrammeStage } from "../enum/programme-status.enum"; - -export class QldbMetadata { - id: string; - version: number; - txTime: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/query.dto.ts b/backend/services/src/shared/dto/query.dto.ts deleted file mode 100644 index 918c9f6e4..000000000 --- a/backend/services/src/shared/dto/query.dto.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { - ApiProperty, - ApiPropertyOptional, - getSchemaPath, -} from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { - IsInt, - IsNumber, - IsOptional, - IsPositive, - ValidateNested, -} from "class-validator"; -import { FilterEntry } from "./filter.entry"; -import { SortEntry } from "./sort.entry"; -import { FilterBy } from "./filter.by"; - -export class QueryDto { - @IsPositive() - @IsInt() - @Type(() => Number) - @ApiProperty() - page: number; - - @IsPositive() - @IsInt() - @Type(() => Number) - @ApiProperty() - size: number; - - @ApiPropertyOptional({ - type: "array", - example: [{ key: "age", operation: "gt", value: 25 }], - items: { - $ref: getSchemaPath(FilterEntry), - }, - }) - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => FilterEntry) - filterAnd: FilterEntry[]; - - @ApiPropertyOptional({ - type: "array", - example: [{ key: "age", operation: "gt", value: 25 }], - items: { - $ref: getSchemaPath(FilterEntry), - }, - }) - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => FilterEntry) - filterOr: FilterEntry[]; - - @ApiPropertyOptional({ - type: "object", - example: { key: "name", order: "asc" }, - items: { - $ref: getSchemaPath(SortEntry), - }, - }) - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => SortEntry) - sort: SortEntry; - - @ApiPropertyOptional({ - type: "object", - example: { key: "ministryLevel", values: ['1', '2'] }, - items: { - $ref: getSchemaPath(FilterEntry), - }, - }) - @IsOptional() - @ValidateNested({ each: true }) - @Type(() => FilterBy) - filterBy: FilterBy; -} diff --git a/backend/services/src/shared/dto/settings.dto.ts b/backend/services/src/shared/dto/settings.dto.ts deleted file mode 100644 index a8d89d818..000000000 --- a/backend/services/src/shared/dto/settings.dto.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsString } from "class-validator"; -import { AnyAaaaRecord } from "dns"; - -export class SettingsDto { - @IsNotEmpty() - @ApiProperty() - id: number; - - @IsNotEmpty() - @IsString() - @ApiProperty() - settingValue: string; -} diff --git a/backend/services/src/shared/dto/solar.constants.dto.ts b/backend/services/src/shared/dto/solar.constants.dto.ts deleted file mode 100644 index 7dd0db650..000000000 --- a/backend/services/src/shared/dto/solar.constants.dto.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNumber, IsString } from "class-validator"; - -export class SolarConstantsDto { - - @ApiProperty() - @IsNumber() - highEmissionFactor: number; - - @ApiProperty() - @IsNumber() - lowEmissionFactor: number; - - @ApiProperty() - @IsString() - emissionFactorUnit: string; - - @ApiProperty() - @IsString() - thresholdUnit: string; - - @ApiProperty({ - type: 'object', - additionalProperties: { - oneOf: [ - { type: 'number' } - ] - } - }) - buildingTypes: { [k: string]: number }; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/solar.properties.ts b/backend/services/src/shared/dto/solar.properties.ts deleted file mode 100644 index 9a9065aa4..000000000 --- a/backend/services/src/shared/dto/solar.properties.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { BuildingType } from "@undp/carbon-credit-calculator"; -import { IsNotEmpty, IsPositive, IsNumber, IsEnum } from "class-validator"; -import { MitigationProperties } from "./mitigation.properties"; - -export class SolarProperties extends MitigationProperties { - - @ApiProperty() - @IsNotEmpty() - @IsPositive() - @IsNumber() - energyGeneration: number; - - @ApiProperty({default: "kWh/year/unit"}) - @IsNotEmpty() - energyGenerationUnit: string; - - @ApiProperty({ enum: BuildingType }) - @IsEnum(BuildingType, { - message: 'Invalid consumer group. Supported following values:' + Object.values(BuildingType) - }) - consumerGroup: BuildingType; -} \ No newline at end of file diff --git a/backend/services/src/shared/dto/sort.entry.ts b/backend/services/src/shared/dto/sort.entry.ts deleted file mode 100644 index 20ffc0a7b..000000000 --- a/backend/services/src/shared/dto/sort.entry.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { - IsInt, - IsNotEmpty, - IsNumber, - IsPositive, - IsString, -} from "class-validator"; - -export class SortEntry { - @IsNotEmpty() - @ApiProperty() - key: any; - - @IsNotEmpty() - @ApiProperty() - order: any; - - @ApiPropertyOptional() - nullFirst?: boolean; -} diff --git a/backend/services/src/shared/dto/stat.dto.ts b/backend/services/src/shared/dto/stat.dto.ts deleted file mode 100644 index 0d3c36e8c..000000000 --- a/backend/services/src/shared/dto/stat.dto.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { IsEnum } from "class-validator"; -import { EntitySubject } from "../entities/entity.subject"; -import { StatType } from "../enum/stat.type.enum"; -import { StatFilter } from "./stat.filter"; - -export class Stat extends EntitySubject { - @ApiProperty({ enum: StatType }) - @IsEnum(StatType, { - message: - "Invalid stat type. Support following values:" + Object.values(StatType), - }) - type: StatType; - value?: any; - data?: any; - - key?: string; - - @ApiPropertyOptional() - @Type(() => StatFilter) - statFilter: StatFilter; -} diff --git a/backend/services/src/shared/dto/stat.filter.ts b/backend/services/src/shared/dto/stat.filter.ts deleted file mode 100644 index 35cc8751e..000000000 --- a/backend/services/src/shared/dto/stat.filter.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ApiPropertyOptional } from "@nestjs/swagger"; -import { IsNotEmpty, IsOptional } from "class-validator"; - -export class StatFilter { - - @ApiPropertyOptional() - @IsOptional() - onlyMine?: boolean; - - @ApiPropertyOptional() - @IsOptional() - startTime?: number; - - @ApiPropertyOptional() - @IsOptional() - endTime?: number; - - @ApiPropertyOptional() - @IsOptional() - timeGroup?: boolean; -} diff --git a/backend/services/src/shared/dto/stat.list.dto.ts b/backend/services/src/shared/dto/stat.list.dto.ts deleted file mode 100644 index a39e14b67..000000000 --- a/backend/services/src/shared/dto/stat.list.dto.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { - IsNotEmptyObject, - IsNumber, - IsObject, - IsOptional, - IsPositive, - ValidateNested, -} from "class-validator"; -import { Stat } from "./stat.dto"; - -export class StatList { - @ApiProperty({ isArray: true, type: Stat }) - @ValidateNested({ each: true }) - @Type(() => Stat) - stats: Stat[]; - - @ApiProperty() - category: string; - - @IsPositive() - @IsNumber() - @ApiPropertyOptional() - @IsOptional() - startTime: number; - - @IsPositive() - @IsNumber() - @ApiPropertyOptional() - @IsOptional() - endTime: number; -} diff --git a/backend/services/src/shared/dto/user.dto.ts b/backend/services/src/shared/dto/user.dto.ts deleted file mode 100644 index 0da104005..000000000 --- a/backend/services/src/shared/dto/user.dto.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { Type } from "class-transformer"; -import { - IsEmail, - IsEnum, - IsNotEmpty, - IsNotEmptyObject, - IsNumber, - IsObject, - IsOptional, - IsString, - ValidateIf, - ValidateNested, -} from "class-validator"; -import { Role } from "../casl/role.enum"; -import MutuallyExclusive from "../util/mutualexclusive.decorator"; -import { OrganisationDto } from "./organisation.dto"; - -export class UserDto { - @IsNotEmpty() - @IsEmail() - @ApiProperty() - email: string; - - @IsNotEmpty() - @ApiProperty({ enum: Role }) - @IsEnum(Role, { - message: "Invalid role. Supported following roles:" + Object.values(Role), - }) - role: Role; - - @IsNotEmpty() - @IsString() - @ApiProperty() - name: string; - - @IsString() - @ApiPropertyOptional() - @IsNotEmpty() - @IsOptional() - phoneNo: string; - - @IsNotEmptyObject() - @ApiPropertyOptional() - @IsOptional() - @ValidateNested() - @Type(() => OrganisationDto) - @MutuallyExclusive("company") - company: OrganisationDto; - - @IsNumber() - @ApiPropertyOptional() - @IsNotEmpty() - @IsOptional() - @MutuallyExclusive("company") - companyId: number; - - password: string; - - apiKey?: string; -} diff --git a/backend/services/src/shared/dto/user.update.dto.ts b/backend/services/src/shared/dto/user.update.dto.ts deleted file mode 100644 index 8af3a89a1..000000000 --- a/backend/services/src/shared/dto/user.update.dto.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsEmail, IsEnum, isNotEmpty, IsNotEmpty, IsNumber, IsOptional, IsString } from "class-validator"; -import { Role } from "../casl/role.enum"; - -export class UserUpdateDto { - - @IsNotEmpty() - @IsNumber() - @ApiProperty() - id: number; - - @IsNotEmpty() - @IsString() - @IsOptional() - @ApiProperty() - name: string; - - @IsString() - @IsOptional() - @ApiPropertyOptional() - phoneNo: string; - - @IsOptional() - @IsEmail() - @ApiPropertyOptional() - email: string; - - @IsOptional() - @ApiPropertyOptional({ enum: Role }) - @IsEnum(Role, { - message: 'Invalid role. Supported following roles:' + Object.values(Role) - }) - role: Role; -} - diff --git a/backend/services/src/shared/email-helper/email-helper.module.ts b/backend/services/src/shared/email-helper/email-helper.module.ts deleted file mode 100644 index 504d02780..000000000 --- a/backend/services/src/shared/email-helper/email-helper.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { forwardRef, Module } from '@nestjs/common'; -import { AsyncOperationsModule } from '../async-operations/async-operations.module'; -import { CompanyModule } from '../company/company.module'; -import { ProgrammeLedgerModule } from '../programme-ledger/programme-ledger.module'; -import { UserModule } from '../user/user.module'; -import { UtilModule } from '../util/util.module'; -import { EmailHelperService } from './email-helper.service'; - -@Module({ - providers: [EmailHelperService], - exports: [EmailHelperService], - imports: [forwardRef(() => UserModule), ProgrammeLedgerModule, forwardRef(() => CompanyModule), AsyncOperationsModule, UtilModule] -}) -export class EmailHelperModule {} diff --git a/backend/services/src/shared/email-helper/email-helper.service.ts b/backend/services/src/shared/email-helper/email-helper.service.ts deleted file mode 100644 index 6ba6b78a1..000000000 --- a/backend/services/src/shared/email-helper/email-helper.service.ts +++ /dev/null @@ -1,420 +0,0 @@ -import { forwardRef, Inject, Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { - AsyncAction, - AsyncOperationsInterface, -} from "../async-operations/async-operations.interface"; -import { CompanyService } from "../company/company.service"; -import { Company } from "../entities/company.entity"; -import { Programme } from "../entities/programme.entity"; -import { AsyncActionType } from "../enum/async.action.type.enum"; -import { ProgrammeLedgerService } from "../programme-ledger/programme-ledger.service"; -import { UserService } from "../user/user.service"; -import { HelperService } from "../util/helpers.service"; - -@Injectable() -export class EmailHelperService { - isEmailDisabled: boolean; - - constructor( - @Inject(forwardRef(() => UserService)) - private userService: UserService, - private configService: ConfigService, - @Inject(forwardRef(() => CompanyService)) - private companyService: CompanyService, - private programmeLedger: ProgrammeLedgerService, - private asyncOperationsInterface: AsyncOperationsInterface, - private helperService: HelperService - ) { - this.isEmailDisabled = this.configService.get( - "email.disableLowPriorityEmails" - ); - } - - public async sendEmailToProgrammeOwnerAdmins( - programmeId: string, - template: any, - templateData: {}, - companyId?: number, - governmentId?: number - ) { - if (this.isEmailDisabled) return; - const programme = await this.programmeLedger.getProgrammeById(programmeId); - const hostAddress = this.configService.get("host"); - let companyDetails: Company; - - switch (template.id) { - case "PROGRAMME_REJECTION": - let authDate = new Date(programme.txTime); - let date = authDate.getDate().toString().padStart(2, "0"); - let month = authDate.toLocaleString("default", { month: "long" }); - let year = authDate.getFullYear(); - let formattedDate = `${date} ${month} ${year}`; - - templateData = { - ...templateData, - programmeName: programme.title, - date: formattedDate, - pageLink: hostAddress + `/programmeManagement/view?id=${programmeId}`, - }; - break; - - case "PROGRAMME_CERTIFICATION": - companyDetails = await this.companyService.findByCompanyId(companyId); - templateData = { - ...templateData, - programmeName: programme.title, - credits: programme.creditBalance, - serialNumber: programme.serialNo, - organisationName: companyDetails.name, - pageLink: hostAddress + `/programmeManagement/view?id=${programmeId}`, - }; - break; - - case "PROGRAMME_CERTIFICATION_REVOKE_BY_CERT": - companyDetails = await this.companyService.findByCompanyId(companyId); - templateData = { - ...templateData, - programmeName: programme.title, - credits: programme.creditBalance, - serialNumber: programme.serialNo, - organisationName: companyDetails.name, - pageLink: hostAddress + `/programmeManagement/view?id=${programmeId}`, - }; - break; - - case "PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_PROGRAMME": - companyDetails = await this.companyService.findByCompanyId(companyId); - const government = await this.companyService.findByCompanyId( - governmentId - ); - templateData = { - ...templateData, - programmeName: programme.title, - credits: programme.creditBalance, - serialNumber: programme.serialNo, - organisationName: companyDetails.name, - government: government.name, - pageLink: hostAddress + `/programmeManagement/view?id=${programmeId}`, - }; - break; - - default: - break; - } - - programme.companyId.forEach(async (companyId: number) => { - this.sendEmailToOrganisationAdmins(companyId, template, templateData); - }); - } - - public async sendEmailToOrganisationAdmins( - companyId: number, - template, - templateData: any, - receiverCompanyId?: number, - programmeId?: string, - initiatorCompanyId?: number - ) { - if (this.isEmailDisabled) return; - const systemCountryName = this.configService.get("systemCountryName"); - const users = await this.userService.getOrganisationAdminAndManagerUsers( - companyId - ); - let companyDetails: Company; - let inititatorCompanyDetails: Company; - let programme: Programme; - const hostAddress = this.configService.get("host"); - - switch (template.id) { - case "CREDIT_TRANSFER_GOV": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - templateData = { - ...templateData, - organisationName: companyDetails.name, - }; - break; - - case "CREDIT_TRANSFER_CANCELLATION": - programme = await this.programmeLedger.getProgrammeById(programmeId); - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - templateData = { - ...templateData, - organisationName: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_TRANSFER_ACCEPTED": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - programme = await this.programmeLedger.getProgrammeById(programmeId); - templateData = { - ...templateData, - organisationName: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_TRANSFER_REJECTED": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - programme = await this.programmeLedger.getProgrammeById(programmeId); - templateData = { - ...templateData, - organisationName: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_TRANSFER_GOV_CANCELLATION": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - programme = await this.programmeLedger.getProgrammeById(programmeId); - templateData = { - ...templateData, - organisationName: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_TRANSFER_GOV_ACCEPTED_TO_RECEIVER": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - programme = await this.programmeLedger.getProgrammeById(programmeId); - templateData = { - ...templateData, - organisationName: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_CERT": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - programme = await this.programmeLedger.getProgrammeById(programmeId); - templateData = { - ...templateData, - government: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - credits: programme.creditBalance, - pageLink: hostAddress + `/programmeManagement/view?id=${programmeId}`, - }; - break; - - case "CREDIT_RETIREMENT_RECOGNITION": - programme = await this.programmeLedger.getProgrammeById(programmeId); - templateData = { - ...templateData, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_RETIREMENT_NOT_RECOGNITION": - programme = await this.programmeLedger.getProgrammeById(programmeId); - templateData = { - ...templateData, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_TRANSFER_CANCELLATION_SYS_TO_SENDER": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - inititatorCompanyDetails = await this.companyService.findByCompanyId( - initiatorCompanyId - ); - templateData = { - ...templateData, - organisationName: companyDetails.name, - initiatorOrganisationName: inititatorCompanyDetails.name, - }; - break; - - case "CREDIT_TRANSFER_CANCELLATION_SYS_TO_INITIATOR": - companyDetails = await this.companyService.findByCompanyId( - receiverCompanyId - ); - templateData = { - ...templateData, - organisationName: companyDetails.name, - }; - break; - - default: - break; - } - - users.forEach(async (user: any) => { - templateData = { - ...templateData, - name: user.user_name, - countryName: systemCountryName, - }; - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: template.id, - sender: user.user_email, - subject: this.helperService.getEmailTemplateMessage( - template["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - template["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - }); - } - - public async sendEmailToGovernmentAdmins( - template, - templateData: any, - programmeId?: string, - companyId?: number - ) { - if (this.isEmailDisabled) return; - const systemCountryName = this.configService.get("systemCountryName"); - const hostAddress = this.configService.get("host"); - const users = await this.userService.getGovAdminAndManagerUsers(); - let programme: Programme; - let companyDetails: Company; - if (programmeId) - programme = await this.programmeLedger.getProgrammeById(programmeId); - - switch (template.id) { - case "CREDIT_TRANSFER_GOV_ACCEPTED_TO_INITIATOR": - companyDetails = await this.companyService.findByCompanyId(companyId); - templateData = { - ...templateData, - organisationName: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_TRANSFER_GOV_REJECTED": - companyDetails = await this.companyService.findByCompanyId(companyId); - templateData = { - ...templateData, - organisationName: companyDetails.name, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_RETIREMENT_CANCEL": - companyDetails = await this.companyService.findByCompanyId(companyId); - templateData = { - ...templateData, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }; - break; - - case "CREDIT_RETIREMENT_CANCEL_SYS_TO_GOV": - companyDetails = await this.companyService.findByCompanyId(companyId); - templateData = { - ...templateData, - organisationName: companyDetails.name, - }; - break; - - default: - break; - } - - users.forEach(async (user: any) => { - templateData = { - ...templateData, - name: user.user_name, - countryName: systemCountryName, - }; - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: template.id, - sender: user.user_email, - subject: this.helperService.getEmailTemplateMessage( - template["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - template["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - }); - } - - public async sendEmail( - sender: string, - template, - templateData: any, - companyId: number - ) { - if (this.isEmailDisabled) return; - const companyDetails = await this.companyService.findByCompanyId(companyId); - const systemCountryName = this.configService.get("systemCountryName"); - templateData = { - ...templateData, - countryName: systemCountryName, - government: companyDetails.name, - }; - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: template.id, - sender: sender, - subject: this.helperService.getEmailTemplateMessage( - template["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - template["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - } -} diff --git a/backend/services/src/shared/email-helper/email.template.ts b/backend/services/src/shared/email-helper/email.template.ts deleted file mode 100644 index 4576ad172..000000000 --- a/backend/services/src/shared/email-helper/email.template.ts +++ /dev/null @@ -1,522 +0,0 @@ -export const EmailTemplates = { - ORGANISATION_CREATE: { - id: "ORGANISATION_CREATE", - subject: "Welcome!", - html: ` - Welcome {{organisationName}},

- Your Organisation has been registered with the {{countryName}} Carbon Registry as a {{organisationRole}} Organisation.

- Explore the Registry here {{home}}.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - USER_CREATE: { - id: "USER_CREATE", - subject: "Welcome!", - html: ` - Welcome {{name}},

- - Thank you for supporting the {{countryName}} Carbon Registry.

- - Your account has been created on: {{home}}
- User: {{email}}
- Password (temporary): {{tempPassword}}

- - If you have any questions, feel free to email our customer success team. - We also offer help documentation and chat. -

- - Sincerely,
- The {{countryName}} Carbon Registry Team

- -
- {{countryName}}
- Address
- Region, Country Zipcode -
- `, - text: "", - }, - API_KEY_EMAIL: { - id: "API_KEY_EMAIL", - subject: "Carbon Credit Registry API Key Generation", - html: ` - Hi {{name}},

- - You carbon registry account api key regenerated - {{apiKey}}. -

- Sincerely,
- The Carbon Credit Registry Team - `, - text: "", - }, - RETIRE_REQUEST: { - subject: "Retire Request Received", - html: ` - Hi {{name}},

- - {{requestedCompany}} has requested to retire {{credits}} credits with the serial number {{serialNo}} from {{programmeName}}. - -

- Sincerely,
- The Carbon Credit Registry Team - `, - text: "", - }, - CHANGE_PASSOWRD: { - id: "CHANGE_PASSOWRD", - subject: "Your Password was Changed", - html: ` - Hi {{name}},

- The password of your Carbon Registry account was changed successfully.

- If you do not use {{countryName}} Carbon Credit Registry or did not request a password reset, please ignore this email or - contact support - if you have questions. - -

- Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - text: "", - }, - FORGOT_PASSOWRD: { - id: "FORGOT_PASSOWRD", - subject: "Password Reset Request", - html: ` - Hi {{name}},

- We received a request to reset your Carbon Registry password.

- Use the link below to set a new password for your account. This password reset is only valid for the next hour. -

- - Click here to reset the password -

- - If you do not use {{countryName}} Carbon Credit Registry or did not request a password reset, please ignore this email or - contact support - if you have questions. - -

- Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - text: "", - }, - PROGRAMME_CREATE: { - id: "PROGRAMME_CREATE", - subject: "New Programme Received for Authorisation", - html: ` - Hi {{name}},

- - A new programme owned by {{organisationName}} is awaiting authorisation.

- - Click here to access all the programmes that require authorisation. -

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_AUTHORISATION: { - id: "PROGRAMME_AUTHORISATION", - subject: "Programme Authorised", - html: ` - Hi {{name}},

- - {{programmeName}} of your Organisation has been authorised on {{authorisedDate}} with the serial number {{serialNumber}}. -

- - Click here for more details of the programme. -

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_REJECTION: { - id: "PROGRAMME_REJECTION", - subject: "Programme Rejected", - html: ` - Hi {{name}},

- - {{programmeName}} of your Organisation has been rejected on {{date}} due to the following reason/s:
- {{reason}}

- - Click here for more details of the programme.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_ISSUANCE: { - id: "CREDIT_ISSUANCE", - subject: "Credits Issued", - html: ` - Hi {{name}},

- - {{programmeName}} of your Organisation with the serial number {{serialNumber}} has been issued with {{credits}} credits.

- - Click here for more details of the programme.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_REQUISITIONS: { - id: "CREDIT_TRANSFER_REQUISITIONS", - subject: "Transfer Request Received", - html: ` - Hi {{name}},

- - {{organisationName}} has requested to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}}.

- Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_CANCELLATION: { - id: "CREDIT_TRANSFER_CANCELLATION", - subject: "Transfer Request Cancelled", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} made by {{organisationName}} has been cancelled.

- Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_CANCELLATION_SYS_TO_INITIATOR: { - id: "CREDIT_TRANSFER_CANCELLATION_SYS_TO_INITIATOR", - subject: "Transfer Request Cancelled by the System", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to {{organisationName}} made by your Organisation has been cancelled due to insufficient credits available.

- Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_CANCELLATION_SYS_TO_SENDER: { - id: "CREDIT_TRANSFER_CANCELLATION_SYS_TO_SENDER", - subject: "Transfer Request Cancelled by the System", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to {{organisationName}} made by {{initiatorOrganisationName}} has been cancelled due to insufficient credits available.

- Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_ACCEPTED: { - id: "CREDIT_TRANSFER_ACCEPTED", - subject: "Transfer Request Accepted", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} made by your Organisation has been accepted by {{organisationName}}.

- Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_REJECTED: { - id: "CREDIT_TRANSFER_REJECTED", - subject: "Transfer Request Rejected", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} - made by your Organisation has been rejected by {{organisationName}}.

- Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team`, - }, - CREDIT_TRANSFER_GOV: { - id: "CREDIT_TRANSFER_GOV", - subject: "Transfer Request Received", - html: ` - Hi {{name}},

- - {{government}} has requested your Organisation to transfer {{credits}} credits with the serial number {{serialNumber}} - from {{programmeName}} to {{organisationName}}.

- - Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_GOV_CANCELLATION: { - id: "CREDIT_TRANSFER_GOV_CANCELLATION", - subject: "Transfer Request Cancelled", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} - to {{organisationName}} made by {{government}} has been cancelled.

- - Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_GOV_ACCEPTED_TO_INITIATOR: { - id: "CREDIT_TRANSFER_GOV_ACCEPTED_TO_INITIATOR", - subject: "Transfer Request Accepted", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} made by your Organisation has been accepted by {{organisationName}}.

- Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_GOV_ACCEPTED_TO_RECEIVER: { - id: "CREDIT_TRANSFER_GOV_ACCEPTED_TO_RECEIVER", - subject: "Credits Received", - html: ` - Hi {{name}},

- - {{organisationName}} has transferred {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to your Organisation by accepting the request made by the {{government}}.

- Click here for more details of the transfer request

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_TRANSFER_GOV_REJECTED: { - id: "CREDIT_TRANSFER_GOV_REJECTED", - subject: "Transfer Request Rejected", - html: ` - Hi {{name}},

- - Request to transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} made by your Organisation has been rejected by {{organisationName}}.

- Click here for more details of the transfer request

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_SEND_DEVELOPER: { - id: "CREDIT_SEND_DEVELOPER", - subject: "Credits Received", - html: ` - Hi {{name}},

- - {{organisationName}} has transferred {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to your Organisation.

- - Click here for more details of the transfer request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_CERTIFICATION: { - id: "PROGRAMME_CERTIFICATION", - subject: "Programme Certified by {{organisationName}}", - html: ` - Hi {{name}},

- - The {{programmeName}} containing {{credits}} credits with the serial number {{serialNumber}} of your Organisation has been certified by {{organisationName}}.

- Click here for more details of the certification.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_CERTIFICATION_REVOKE_BY_CERT: { - id: "PROGRAMME_CERTIFICATION_REVOKE_BY_CERT", - subject: "Programme Certificate Revoked by {{organisationName}}", - html: ` - Hi {{name}},

- - The certification of the programme {{programmeName}} containing {{credits}} credits with the serial number {{serialNumber}} has been revoked by {{organisationName}}.

- Click here for more details of the certification.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_PROGRAMME: { - id: "PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_PROGRAMME", - subject: "Programme Certificate Revoked by {{government}}", - html: ` - Hi {{name}},

- - The certification given by {{organisationName}} for the programme {{programmeName}} containing {{credits}} credits with the serial number {{serialNumber}} has been revoked by the {{government}}.

- Click here for more details of the certification.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_CERT: { - id: "PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_CERT", - subject: "Programme Certificate Revoked by {{government}}", - html: ` - Hi {{name}},

- - The certification given by your Organisation for the programme {{programmeName}} containing {{credits}} credits with the serial number {{serialNumber}} has been revoked by the {{government}}.

- Click here for more details of the certification.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_CERTIFICATION_REVOKE_BY_SYSTEM: { - id: "PROGRAMME_CERTIFICATION_REVOKE_BY_SYSTEM", - subject: "Programme Certificate Revoked by the System", - html: ` - Hi {{name}},

- - The certification given by {{organisationName}} for the programme {{programmeName}} containing {{credits}} credits with the serial number {{serialNumber}} has been revoked by the system as {{organisationName}} was deactivated.

- Click here for more details of the certification.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - PROGRAMME_DEVELOPER_ORG_DEACTIVATION: { - id: "PROGRAMME_DEVELOPER_ORG_DEACTIVATION", - subject: "Organisation Deactivated", - html: ` - Hi,

- - Your Organisation has been deactivated by the {{government}}. Your Organisation will still be visible but no further action will be able to take place. Following were the effects of deactivation:

- · All the users of the Organisation were deactivated.
- · All the credits owned by your Organisation were frozen.
- · All credit transfer requests sent and received by your Organisation were cancelled.
- · All the international transfer retire requests sent by your Organisation were cancelled.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CERTIFIER_ORG_DEACTIVATION: { - id: "CERTIFIER_ORG_DEACTIVATION", - subject: "Organisation Deactivated", - html: ` - Hi,

- - Your Organisation has been deactivated by the {{government}}. Your Organisation will still be visible but no further action will be able to take place. Following are the effects of deactivation:

- · All the users of the Organisation were deactivated.
- · All the certificates given by your Organisation were revoked.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_RETIREMENT_BY_GOV: { - id: "CREDIT_RETIREMENT_BY_GOV", - subject: "Credits Retired", - html: ` - Hi {{name}},

- - {{credits}} credits of the programme {{programmeName}} with the serial number {{serialNumber}} has been retired by the {{government}} as {{reason}}.

- Click here for more details of the retirement.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_RETIREMENT_BY_DEV: { - id: "CREDIT_RETIREMENT_BY_DEV", - subject: "International Transfer Retire Request Received", - html: ` - Hi {{name}},

- - {{organisationName}} has requested an international transfer retirement of {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}}.

- Click here for more details of the international transfer retire request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_RETIREMENT_CANCEL: { - id: "CREDIT_RETIREMENT_CANCEL", - subject: "International Transfer Retire Request Cancelled", - html: ` - Hi {{name}},

- - Request to internationally transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to {{country}} made by {{organisationName}} has been cancelled.

- Click here for more details of the international transfer retire request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_RETIREMENT_CANCEL_SYS_TO_INITIATOR: { - id: "CREDIT_RETIREMENT_CANCEL_SYS_TO_INITIATOR", - subject: "International Transfer Retire Request Cancelled by the System", - html: ` - Hi {{name}},

- Request to internationally transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to {{country}} made by your Organisation has been cancelled by the system due to insufficient credits available.

- Click here for more details of the international transfer retire request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_RETIREMENT_CANCEL_SYS_TO_GOV: { - id: "CREDIT_RETIREMENT_CANCEL_SYS_TO_GOV", - subject: "International Transfer Retire Request Cancelled by the System", - html: ` - Hi {{name}},

- Request to internationally transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to {{country}} made by {{organisationName}} has been cancelled by the system due to insufficient credits available.

- Click here for more details of the international transfer retire request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_RETIREMENT_RECOGNITION: { - id: "CREDIT_RETIREMENT_RECOGNITION", - subject: "International Transfer Retire Request Recognised", - html: ` - Hi {{name}},

- - Request to internationally transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to {{country}} made by your Organisation has been recognised.

- Click here for more details of the international transfer retire request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - CREDIT_RETIREMENT_NOT_RECOGNITION: { - id: "CREDIT_RETIREMENT_NOT_RECOGNITION", - subject: "International Transfer Retire Request Not Recognised", - html: ` - Hi {{name}},

- - Request to internationally transfer {{credits}} credits with the serial number {{serialNumber}} from {{programmeName}} to {{country}} made by your Organisation has not been recognised.

- Click here for more details of the international transfer retire request.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, - ORG_REACTIVATION: { - id: "ORG_REACTIVATION", - subject: "Organisation Reactivated", - html: ` - Hi

- - Your Organisation has been reactivated by the {{government}}. Your Organisation will be able to perform actions as before and all the users of the Organisation will be reactivated.

- - Sincerely,
- The {{countryName}} Carbon Credit Registry Team - `, - }, -}; diff --git a/backend/services/src/shared/email/email.module.ts b/backend/services/src/shared/email/email.module.ts deleted file mode 100644 index 51210c627..000000000 --- a/backend/services/src/shared/email/email.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Logger, Module } from "@nestjs/common"; -import { EmailService } from "./email.service"; - -@Module({ - providers: [EmailService, Logger], - exports: [EmailService], -}) -export class EmailModule {} diff --git a/backend/services/src/shared/email/email.service.spec.ts b/backend/services/src/shared/email/email.service.spec.ts deleted file mode 100644 index c5e9129b8..000000000 --- a/backend/services/src/shared/email/email.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from "@nestjs/testing"; -import { EmailService } from "./email.service"; - -describe("EmailService", () => { - let service: EmailService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [EmailService], - }).compile(); - - service = module.get(EmailService); - }); - - it("should be defined", () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/email/email.service.ts b/backend/services/src/shared/email/email.service.ts deleted file mode 100644 index c39831598..000000000 --- a/backend/services/src/shared/email/email.service.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import nodemailer = require("nodemailer"); - -@Injectable() -export class EmailService { - private transporter; - private CHAR_SET: "UTF-8"; - - private sourceEmail: string; - private emailDisabled: boolean; - - constructor(private logger: Logger, private configService: ConfigService) { - this.sourceEmail = this.configService.get("email.source"); - this.emailDisabled = this.configService.get("email.disabled"); - - this.transporter = nodemailer.createTransport({ - host: this.configService.get("email.endpoint"), - port: 465, - secure: true, - auth: { - user: this.configService.get("email.username"), - pass: this.configService.get("email.password"), - }, - pool: true, - maxMessages : 14 - }); - } - - async sendEmail(emailDataObj: any): Promise { - if (emailDataObj?.sender && !this.emailDisabled) { - return new Promise((resolve, reject) => { - this.transporter.sendMail( - { - from: this.sourceEmail, - to: emailDataObj?.sender, - subject: emailDataObj?.subject, - text: emailDataObj?.emailBody, - html: emailDataObj?.emailBody, - }, - function (error, info) { - console.log('SendEmail Response', error, info); - if (error) { - reject(error); - } else { - resolve(info); - } - } - ); - }); - } - } -} diff --git a/backend/services/src/shared/entities/async.action.entity.ts b/backend/services/src/shared/entities/async.action.entity.ts deleted file mode 100644 index ac613843c..000000000 --- a/backend/services/src/shared/entities/async.action.entity.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; -import { AsyncActionType } from "../enum/async.action.type.enum"; - -@Entity() -export class AsyncActionEntity { - @PrimaryGeneratedColumn() - actionId: number; - - @Column({ - type: "enum", - enum: AsyncActionType, - array: false - }) - actionType: AsyncActionType; - - @Column() - actionProps: string; -} \ No newline at end of file diff --git a/backend/services/src/shared/entities/company.entity.ts b/backend/services/src/shared/entities/company.entity.ts deleted file mode 100644 index 9716ba61e..000000000 --- a/backend/services/src/shared/entities/company.entity.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { BeforeInsert, Column, Entity, PrimaryColumn } from "typeorm"; -import { CompanyRole } from "../enum/company.role.enum"; -import { CompanyState } from "../enum/company.state.enum"; -import { EntitySubject } from "./entity.subject"; -import { SectoralScope } from "@undp/serial-number-gen"; - -@Entity() -export class Company implements EntitySubject { - @PrimaryColumn() - companyId: number; - - @Column({ unique: true, nullable: true }) - taxId: string; - - @Column() - name: string; - - @Column({ unique: true, nullable: true }) - email: string; - - @Column({ nullable: true }) - phoneNo: string; - - @Column({ nullable: true }) - website: string; - - @Column({ nullable: true }) - address: string; - - @Column({ nullable: true }) - logo: string; - - @Column({ nullable: true }) - country: string; - - @Column({ - type: "enum", - enum: CompanyRole, - array: false, - }) - companyRole: CompanyRole; - - @Column({ - type: "enum", - enum: CompanyState, - array: false, - default: CompanyState.ACTIVE, - }) - state: CompanyState; - - @Column("real", { nullable: true }) - creditBalance: number; - - @Column({ - type: "jsonb", - array: false, - nullable: true, - }) - secondaryAccountBalance: any; - - @Column("bigint", { nullable: true }) - programmeCount: number; - - @Column("bigint", { nullable: true }) - lastUpdateVersion: number; - - @Column("bigint", { nullable: true }) - creditTxTime: number; - - @Column({ nullable: true }) - remarks: string; - - @Column({ type: "bigint", nullable: true }) - createdTime: number; - - @Column({ nullable: true }) - nameOfMinister: string; - - @Column("varchar", { array: true, nullable: true }) - sectoralScope: SectoralScope[]; - - @BeforeInsert() - setDefaultState() { - if ( - this.companyRole === CompanyRole.GOVERNMENT || - this.companyRole === CompanyRole.CERTIFIER - ) { - this.programmeCount = null; - } else if (this.companyRole === CompanyRole.PROGRAMME_DEVELOPER) { - this.programmeCount = 0; - } - if ( - this.companyRole === CompanyRole.GOVERNMENT || - this.companyRole === CompanyRole.PROGRAMME_DEVELOPER - ) { - this.creditBalance = 0; - } else if (this.companyRole === CompanyRole.CERTIFIER) { - this.creditBalance = null; - } - } -} diff --git a/backend/services/src/shared/entities/configuration.settings.ts b/backend/services/src/shared/entities/configuration.settings.ts deleted file mode 100644 index 6379fae23..000000000 --- a/backend/services/src/shared/entities/configuration.settings.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Column, Entity, PrimaryColumn } from "typeorm"; -import { ConfigurationSettingsType } from "../enum/configuration.settings.type.enum"; -import { EntitySubject } from "./entity.subject"; - -@Entity() -export class ConfigurationSettings implements EntitySubject { - @PrimaryColumn({ - type: "enum", - enum: ConfigurationSettingsType, - array: false, - }) - id: ConfigurationSettingsType; - - @Column() - settingValue: string; -} diff --git a/backend/services/src/shared/entities/constants.entity.ts b/backend/services/src/shared/entities/constants.entity.ts deleted file mode 100644 index 783656ce2..000000000 --- a/backend/services/src/shared/entities/constants.entity.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { SubSectorConstants } from "@undp/carbon-credit-calculator"; -import { Column, Entity, Generated, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; -import { TypeOfMitigation } from "../enum/typeofmitigation.enum"; - -@Entity() -export class ConstantEntity { - - @PrimaryColumn({ - type: "enum", - enum: TypeOfMitigation, - array: false - }) - id: TypeOfMitigation; - - @PrimaryGeneratedColumn('increment') - version: number; - - @Column({ - type: 'jsonb', - array: false, - nullable: true - }) - data: SubSectorConstants; - -} \ No newline at end of file diff --git a/backend/services/src/shared/entities/counter.entity.ts b/backend/services/src/shared/entities/counter.entity.ts deleted file mode 100644 index e50eefcb0..000000000 --- a/backend/services/src/shared/entities/counter.entity.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Column, Entity, PrimaryColumn } from "typeorm"; -import { CounterType } from "../util/counter.type.enum"; - -@Entity() -export class Counter { - - @PrimaryColumn({ - type: "enum", - enum: CounterType, - array: false - }) - id: CounterType; - - @Column({ default: 0 }) - counter: number; - -} \ No newline at end of file diff --git a/backend/services/src/shared/entities/country.entity.ts b/backend/services/src/shared/entities/country.entity.ts deleted file mode 100644 index d7f76042a..000000000 --- a/backend/services/src/shared/entities/country.entity.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Column, Entity, PrimaryColumn } from "typeorm"; -import { CounterType } from "../util/counter.type.enum"; - -@Entity() -export class Country { - - @PrimaryColumn() - alpha2: string; - - @Column() - alpha3: string; - - @Column() - name: string - -} \ No newline at end of file diff --git a/backend/services/src/shared/entities/credit.overall.entity.ts b/backend/services/src/shared/entities/credit.overall.entity.ts deleted file mode 100644 index be68ea2ee..000000000 --- a/backend/services/src/shared/entities/credit.overall.entity.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { PRECISION } from '@undp/carbon-credit-calculator/dist/esm/calculator'; -import { Entity, Column, PrimaryColumn } from 'typeorm'; -import { TxType } from '../enum/txtype.enum'; -import { EntitySubject } from './entity.subject'; - -@Entity() -export class CreditOverall implements EntitySubject { - - @PrimaryColumn() - txId: string; - - @Column() - txRef: string; - - @Column({ - type: "enum", - enum: TxType, - array: false - }) - txType: TxType; - - @Column({type: "decimal", precision: 10, scale: PRECISION}) - credit: number; -} diff --git a/backend/services/src/shared/entities/entity.subject.ts b/backend/services/src/shared/entities/entity.subject.ts deleted file mode 100644 index b9a02cb35..000000000 --- a/backend/services/src/shared/entities/entity.subject.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class EntitySubject { - -} \ No newline at end of file diff --git a/backend/services/src/shared/entities/programme.entity.ts b/backend/services/src/shared/entities/programme.entity.ts deleted file mode 100644 index d31f4bd54..000000000 --- a/backend/services/src/shared/entities/programme.entity.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { PRECISION } from "@undp/carbon-credit-calculator/dist/esm/calculator"; -import { SectoralScope } from "@undp/serial-number-gen"; -import { Entity, Column, PrimaryColumn } from "typeorm"; -import { ProgrammeProperties } from "../dto/programme.properties"; -import { Sector } from "../enum/sector.enum"; -import { TxType } from "../enum/txtype.enum"; -import { ProgrammeStage } from "../enum/programme-status.enum"; -import { EntitySubject } from "./entity.subject"; -import { MitigationProperties } from "../dto/mitigation.properties"; - -@Entity() -export class Programme implements EntitySubject { - @PrimaryColumn() - programmeId: string; - - @Column({ nullable: true }) - serialNo: string; - - @Column() - title: string; - - @Column({ unique: true, nullable: true }) - externalId: string; - - @Column({ - type: "enum", - enum: SectoralScope, - array: false, - }) - sectoralScope: SectoralScope; - - @Column() - sector: Sector; - - @Column() - countryCodeA2: string; - - @Column({ - type: "enum", - enum: ProgrammeStage, - array: false, - default: ProgrammeStage.NEW, - }) - currentStage: ProgrammeStage; - - @Column({ type: "bigint" }) - startTime: number; - - @Column({ type: "bigint" }) - endTime: number; - - @Column({ type: "decimal", precision: 10, scale: PRECISION, nullable: true }) - creditEst: number; - - @Column({ type: "decimal", precision: 10, scale: PRECISION, nullable: true }) - creditChange: number; - - @Column({ type: "decimal", precision: 10, scale: PRECISION, nullable: true }) - creditIssued: number; - - // @Column({type: "decimal", precision: 10, scale: PRECISION, nullable: true}) - // creditPending: number; - - @Column({ type: "decimal", precision: 10, scale: PRECISION, nullable: true }) - creditBalance: number; - - @Column("real", { array: true, nullable: true }) - creditRetired: number[]; - - @Column("real", { array: true, nullable: true }) - creditFrozen: number[]; - - @Column("real", { array: true, nullable: true }) - creditTransferred: number[]; - - @Column({ nullable: true }) - constantVersion: string; - - @Column("varchar", { array: true }) - proponentTaxVatId: string[]; - - @Column("bigint", { array: true }) - companyId: number[]; - - @Column("real", { array: true, nullable: true }) - proponentPercentage: number[]; - - @Column("real", { array: true, nullable: true }) - creditOwnerPercentage: number[]; - - @Column("bigint", { array: true, nullable: true }) - certifierId: number[]; - - @Column("bigint", { array: true, nullable: true }) - revokedCertifierId: number[]; - - @Column() - creditUnit: string; - - @Column({ - type: "jsonb", - array: false, - }) - programmeProperties: ProgrammeProperties; - - @Column("jsonb", { array: false, nullable: true }) - mitigationActions?: MitigationProperties[]; - - @Column({ type: "bigint" }) - txTime: number; - - @Column({ type: "bigint" }) - createdTime: number; - - @Column({ type: "bigint", nullable: true }) - authTime: number; - - @Column({ type: "bigint", nullable: true }) - creditUpdateTime: number; - - @Column({ type: "bigint", nullable: true }) - statusUpdateTime: number; - - @Column({ type: "bigint", nullable: true }) - certifiedTime: number; - - @Column({ nullable: true }) - txRef: string; - - @Column({ - type: "enum", - enum: TxType, - array: false, - nullable: true, - }) - txType: TxType; - - @Column({ - type: "jsonb", - array: false, - nullable: true, - }) - geographicalLocationCordintes: any; - - @Column({ type: 'timestamptz', nullable: true }) - createdAt: Date; - - @Column({ type: 'timestamptz', nullable: true }) - updatedAt: Date; -} diff --git a/backend/services/src/shared/entities/programme.transfer.ts b/backend/services/src/shared/entities/programme.transfer.ts deleted file mode 100644 index 64c739cca..000000000 --- a/backend/services/src/shared/entities/programme.transfer.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Entity, Column, PrimaryGeneratedColumn, ValueTransformer } from 'typeorm'; -import { TransferStatus } from '../enum/transform.status.enum'; -import { EntitySubject } from './entity.subject'; -import { BasicOrgInfo } from '../dto/basic.organisation.dto'; -import { RetireType } from '../enum/retire.type.enum'; - -export const bigint: ValueTransformer = { - to: (entityValue: number) => entityValue, - from: (databaseValue: string[]): number[] => databaseValue.map( v => parseInt(v, 10)) - } - -@Entity() -export class ProgrammeTransfer implements EntitySubject { - - @PrimaryGeneratedColumn() - requestId: number; - - @Column() - programmeId: string; - - @Column() - initiator: number; - - @Column() - initiatorCompanyId: number; - - @Column() - toCompanyId: number; - - @Column({nullable: true}) - toAccount: string; - - @Column({ - type: 'jsonb', - array: false, - nullable: true - }) - toCompanyMeta: BasicOrgInfo; - - @Column({ - type: "enum", - enum: RetireType, - array: false, - nullable: true - }) - retirementType: RetireType; - - @Column() - fromCompanyId: number; - - @Column("real") - creditAmount: number; - - @Column({nullable: true}) - comment: string; - - @Column({nullable: true}) - txRef: string; - - @Column({type: "bigint"}) - txTime: number; - - @Column({type: "bigint", nullable: true}) - createdTime: number; - - @Column({type: "bigint", nullable: true}) - authTime: number; - - @Column({ - type: "enum", - enum: TransferStatus, - array: false - }) - status: TransferStatus; - - @Column({nullable: true, default: false}) - isRetirement: boolean; -} diff --git a/backend/services/src/shared/entities/programme.view.entity.ts b/backend/services/src/shared/entities/programme.view.entity.ts deleted file mode 100644 index 4ef82d2bf..000000000 --- a/backend/services/src/shared/entities/programme.view.entity.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ViewColumn, ViewEntity } from "typeorm" -import { Company } from "./company.entity"; -import { Programme } from "./programme.entity" - -@ViewEntity({ - expression: ` - SELECT programme.*, json_agg(DISTINCT "company".*) as "company", json_agg(DISTINCT "cert".*) as "certifier" FROM "programme" "programme" - LEFT JOIN "company" "cert" ON "cert"."companyId" = ANY("programme"."certifierId") - LEFT JOIN "company" "company" ON "company"."companyId" = ANY("programme"."companyId") - group by "programme"."programmeId"; - `, -}) -export class ProgrammeQueryEntity extends Programme { - - @ViewColumn() - company: Company[]; - - @ViewColumn() - certifier: Company[] -} \ No newline at end of file diff --git a/backend/services/src/shared/entities/programmeTransfer.view.entity.ts b/backend/services/src/shared/entities/programmeTransfer.view.entity.ts deleted file mode 100644 index 1174ea70c..000000000 --- a/backend/services/src/shared/entities/programmeTransfer.view.entity.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ViewColumn, ViewEntity } from "typeorm" -import { Company } from "./company.entity"; -import { ProgrammeTransfer } from "./programme.transfer"; - -@ViewEntity({ - expression: ` - SELECT programme_transfer.*, JSON_AGG(distinct "requester".*) as "requester", JSON_AGG(distinct "receiver".*) as "receiver", - "prog"."creditBalance" as "creditBalance", "prog"."title" as "programmeTitle", "prog"."certifierId" as "programmeCertifierId", - "prog"."sector" as "programmeSector", "prog"."sectoralScope" as "programmeSectoralScope", JSON_AGG(distinct "certifier".*) as "certifier", - JSON_AGG(distinct "sender".*) as "sender", "prog"."proponentTaxVatId" as "proponentTaxVatId", - "prog"."proponentPercentage" as "proponentPercentage", "prog"."creditOwnerPercentage" as "creditOwnerPercentage", - "prog"."companyId" as "companyId", "prog"."serialNo" as "serialNo" - FROM "programme_transfer" "programme_transfer" - LEFT JOIN "programme" "prog" ON "prog"."programmeId" = "programme_transfer"."programmeId" - LEFT JOIN "company" "requester" ON "requester"."companyId" = "programme_transfer"."initiatorCompanyId" - LEFT JOIN "company" "receiver" ON "receiver"."companyId" = "programme_transfer"."toCompanyId" - LEFT JOIN "company" "sender" ON "sender"."companyId" = "programme_transfer"."fromCompanyId" - LEFT JOIN "company" "certifier" ON "certifier"."companyId" = ANY("prog"."certifierId") - group by "programme_transfer"."requestId", "requester"."companyId", "prog"."programmeId"; - `, -}) -export class ProgrammeTransferViewEntityQuery extends ProgrammeTransfer { - @ViewColumn() - creditBalance: number; - - @ViewColumn() - programmeTitle: string; - - @ViewColumn() - programmeCertifierId: number[] - - @ViewColumn() - serialNo: string; - - @ViewColumn() - programmeSector: string; - - @ViewColumn() - programmeSectoralScope: string; - - @ViewColumn() - certifier: Company[]; - - @ViewColumn() - sender: Company; - - @ViewColumn() - requester: Company; - - @ViewColumn() - receiver: Company; - - @ViewColumn() - proponentTaxVatId: string[]; - - @ViewColumn() - proponentPercentage: number[]; - - @ViewColumn() - companyId: string[]; - - @ViewColumn() - creditOwnerPercentage: number[]; - -} \ No newline at end of file diff --git a/backend/services/src/shared/entities/region.entity.ts b/backend/services/src/shared/entities/region.entity.ts deleted file mode 100644 index 0f8deba33..000000000 --- a/backend/services/src/shared/entities/region.entity.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; - -@Entity() -export class Region { - @PrimaryColumn() - key: string; - - @Column() - countryAlpha2: string; - - @Column() - regionName: string; - - @Column() - lang: string; - - @Column({ - type: "jsonb", - array: false, - nullable: true, - }) - geoCoordinates: any; -} diff --git a/backend/services/src/shared/entities/user.entity.ts b/backend/services/src/shared/entities/user.entity.ts deleted file mode 100644 index 3d3f7244f..000000000 --- a/backend/services/src/shared/entities/user.entity.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Role } from '../casl/role.enum'; -import { Entity, Column, PrimaryGeneratedColumn, JoinColumn, OneToOne, OneToMany, ManyToOne } from 'typeorm'; -import { EntitySubject } from './entity.subject'; -import { CompanyRole } from '../enum/company.role.enum'; -import { Company } from './company.entity'; - -@Entity() -export class User implements EntitySubject{ - @PrimaryGeneratedColumn() - id: number; - - @Column({ unique: true }) - email: string; - - @Column({select: false}) - password: string; - - @Column({ - type: "enum", - enum: Role, - array: false, - default: Role.ViewOnly - }) - role: Role; - - @Column() - name: string; - - @Column() - country: string; - - @Column({nullable: true}) - phoneNo: string; - - @Column({nullable: true}) - companyId: number; - - // @ManyToOne(() => Company, (company) => company.companyId) - // @JoinColumn({name: "companyId"}) - // company: Company | null; - - @Column({ - type: "enum", - enum: CompanyRole, - array: false, - default: CompanyRole.PROGRAMME_DEVELOPER - }) - companyRole: CompanyRole; - - @Column({nullable: true, select: false}) - apiKey: string; - - @Column({type: "bigint", nullable: true}) - createdTime: number; - - companyState: number; -} diff --git a/backend/services/src/shared/entities/userPasswordResetToken.entity.ts b/backend/services/src/shared/entities/userPasswordResetToken.entity.ts deleted file mode 100644 index ec1ccf94a..000000000 --- a/backend/services/src/shared/entities/userPasswordResetToken.entity.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; -import { CompanyRole } from "../enum/company.role.enum"; -import { CompanyState } from "../enum/company.state.enum"; -import { EntitySubject } from "./entity.subject"; - -@Entity() -export class PasswordReset implements EntitySubject { - @PrimaryGeneratedColumn() - id: number; - - @Column() - email: string; - - @Column() - token: string; - - @Column({ type: "bigint", nullable: true }) - expireTime: number; -} diff --git a/backend/services/src/shared/enum/async.action.type.enum.ts b/backend/services/src/shared/enum/async.action.type.enum.ts deleted file mode 100644 index aa29f263b..000000000 --- a/backend/services/src/shared/enum/async.action.type.enum.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum AsyncActionType { - Email, - RegistryCompanyCreate, - IssueCredit, - AuthProgramme, - RejectProgramme -} diff --git a/backend/services/src/shared/enum/async.operation.type.enum.ts b/backend/services/src/shared/enum/async.operation.type.enum.ts deleted file mode 100644 index 21f4a3045..000000000 --- a/backend/services/src/shared/enum/async.operation.type.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum AsyncOperationType { - Queue = "Queue", - Database = "Database" -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/chart.type.enum.ts b/backend/services/src/shared/enum/chart.type.enum.ts deleted file mode 100644 index 14c7c3115..000000000 --- a/backend/services/src/shared/enum/chart.type.enum.ts +++ /dev/null @@ -1,10 +0,0 @@ -export enum ChartType { - TOTAL_PROGRAMS = "TOTAL_PROGRAMS", - TOTAL_PROGRAMS_SECTOR = "TOTAL_PROGRAMS_SECTOR", - TOTAL_CREDITS = "TOTAL_CREDITS", - TOTAL_CREDITS_CERTIFIED = "TOTAL_CREDITS_CERTIFIED", - TOTAL_CREDITS_SECTOR = "TOTAL_CREDITS_SECTOR", - PROGRAMME_LOCATIONS = "PROGRAMME_LOCATIONS", - TRANSFER_LOCATIONS = "TRANSFER_LOCATIONS", - PROGRAMME_DETAILS = "PROGRAMME_DETAILS", -} diff --git a/backend/services/src/shared/enum/company.role.enum.ts b/backend/services/src/shared/enum/company.role.enum.ts deleted file mode 100644 index 0c3cfd1e6..000000000 --- a/backend/services/src/shared/enum/company.role.enum.ts +++ /dev/null @@ -1,18 +0,0 @@ -export enum CompanyRole { - ACADEMICS = 'Academics', - SERVICE_PROVIDER = 'ServiceProvider', - MITIGATION_ACTIVITY_PARTNER = 'MitigationActivityParticipant', - CARBON_CREDIT_BROKER = 'CarbonCreditBroker', - VALIDATION_VERIFICATION_ENTITY = 'ValidationVerificationEntities', - COMMERCIAL_BANKS = 'CommercialBanks', - INVESTORS = 'InvestorsFinanciers', - GOV_REGULATOR = 'GovernmentRegulators', - OBSERVERS = 'Observers', - CIVIL_SOCIETY_ORG = 'CivilSocietyOrganization', - CERTIFIER = 'Certifier', - INTERNAL_ORGANIZATION = 'InternationalOrganization', - PROGRAMME_DEVELOPER = 'ProgrammeDeveloper', - API = 'API', - GOVERNMENT = 'Government', - MINISTRY = "Ministry", -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/company.state.enum.ts b/backend/services/src/shared/enum/company.state.enum.ts deleted file mode 100644 index 9e0d55bfe..000000000 --- a/backend/services/src/shared/enum/company.state.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum CompanyState { - SUSPENDED = '0', - ACTIVE = '1' -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/configuration.settings.type.enum.ts b/backend/services/src/shared/enum/configuration.settings.type.enum.ts deleted file mode 100644 index 099edc47c..000000000 --- a/backend/services/src/shared/enum/configuration.settings.type.enum.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum ConfigurationSettingsType { - isTransferFrozen, -} diff --git a/backend/services/src/shared/enum/credit.stat.type.enum.ts b/backend/services/src/shared/enum/credit.stat.type.enum.ts deleted file mode 100644 index e6ba51908..000000000 --- a/backend/services/src/shared/enum/credit.stat.type.enum.ts +++ /dev/null @@ -1,15 +0,0 @@ -export enum CreditStatType { - CREDIT_STATS_BALANCE = "creditBalance", - CREDIT_STATS_TRANSFERRED = "creditTransferred", - CREDIT_STATS_RETIRED = "creditRetired", - CREDIT_STATS_ISSUED = "creditIssued", - CREDIT_STATS_ESTIMATED = "creditEst", - CREDIT_STATS_FROZEN = 'creditFrozen', - CREDIT_CERTIFIED_BALANCE = "creditBalance", - CREDIT_CERTIFIED_TRANSFERRED = "creditTransferred", - CREDIT_CERTIFIED_RETIRED = "creditRetired", - CREDIT_CERTIFIED_ISSUED = "creditIssued", - CREDIT_CERTIFIED = "creditBalance", - CREDIT_UNCERTIFIED = "creditBalance", - CREDIT_REVOKED = "creditBalance", -} diff --git a/backend/services/src/shared/enum/ghgs.enum.ts b/backend/services/src/shared/enum/ghgs.enum.ts deleted file mode 100644 index 5a02f7b32..000000000 --- a/backend/services/src/shared/enum/ghgs.enum.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum GHGs { - CO2, - CH4, - N2O, - HFCs, - PFCs, - SF6 -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/ledger.type.ts b/backend/services/src/shared/enum/ledger.type.ts deleted file mode 100644 index f92c033b1..000000000 --- a/backend/services/src/shared/enum/ledger.type.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum LedgerType { - QLDB = "QLDB", - PGSQL = "PGSQL" -} diff --git a/backend/services/src/shared/enum/location.type.ts b/backend/services/src/shared/enum/location.type.ts deleted file mode 100644 index 4410c22b4..000000000 --- a/backend/services/src/shared/enum/location.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum LocationType { - MAPBOX = "MAPBOX", - FILE = "FILE", - OPENSTREET = "OPENSTREET" -} diff --git a/backend/services/src/shared/enum/programme-status.enum.ts b/backend/services/src/shared/enum/programme-status.enum.ts deleted file mode 100644 index 48b8811f2..000000000 --- a/backend/services/src/shared/enum/programme-status.enum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum ProgrammeStage { - NEW = 'New', - AWAITING_AUTHORIZATION = "AwaitingAuthorization", - AUTHORISED = "Authorised", - REJECTED = "Rejected", -} diff --git a/backend/services/src/shared/enum/retire.type.enum.ts b/backend/services/src/shared/enum/retire.type.enum.ts deleted file mode 100644 index 4d3780445..000000000 --- a/backend/services/src/shared/enum/retire.type.enum.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum RetireType { - CROSS_BORDER = '0', - LEGAL_ACTION = '1', - OTHER = '2', -} diff --git a/backend/services/src/shared/enum/sector.enum.ts b/backend/services/src/shared/enum/sector.enum.ts deleted file mode 100644 index 577a0ab80..000000000 --- a/backend/services/src/shared/enum/sector.enum.ts +++ /dev/null @@ -1,12 +0,0 @@ -export enum Sector { - Energy = 'Energy', - Health = 'Health', - Education = 'Education', - Transport = 'Transport', - Manufacturing = 'Manufacturing', - Hospitality = 'Hospitality', - Forestry = 'Forestry', - Waste = 'Waste', - Agriculture = 'Agriculture', - Other = 'Other' -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/sourceoffinding.enum.ts b/backend/services/src/shared/enum/sourceoffinding.enum.ts deleted file mode 100644 index e1f826be4..000000000 --- a/backend/services/src/shared/enum/sourceoffinding.enum.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum SourceOfFunding { - BoardSourceFunding = "BoardSourceFunding", - GovernmentGrantOrLoan = "GovernmentGrantOrLoan", - Other = "Other", -} diff --git a/backend/services/src/shared/enum/stat.type.enum.ts b/backend/services/src/shared/enum/stat.type.enum.ts deleted file mode 100644 index 9af40b9ce..000000000 --- a/backend/services/src/shared/enum/stat.type.enum.ts +++ /dev/null @@ -1,62 +0,0 @@ -export enum StatType { - TOTAL_PROGRAMS = "TOTAL_PROGRAMS", - TOTAL_PROGRAMS_LAST_UPDATE = "TOTAL_PROGRAMS_LAST_UPDATE", - CREDIT_ISSUED = "CREDIT_ISSUED", - TRANSFER_REQUEST = "TRANSFER_REQUEST", - TRANSFER_REQUEST_LAST_UPDATE = "TRANSFER_REQUEST_LAST_UPDATE", - TRANSFER_REQUEST_SENT = "TRANSFER_REQUEST_SENT", - TRANSFER_REQUEST_RECEIVED = "TRANSFER_REQUEST_RECEIVED", - PROGRAMS_BY_STATUS = "PROGRAMS_BY_STATUS", - - CREDIT_STATS_BALANCE = "CREDIT_STATS_BALANCE", - CREDIT_STATS_ESTIMATED = "CREDIT_STATS_ESTIMATED", - CREDIT_STATS_TRANSFERRED = "CREDIT_STATS_TRANSFERRED", - CREDIT_STATS_ISSUED = "CREDIT_STATS_ISSUED", - CREDIT_STATS_RETIRED = "CREDIT_STATS_RETIRED", - CREDIT_STATS_FROZEN = "CREDIT_STATS_FROZEN", - - CREDIT_CERTIFIED_BALANCE = "CREDIT_CERTIFIED_BALANCE", - CREDIT_CERTIFIED_TRANSFERRED = "CREDIT_CERTIFIED_TRANSFERRED", - CREDIT_CERTIFIED_ISSUED = "CREDIT_CERTIFIED_ISSUED", - CREDIT_CERTIFIED_RETIRED = "CREDIT_CERTIFIED_RETIRED", - CREDIT_CERTIFIED = "CREDIT_CERTIFIED", - CREDIT_UNCERTIFIED = "CREDIT_UNCERTIFIED", - CREDIT_REVOKED = "CREDIT_REVOKED", - CREDIT_TRANSFERRED = "CREDIT_TRANSFERRED", - CERTIFICATION_ISSUED = "CERTIFICATION_ISSUED", - PROGRAMS_BY_SECTOR = "PROGRAMS_BY_SECTOR", - PROGRAMS_BY_SUB_SECTOR = "PROGRAMS_BY_SUB_SECTOR", - CREDIT_ISSUED_TIME = "CREDIT_ISSUED_TIME", - CREDIT_CERTIFIED_TIME = "CREDIT_CERTIFIED", - PROGRAMS_CERTIFIED = "PROGRAMS_CERTIFIED", - PROGRAMS_UNCERTIFIED = "PROGRAMS_UNCERTIFIED", - - AGG_PROGRAMME_BY_STATUS = "AGG_PROGRAMME_BY_STATUS", - AGG_PROGRAMME_BY_SECTOR = "AGG_PROGRAMME_BY_SECTOR", - MY_CREDIT = "MY_CREDIT", - PENDING_TRANSFER_INIT = "PENDING_TRANSFER_INIT", - PENDING_TRANSFER_RECV = "PENDING_TRANSFER_RECV", - CERTIFIED_BY_ME = "CERTIFIED_BY_ME", - REVOKED_BY_ME = "REVOKED_BY_ME", - CERTIFIED_REVOKED_BY_ME = "CERTIFIED_REVOKED_BY_ME", - UNCERTIFIED_BY_ME = "UNCERTIFIED_BY_ME", - ALL_AUTH_PROGRAMMES = "ALL_AUTH_PROGRAMMES", - ALL_AUTH_PROGRAMME_MINE = "ALL_AUTH_PROGRAMME_MINE", - CERTIFIED_PROGRAMMES = "CERTIFIED_PROGRAMMES", - REVOKED_PROGRAMMES = "REVOKED_PROGRAMMES", - CERTIFIED_REVOKED_PROGRAMMES = "CERTIFIED_REVOKED_PROGRAMMES", - CERTIFIED_BY_ME_BY_STATE = "CERTIFIED_BY_ME_BY_STATE", - CERTIFIED_BY_ME_BY_SECTOR = "CERTIFIED_BY_ME_BY_SECTOR", - MY_AGG_PROGRAMME_BY_STATUS = "MY_AGG_PROGRAMME_BY_STATUS", - MY_AGG_PROGRAMME_BY_SECTOR = "MY_AGG_PROGRAMME_BY_SECTOR", - MY_CERTIFIED_REVOKED_PROGRAMMES = "MY_CERTIFIED_REVOKED_PROGRAMMES", - ALL_PROGRAMME_LOCATION = "ALL_PROGRAMME_LOCATION", - MY_PROGRAMME_LOCATION = "MY_PROGRAMME_LOCATION", - // MY_CERTIFIED_PROGRAMME_LOCATION = 'MY_CERTIFIED_PROGRAMME_LOCATION', - ALL_TRANSFER_LOCATION = "ALL_TRANSFER_LOCATION", - MY_TRANSFER_LOCATION = "MY_TRANSFER_LOCATION", - MY_CERTIFIED_TRANSFER_LOCATION = "MY_CERTIFIED_TRANSFER_LOCATION", - AGG_AUTH_PROGRAMME_BY_STATUS = "AGG_AUTH_PROGRAMME_BY_STATUS", - MY_AGG_AUTH_PROGRAMME_BY_STATUS = "MY_AGG_AUTH_PROGRAMME_BY_STATUS", - AUTH_CERTIFIED_BY_ME_BY_STATE = "AUTH_CERTIFIED_BY_ME_BY_STATE", -} diff --git a/backend/services/src/shared/enum/storage.type.ts b/backend/services/src/shared/enum/storage.type.ts deleted file mode 100644 index efe40db8e..000000000 --- a/backend/services/src/shared/enum/storage.type.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum StorageType { - S3 = "S3", - LOCAL = "LOCAL" -} diff --git a/backend/services/src/shared/enum/system.action.type.ts b/backend/services/src/shared/enum/system.action.type.ts deleted file mode 100644 index bc845cd5b..000000000 --- a/backend/services/src/shared/enum/system.action.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum SystemActionType { - SUSPEND_AUTO_CANCEL = 'SUSPEND_AUTO_CANCEL', - SUSPEND_REVOKE = 'SUSPEND_REVOKE', - LOW_CREDIT_AUTO_CANCEL = 'LOW_CREDIT_AUTO_CANCEL', -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/transform.status.enum.ts b/backend/services/src/shared/enum/transform.status.enum.ts deleted file mode 100644 index 24dfa298f..000000000 --- a/backend/services/src/shared/enum/transform.status.enum.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum TransferStatus { - PROCESSING = 'Process', - APPROVED = 'Approved', - REJECTED = 'Rejected', - PENDING = 'Pending', - CANCELLED = 'Cancelled', - RECOGNISED = 'Recognised', - NOTRECOGNISED = 'NotRecognised' -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/txtype.enum.ts b/backend/services/src/shared/enum/txtype.enum.ts deleted file mode 100644 index f4e7e15d6..000000000 --- a/backend/services/src/shared/enum/txtype.enum.ts +++ /dev/null @@ -1,15 +0,0 @@ -export enum TxType { - CREATE = '0', - REJECT = '1', - ISSUE = '2', - TRANSFER = '3', - CERTIFY = '4', - RETIRE = '5', - REVOKE = '6', - FREEZE = '7', - AUTH = '8', - UNFREEZE = '9', - ADD_DOCUMENT = '10', - ADD_MITIGATION = '11', - OWNERSHIP_UPDATE = '12' -} \ No newline at end of file diff --git a/backend/services/src/shared/enum/typeofmitigation.enum.ts b/backend/services/src/shared/enum/typeofmitigation.enum.ts deleted file mode 100644 index 1d33adc86..000000000 --- a/backend/services/src/shared/enum/typeofmitigation.enum.ts +++ /dev/null @@ -1,26 +0,0 @@ -export enum TypeOfMitigation { - AGRICULTURE = 'Agriculture', - BIOMASS_ENERGY = 'BiomassEnergy', - CCS = 'CCS', - CEMENT = 'Cement', - COAL_MINE = 'Coal/Mine', - EE_HOUSEHOLDS = 'EEHouseholds', - EE_INDUSTRY = 'EEIndustry', - EE_OWN_GENERATION = 'EEOwnGeneration', - EE_SERVICE = 'EEService', - EE_SUPPLY_SIDE = 'EESupplySide', - ENERGY_DISTRIBUTION = 'EnergyDistribution', - FORESTRY = 'Forestry', - FOSSIL_FUEL = 'FossilFuel', - FUGITIVE = 'Fugitive', - GEOTHERMAL = 'Geothermal', - HFC_PFCS_SF6 = 'HFC_PFCs_SF6', - HYDRO = 'Hydro', - LANDFILLS = 'Landfills', - MARINE = 'Marine', - METHANE_AVOIDANCE = 'MethaneAvoidance', - N20 = 'N20', - SOLAR = 'Solar', - TRANSPORT = 'Transport', - WIND = 'Wind' -} \ No newline at end of file diff --git a/backend/services/src/shared/file-handler/filehandler.interface.ts b/backend/services/src/shared/file-handler/filehandler.interface.ts deleted file mode 100644 index fe6e738d6..000000000 --- a/backend/services/src/shared/file-handler/filehandler.interface.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { forwardRef, Inject, Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { CompanyService } from "../company/company.service"; -import { Company } from "../entities/company.entity"; -import { Programme } from "../entities/programme.entity"; -import { ProgrammeLedgerService } from "../programme-ledger/programme-ledger.service"; -import { UserService } from "../user/user.service"; - -@Injectable() -export abstract class FileHandlerInterface { - - public abstract uploadFile(path: string, content: string): Promise; - - public abstract getUrl(path: string): Promise; - -} diff --git a/backend/services/src/shared/file-handler/filehandler.module.ts b/backend/services/src/shared/file-handler/filehandler.module.ts deleted file mode 100644 index 29cf6ff5c..000000000 --- a/backend/services/src/shared/file-handler/filehandler.module.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Logger, Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import configuration from '../configuration'; -import { StorageType } from '../enum/storage.type'; -import { FileHandlerInterface } from './filehandler.interface'; -import { LocalFileHandlerService } from './local.filehandler.service'; -import { S3FileHandlerService } from './s3.filehandler.service'; - -@Module({ - providers: [ - Logger, - { - provide: FileHandlerInterface, - useClass: - process.env.FILE_SERVICE === StorageType.S3 - ? S3FileHandlerService - : LocalFileHandlerService, - } - ], - exports: [FileHandlerInterface], - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }) - ], -}) -export class FileHandlerModule {} \ No newline at end of file diff --git a/backend/services/src/shared/file-handler/local.filehandler.service.ts b/backend/services/src/shared/file-handler/local.filehandler.service.ts deleted file mode 100644 index 115f4cc70..000000000 --- a/backend/services/src/shared/file-handler/local.filehandler.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { FileHandlerInterface } from "./filehandler.interface"; -const fs = require("fs").promises; -const fsAync = require("fs"); - -@Injectable() -export class LocalFileHandlerService implements FileHandlerInterface { - public async uploadFile(path: string, content: string): Promise { - // This must run inside a function marked `async`: - const parts = path.split("/"); - if (parts.length > 1) { - const folders = './public/' + parts.slice(0, -1).join("/"); - console.log('Creating folder path:', folders) - if (!(await fsAync.existsSync(folders))) { - await fsAync.mkdirSync(folders, { recursive: true }); - } - } - await fs.writeFile("./public/" + path, content, 'base64'); - return global.baseUrl + "/" + path; - } - public getUrl(path: string): Promise { - throw new Error("Method not implemented."); - } -} diff --git a/backend/services/src/shared/file-handler/s3.filehandler.service.ts b/backend/services/src/shared/file-handler/s3.filehandler.service.ts deleted file mode 100644 index 5513353c1..000000000 --- a/backend/services/src/shared/file-handler/s3.filehandler.service.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { FileHandlerInterface } from "./filehandler.interface"; -var AWS = require("aws-sdk"); -const s3 = new AWS.S3(); - -@Injectable() -export class S3FileHandlerService implements FileHandlerInterface { - - constructor( - private logger: Logger, - private configService: ConfigService - ) {} - - public async uploadFile(path: string, content: string): Promise { - const imgBuffer = Buffer.from(content, "base64"); - var uploadParams = { - Bucket: this.configService.get("s3CommonBucket.name"), - Key: "", - Body: imgBuffer, - ContentEncoding: "base64", - ContentType: "image/png", - }; - - // uploadParams.Key = `profile_images/${companyId}_${new Date().getTime()}.png`; - uploadParams.Key = path - return (await s3 - .upload(uploadParams) - .promise())?.Location; - } - - - public getUrl(path: string): Promise { - throw new Error("Method not implemented."); - } - -} \ No newline at end of file diff --git a/backend/services/src/shared/handler.ts b/backend/services/src/shared/handler.ts deleted file mode 100644 index 34de68d8b..000000000 --- a/backend/services/src/shared/handler.ts +++ /dev/null @@ -1,3 +0,0 @@ -exports.handler = async (event) => { - console.log(`Started with: ${event.body}`) -} \ No newline at end of file diff --git a/backend/services/src/shared/ledger-db/ledger-db.module.ts b/backend/services/src/shared/ledger-db/ledger-db.module.ts deleted file mode 100644 index 017008d00..000000000 --- a/backend/services/src/shared/ledger-db/ledger-db.module.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Logger, Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import configuration from "../configuration"; -import { LedgerType } from "../enum/ledger.type"; -import { TypeOrmConfigService } from "../typeorm.config.service"; -import { LedgerDBInterface } from "./ledger.db.interface"; -import { PgSqlLedgerService } from "./pgsql-ledger.service"; -import { QLDBLedgerService } from "./qldb-ledger.service"; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - }), - ], - providers: [ - Logger, - { - provide: LedgerDBInterface, - useClass: - process.env.LEDGER_TYPE === LedgerType.QLDB - ? QLDBLedgerService - : PgSqlLedgerService, - }, - ], - exports: [LedgerDBInterface], -}) -export class LedgerDbModule {} diff --git a/backend/services/src/shared/ledger-db/ledger-db.service.spec.ts b/backend/services/src/shared/ledger-db/ledger-db.service.spec.ts deleted file mode 100644 index 1e69ad637..000000000 --- a/backend/services/src/shared/ledger-db/ledger-db.service.spec.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Logger } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { dom } from 'ion-js'; -import configuration from '../configuration'; -import { PgSqlLedgerService } from './pgsql-ledger.service'; -import { QLDBLedgerService } from "./qldb-ledger.service"; - -describe('LedgerDbService', () => { - let service: PgSqlLedgerService; - - jest.useRealTimers(); - jest.setTimeout(30000); - - beforeEach(async () => { - - const module: TestingModule = await Test.createTestingModule({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`] - }), - ], - providers: [QLDBLedgerService, Logger, PgSqlLedgerService], - }).compile(); - - service = module.get(PgSqlLedgerService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); - - it('insert record', async () => { - return service.insertRecord({'test_name': 'name', 'val': 700}, 'test_table').then( data => { - console.log(data) - }) - }) - - it('get record', async () => { - return service.fetchRecords({'test_name': 'name'}, 'test_table').then( data => { - console.log(data) - expect(data.length).toEqual(1) - expect(data[0]['val']).toEqual(700) - }) - }) - - it('get history', async () => { - return service.fetchHistory({'test_name': 'name'}, 'test_table').then( data => { - console.log(data) - expect(data.length).toBeGreaterThan(1) - expect(data[0]['data']['val']).toEqual(700) - }) - }) - - it('update record', async () => { - const txVal = 9999 - return service.updateRecords({'val': txVal}, {'test_name': 'name2'}, 'test_table').then( data => { - console.log(data) - return service.fetchRecords({'test_name': 'name2'}, 'test_table').then( data2 => { - console.log(data2) - expect(data2.length).toEqual(1) - expect(data2[0]['val']).toEqual(txVal) - }) - }) - }) - - it('get update tx',async () => { - const table = 'test_table'; - const getQueries = {}; - getQueries[table] = { - 'test_name': 'name3' - }; - const r = await service.getAndUpdateTx( - getQueries, - (results: Record) => { - console.log(results) - expect(results[table].length).toEqual(1); - return [{ - test_table: { - 'val': 12345 - } - }, { - test_table: { - 'test_name': 'name3' - } - }, {}]; - }, - ); - }) -}); diff --git a/backend/services/src/shared/ledger-db/ledger.db.interface.ts b/backend/services/src/shared/ledger-db/ledger.db.interface.ts deleted file mode 100644 index fa76d6a84..000000000 --- a/backend/services/src/shared/ledger-db/ledger.db.interface.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { dom } from "ion-js"; - -export class ArrayIn { - constructor(public key: string, public value: any) { - } -} - -export class ArrayLike { - constructor(public key: string, public value: any) { - } - - public toString = () : string => { - return `${this.value}`; - } -} - -@Injectable() -export abstract class LedgerDBInterface { - - public tableName: string; - public overallTableName: string; - public companyTableName: string; - public ledgerName: string; - - abstract createTable(tableName?: string): Promise; - - abstract createIndex(indexCol: string, tableName?: string): Promise; - - abstract insertRecord(document: Record, tableName?: string): Promise; - - abstract fetchRecords(where: Record): Promise; - - abstract fetchHistory(where: Record): Promise; - - abstract updateRecords(update: Record, where: Record): Promise; - - abstract getAndUpdateTx(getQueries: Record>, processGetFn: (results: Record) => [Record, Record, Record]): Promise>; - -} diff --git a/backend/services/src/shared/ledger-db/pgsql-ledger.service.ts b/backend/services/src/shared/ledger-db/pgsql-ledger.service.ts deleted file mode 100644 index 0d969b7e9..000000000 --- a/backend/services/src/shared/ledger-db/pgsql-ledger.service.ts +++ /dev/null @@ -1,421 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { dom } from "ion-js"; -import { ArrayIn, ArrayLike, LedgerDBInterface } from "./ledger.db.interface"; -import { Pool, QueryResult, Client } from "pg"; -import { Programme } from "../entities/programme.entity"; - -class MetaEntity { - version: number; - txTime: Date; -} - -export class PgProgrammeEventEntity { - data: Programme; - meta: MetaEntity; - hash: number; -} - -export class TxElement { - sql: string; - params?: any[]; -} - -@Injectable() -export class PgSqlLedgerService implements LedgerDBInterface { - public tableName: string; - public overallTableName: string; - public companyTableName: string; - public ledgerName: string; - private dbCon: Pool; - - constructor( - private readonly logger: Logger, - private readonly configService: ConfigService - ) { - this.ledgerName = configService.get("ledger.name"); - this.tableName = configService.get("ledger.table"); - this.overallTableName = configService.get("ledger.overallTable"); - this.companyTableName = configService.get("ledger.companyTable"); - - let dbc = this.configService.get("database"); - - const config = { - host: dbc["host"], - port: dbc["port"], - user: dbc["username"], - password: dbc["password"], - database: dbc["database"] + "Events", - }; - this.dbCon = new Pool(config); - logger.log("PgSQL Ledger init ", this.ledgerName); - } - - // TODO: Handler session expire - private async execute(queries: TxElement[]): Promise { - console.log(`Statement: ${JSON.stringify(queries)}`); - const client = await this.dbCon.connect(); - try { - const responses = []; - await client.query("BEGIN"); - for (const c of queries) { - const resp = await client.query(c.sql, c.params); - responses.push(resp); - console.log("Execute resp", resp); - } - await client.query("COMMIT"); - return responses; - } catch (e) { - console.log("Error", e); - await client.query("ROLLBACK"); - throw e; - } finally { - client.release(); - } - } - - private async executeTxn( - client: Client, - queries: { [key: string]: TxElement } - ): Promise<{ [key: string]: QueryResult }> { - console.log(`Statement: ${JSON.stringify(queries)}`); - try { - const responses = {}; - await client.query("BEGIN"); - for (const k in queries) { - const c = queries[k]; - const resp = await client.query(c.sql, c.params); - responses[k] = resp; - console.log("Execute resp", resp); - } - await client.query("COMMIT"); - return responses; - } catch (e) { - console.log("Error", e); - await client.query("ROLLBACK"); - throw e; - } - } - - public async createTable(tableName?: string): Promise { - const sql = `CREATE SEQUENCE ${ - tableName ? tableName : this.tableName - }_hash_seq; - CREATE TABLE IF NOT EXISTS ${tableName ? tableName : this.tableName} - ( - data jsonb NOT NULL, - meta jsonb NOT NULL, - hash integer NOT NULL DEFAULT nextval('${ - tableName ? tableName : this.tableName - }_hash_seq'::regclass), - PRIMARY KEY (hash) - );`; - await await this.execute([{ sql }]); - } - - public async createIndex( - indexCol: string, - tableName?: string - ): Promise { - return null; - // await (await this.execute(`create index on ${tableName ? tableName : this.tableName} (${indexCol})`)); - } - - public async insertRecord( - document: Record, - tableName?: string - ): Promise { - await this.execute([ - { - sql: `INSERT INTO "${ - tableName ? tableName : this.tableName - }" ("data", "meta") VALUES ($1, $2)`, - params: [ - document, - { - version: 0, - txTime: new Date(), - }, - ], - }, - ]); - } - - private getUniqueIndex(tableName: string) { - if (tableName === this.tableName) { - return "data->>'programmeId'" - } - else { - return "data->>'txId'" - } - } - - public async fetchRecords( - where: Record, - tableName?: string - ): Promise { - const whereClause = Object.keys(where) - .map((k, i) => `data->>'${k}' = $${i + 1}`) - .join(" and "); - // const fieldList = Object.keys(where) - // .map((k) => `data->>'${k}'`) - // .join(", "); - const t = tableName ? tableName : this.tableName - return ( - await this.execute([ - { - sql: `SELECT * from (SELECT DISTINCT ON (${this.getUniqueIndex(t)}) data FROM ${ - t - } order by ${this.getUniqueIndex(t)}, hash desc) x where ${whereClause}`, - params: Object.values(where), - }, - ]) - )[0]?.rows.map((e) => e.data); - } - - public async fetchHistory( - where: Record, - tableName?: string - ): Promise { - const whereClause = Object.keys(where) - .map((k, i) => `data->>'${k}' = $${i + 1}`) - .join(" and "); - const x = ( - await this.execute([ - { - sql: `SELECT * FROM ${ - tableName ? tableName : this.tableName - } as h WHERE ${whereClause} order by hash`, - params: Object.values(where), - }, - ]) - )[0]?.rows; - console.log("Results", x); - return x; - } - - public async updateRecords( - update: Record, - where: Record, - tableName?: string - ): Promise { - // const whereClause = Object.keys(where) - // .map((k) => `${k} = ?`) - // .join(" and "); - // const updateClause = Object.keys(update) - // .map((k) => `${k} = ?`) - // .join(","); - const table = tableName ? tableName : this.tableName; - const getQueries = {}; - getQueries[table] = where; - const r = await this.getAndUpdateTx( - getQueries, - (results: Record) => { - const resTable = results[table]; - console.log("Res table", resTable, update); - const insertMap = {}; - for (const obj of resTable) { - for (const k in update) { - obj[k] = update[k]; - } - insertMap[table] = obj; - } - console.log("Updating records", insertMap); - return [{}, {}, insertMap]; - } - ); - - console.log(r); - - return r[table]; - } - - private getValuesList(filterObj: any): any { - const list = []; - for (const k in filterObj) { - const v = filterObj[k]; - if (v instanceof ArrayIn) { - // list.push(v.value); - } else if (v instanceof ArrayLike) { - list.push(v.value); - } else if (v instanceof Array) { - list.push(...v) - } else { - list.push(v); - } - } - return list; - } - - public async getAndUpdateTx( - getQueries: Record>, - processGetFn: ( - results: Record - ) => [Record, Record, Record] - ): Promise> { - this.logger.log(`getQueries: ${JSON.stringify(getQueries)}`); - - let updateResults = {}; - const client = await this.dbCon.connect(); - try { - const getTxElements = {}; - for (const t in getQueries) { - console.log("getQueries t", t); - if (getQueries.hasOwnProperty(t)) { - const isHistoryQuery = t.includes("history("); - let table = t; - if (isHistoryQuery) { - table = t.replace("history(", "").replace(")", ""); - } - let j = 0; - const wc = Object.keys(getQueries[t]) - .map((k, i) => { - if (isHistoryQuery) { - k = k.replace("data.", ""); - } - if (getQueries[t][k] instanceof Array) { - return `data->>'${k}' in (${getQueries[t][k].map((e) => { - j += 1; - return "$" + j; - }).join(', ')})`; - } else if (getQueries[t][k] instanceof ArrayIn) { - // j += 1; - return `data @> '{"${k}": [${getQueries[t][k].value}]}'`; - } else if (getQueries[t][k] instanceof ArrayLike) { - j += 1; - return `data->>'${k}' LIKE $${j}`; - } - j += 1; - return `data->>'${k}' = $${j}`; - }) - .join(" and "); - // const fieldList = Object.keys(getQueries[t]) - // .map((k) => { - // if (isHistoryQuery) { - // k = k.replace("data.", ""); - // } - // return `data->>'${k}'`; - // }) - // .join(", "); - - let sql = '' - if (isHistoryQuery) { - sql = `SELECT data FROM ${table} WHERE ${wc} order by ${this.getUniqueIndex(table)}, hash desc` - } else { - sql = `select * from (SELECT ${`DISTINCT ON (${this.getUniqueIndex(table)})` - } data FROM ${table} order by ${this.getUniqueIndex(table)}, hash desc) x where ${wc}` - } - getTxElements[t] = { - sql: sql, - params: this.getValuesList(getQueries[t]), - }; - } - } - console.log("Get elements", getTxElements); - const list = await this.executeTxn(client, getTxElements); - - const mapped = {}; - for (const el in list) { - mapped[el] = list[el]?.rows.map((e) => e.data); - } - let [update, updateWhere, insert] = processGetFn(mapped); - - console.log("processGetFn", update, updateWhere, insert); - const updateGetElements = {}; - - if (update && Object.keys(update).length > 0) { - for (const t in updateWhere) { - const tableName = t.split("#")[0]; - if (updateWhere.hasOwnProperty(t)) { - let j = 0; - const wc = Object.keys(updateWhere[t]) - .map((k, i) => { - if (updateWhere[t][k] instanceof Array) { - return `data->>'${k}' in (${updateWhere[t][k].map((e) => { - j += 1; - return "$" + j; - }).join(', ')})`; - } else if (updateWhere[t][k] instanceof ArrayIn) { - // j += 1; - return `data @> '{"${k}": [${updateWhere[t][k].value}]}'`; - } else if (updateWhere[t][k] instanceof ArrayLike) { - j += 1; - return `data->>'${k}' LIKE $${j}`; - } - j += 1; - return `data->>'${k}' = $${j}`; - }) - .join(" and "); - // const fieldList = Object.keys(updateWhere[t]) - // .map((k) => `data->>'${k}'`) - // .join(", "); - updateGetElements[t] = { - sql: `select * from (SELECT DISTINCT ON (${this.getUniqueIndex(tableName)}) data FROM ${tableName} order by ${this.getUniqueIndex(tableName)}, hash desc) x where ${wc}`, - params: this.getValuesList(updateWhere[t]), - }; - } - } - - console.log("TEST", updateGetElements); - const obj = await this.executeTxn(client, updateGetElements); - const updatingObj = {}; - for (const el in obj) { - updatingObj[el] = obj[el]?.rows.map((e) => e.data); - console.log('updateGetElements TEST', el, JSON.stringify(obj[el])) - } - - if (!insert) { - insert = {}; - } - - console.log("Update property", updatingObj, update); - for (const t in updatingObj) { - if (updatingObj.hasOwnProperty(t)) { - if (updatingObj[t]) { - console.log("Length", updatingObj[t].length); - for (const o of updatingObj[t]) { - if (update[t]) { - for (const f in update[t]) { - o[f] = update[t][f]; - } - insert[t] = o; - } - } - } - } - } - console.log("Updated prop", insert); - } - - const updateTxElements = {}; - this.logger.log(`Insert queries`, JSON.stringify(insert)); - for (const qk in insert) { - const tableName = qk.split("#")[0]; - if (insert.hasOwnProperty(qk)) { - updateTxElements[qk] = { - sql: `INSERT INTO "${ - tableName ? tableName : this.tableName - }" ("data", "meta") VALUES ($1, $2)`, - params: [ - insert[qk], - { - version: 0, - txTime: new Date(), - }, - ], - }; - } - } - updateResults = await this.executeTxn(client, updateTxElements); - } finally { - client.release(); - } - this.logger.debug("Response", JSON.stringify(updateResults)); - - const processedResponse = {}; - for (const k in updateResults) { - processedResponse[k] = Array(updateResults[k]?.rowCount).fill(0); - } - return processedResponse; - } -} diff --git a/backend/services/src/shared/ledger-db/qldb-ledger.service.ts b/backend/services/src/shared/ledger-db/qldb-ledger.service.ts deleted file mode 100644 index 1302ff232..000000000 --- a/backend/services/src/shared/ledger-db/qldb-ledger.service.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { QldbDriver, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; -import { dom } from "ion-js"; -import { ArrayIn, ArrayLike, LedgerDBInterface } from './ledger.db.interface'; - -@Injectable() -export class QLDBLedgerService implements LedgerDBInterface { - - public tableName: string; - public overallTableName: string; - public companyTableName: string; - public ledgerName: string; - private driver: QldbDriver; - - constructor(private readonly logger: Logger, private readonly configService: ConfigService) { - this.ledgerName = configService.get('ledger.name'); - this.tableName = configService.get('ledger.table'); - this.overallTableName = configService.get('ledger.overallTable'); - this.companyTableName = configService.get('ledger.companyTable'); - logger.log("QLDB Ledger init ", this.ledgerName); - } - - // TODO: Handler session expire - private async execute(sql, ...parameters: any[]): Promise { - this.logger.debug(`Statement: ${sql}, parameter: ${JSON.stringify(parameters)}`); - this.driver = new QldbDriver(this.ledgerName); - const resp = await this.driver.executeLambda(async (txn: TransactionExecutor) => { - if (parameters.length > 0) { - return await txn.execute(sql, ...parameters); - } else { - return await txn.execute(sql); - } - - }); - this.logger.debug('Response', JSON.stringify(resp)); - this.driver.close(); - return resp; - } - - private async executeTxn(txn: TransactionExecutor, sql, ...parameters: any[]): Promise { - this.logger.debug(`Statement: ${sql}, parameter: ${JSON.stringify(parameters)}`); - if (parameters.length > 0) { - return await txn.execute(sql, ...parameters); - } else { - return await txn.execute(sql); - } - } - - public async createTable(tableName?: string): Promise { - await (await this.execute(`create table ${tableName ? tableName : this.tableName}`)); - } - - public async createIndex(indexCol: string, tableName?: string): Promise { - await (await this.execute(`create index on ${tableName ? tableName : this.tableName} (${indexCol})`)); - } - - public async insertRecord(document: Record, tableName?: string): Promise { - await (await this.execute(`INSERT INTO ${tableName ? tableName : this.tableName} ?`, document)); - } - - public async fetchRecords(where: Record): Promise { - const whereClause = Object.keys(where).map(k => (`${k} = ?`)).join(' and '); - return (await this.execute(`SELECT * FROM ${this.tableName} WHERE ${whereClause}`, ...Object.values(where)))?.getResultList(); - } - - public async fetchHistory(where: Record): Promise { - const whereClause = Object.keys(where).map(k => (`h.data.${k} = ?`)).join(' and '); - const x = (await this.execute(`SELECT * FROM history(${this.tableName}) as h WHERE ${whereClause}`, ...Object.values(where)))?.getResultList(); - console.log('Results', x); - return x; - } - - public async updateRecords(update: Record, where: Record): Promise { - const whereClause = Object.keys(where).map(k => (`${k} = ?`)).join(' and '); - const updateClause = Object.keys(update).map(k => (`${k} = ?`)).join(','); - return (await this.execute(`UPDATE ${this.tableName} SET ${updateClause} WHERE ${whereClause}`, ...Object.values(update), ...Object.values(where)))?.getResultList(); - }; - - private getValuesList(filterObj: any): any { - const list = []; - for (const k in filterObj) { - const v = filterObj[k]; - if (v instanceof ArrayIn) { - list.push(v.value); - } else if (v instanceof ArrayLike) { - list.push(v.value); - } else { - list.push(v); - } - } - return list; - } - - public async getAndUpdateTx(getQueries: Record>, processGetFn: (results: Record) => [Record, Record, Record]): Promise> { - this.logger.debug(``); - this.driver = new QldbDriver(this.ledgerName); - const resp = await this.driver.executeLambda(async (txn: TransactionExecutor) => { - const getResults = {}; - for (const t in getQueries) { - if (getQueries.hasOwnProperty(t)) { - const wc = Object.keys(getQueries[t]).map(k => { - if (getQueries[t][k] instanceof Array) { - return (`${k} in ?`); - } else if (getQueries[t][k] instanceof ArrayIn) { - return (`? IN "${getQueries[t][k].key}"`); - } else if (getQueries[t][k] instanceof ArrayLike) { - return (`${k} LIKE ?`); - } - return (`${k} = ?`); - }).join(' and '); - const r = (await this.executeTxn(txn, `SELECT * FROM ${t} WHERE ${wc}`, ...this.getValuesList(getQueries[t])))?.getResultList(); - getResults[t] = r; - } - } - const [update, updateWhere, insert] = processGetFn(getResults); - const updateResults = {}; - for (const qk in update) { - const tableName = qk.split('#')[0]; - if (update.hasOwnProperty(qk) && updateWhere.hasOwnProperty(qk)) { - const whereClause = Object.keys(updateWhere[qk]).map(k => (`${k} = ?`)).join(' and '); - const updateClause = Object.keys(update[qk]).map(k => (`${k} = ?`)).join(','); - updateResults[qk] = (await this.executeTxn(txn, `UPDATE ${tableName} SET ${updateClause} WHERE ${whereClause}`, ...Object.values(update[qk]), ...Object.values(updateWhere[qk])))?.getResultList(); - } - } - - this.logger.verbose(`Insert queries`, JSON.stringify(insert)); - for (const qk in insert) { - const tableName = qk.split('#')[0]; - if (insert.hasOwnProperty(qk)) { - updateResults[qk] = (await this.executeTxn(txn, `INSERT INTO ${tableName ? tableName : this.tableName} ?`, insert[qk]))?.getResultList(); - } - } - - return updateResults; - }); - this.logger.debug('Response', JSON.stringify(resp)); - this.driver.close(); - return resp; - } - -} diff --git a/backend/services/src/shared/location/file.location.service.ts b/backend/services/src/shared/location/file.location.service.ts deleted file mode 100644 index 7f9e1a6ed..000000000 --- a/backend/services/src/shared/location/file.location.service.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { resolve } from "path"; -import { LocationInterface } from "./location.interface"; -const fs = require('fs') - -@Injectable() -export class FileLocationService implements LocationInterface { - - private regionMap: { [key: string]: number[] } = {} - constructor( - private logger: Logger - ) { - const deliminator = ',' - const regionRawData = fs.readFileSync('regions.csv', 'utf8'); - const headers = regionRawData.slice(0, regionRawData.indexOf("\n")).split(deliminator).map(e => e.trim().replace('\r', '')) - const rows = regionRawData.slice(regionRawData.indexOf("\n") + 1).split("\n") - - const nameIndex = headers.indexOf('Name') - const latitudeIndex = headers.indexOf('Latitude') - const longitudeIndex = headers.indexOf('Longitude') - console.log(headers, nameIndex, latitudeIndex, longitudeIndex) - if (nameIndex >=0 && latitudeIndex >=0 && longitudeIndex >=0) { - for (let row of rows) { - row = row.replace('\r', '') - const columns = row.split(deliminator) - if (columns.length != headers.length) { - continue - } - this.regionMap[columns[nameIndex].trim()] = [ Number(columns[longitudeIndex].trim()), Number(columns[latitudeIndex].trim()) ] - } - } - - this.logger.log(`Regions loaded: ${Object.values(this.regionMap).length}`) - } - - public init(): Promise { - return null; - } - - public getCoordinatesForRegion(regions: string[]): Promise { - return new Promise((resolve, reject) => { - resolve(regions.map( (region) => { - return this.regionMap[region] - })); - }) - } - -} \ No newline at end of file diff --git a/backend/services/src/shared/location/location.interface.ts b/backend/services/src/shared/location/location.interface.ts deleted file mode 100644 index 092e3bd5a..000000000 --- a/backend/services/src/shared/location/location.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from "@nestjs/common"; - -@Injectable() -export abstract class LocationInterface { - - public abstract init(): Promise; - public abstract getCoordinatesForRegion(regions: string[]): Promise; -} diff --git a/backend/services/src/shared/location/location.module.ts b/backend/services/src/shared/location/location.module.ts deleted file mode 100644 index 01c98d5bc..000000000 --- a/backend/services/src/shared/location/location.module.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Logger, Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import configuration from "../configuration"; -import { Region } from "../entities/region.entity"; -import { LocationType } from "../enum/location.type"; -import { TypeOrmConfigService } from "../typeorm.config.service"; -import { FileLocationService } from "./file.location.service"; -import { LocationInterface } from "./location.interface"; -import { MapboxLocationService } from "./mapbox.location.service"; -import { OpenStreetLocationService } from "./openstreet.location.service"; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - imports: undefined, - }), - TypeOrmModule.forFeature([Region]), - ], - providers: [ - Logger, - { - provide: LocationInterface, - useClass: - process.env.LOCATION_SERVICE === LocationType.MAPBOX - ? MapboxLocationService - : process.env.LOCATION_SERVICE === LocationType.OPENSTREET - ? OpenStreetLocationService - : FileLocationService, - }, - ], - exports: [LocationInterface], -}) -export class LocationModule {} diff --git a/backend/services/src/shared/location/mapbox.location.service.ts b/backend/services/src/shared/location/mapbox.location.service.ts deleted file mode 100644 index 77b8bea4a..000000000 --- a/backend/services/src/shared/location/mapbox.location.service.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import axios from "axios"; -import { LocationInterface } from "./location.interface"; - -@Injectable() -export class MapboxLocationService implements LocationInterface { - - constructor( - private logger: Logger, - private configService: ConfigService - ) {} - - public init(): Promise { - return null; - } - - public async getCoordinatesForRegion(regions: string[]): Promise { - - console.log("addresses passed to forwardGeocoding function -> ", regions); - let geoCodinates: any[] = []; - const ACCESS_TOKEN = this.configService.get('mapbox.key'); - - for (let index = 0; index < regions.length; index++) { - const url = - "https://api.mapbox.com/geocoding/v5/mapbox.places/" + - encodeURIComponent(regions[index]) + - ".json?access_token=" + - ACCESS_TOKEN + - "&limit=1" + - `&country=${this.configService.get( - "systemCountry" - )}&autocomplete=false&types=region%2Cdistrict`; - console.log("geocoding request urls -> ", index, url); - await axios - .get(url) - .then(function (response) { - // handle success - console.log( - "cordinates data in replicator -> ", - response?.data?.features[0], - response?.data?.features[0]?.center - ); - if (response?.data?.features.length > 0) { - geoCodinates.push([...response?.data?.features[0]?.center]); - } else { - geoCodinates.push(null); - } - }) - .catch((err) => { - this.logger.error("Geocoding failed - ", err); - return err; - }); - } - - return geoCodinates; - - } -} diff --git a/backend/services/src/shared/location/openstreet.location.service.ts b/backend/services/src/shared/location/openstreet.location.service.ts deleted file mode 100644 index c88ad6989..000000000 --- a/backend/services/src/shared/location/openstreet.location.service.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Repository } from "typeorm"; -import { Region } from "../entities/region.entity"; -import { LocationInterface } from "./location.interface"; -import axios from "axios"; -import { ConfigService } from "@nestjs/config"; - -@Injectable() -export class OpenStreetLocationService implements LocationInterface { - constructor( - private logger: Logger, - private configService: ConfigService, - @InjectRepository(Region) private regionRepo: Repository - ) {} - - public async init(): Promise { - this.logger.log('open street init') - return await this.retrieveData(); - } - - public async retrieveData() { - if ( - this.configService.get("openstreet.retrieve") || - (await this.regionRepo.count()) <= 0 - ) { - const data: Region[] = []; - const countryCode = this.configService.get("systemCountryCode"); - const query = `data=%5Bout%3Ajson%5D%3B%0Aarea%5B%22ISO3166-1%22%3D%22${countryCode}%22%5D-%3E.a%3B%0A%28%0A%20%20node%28area.a%29%5B%22admin_level%22%3D%224%22%5D%3B%0A%29%3B%0Aout%20body%3B`; - this.logger.log('Region query', query); - const response = await axios - .post("https://overpass-api.de/api/interpreter", query) - .catch((err) => { - this.logger.error("Geocoding failed - ", err); - return err; - }); - - if (response && response.data?.elements) { - - for (const element of response.data?.elements) { - const location = [element.lon, element.lat]; - - if (element.tags) { - for (const tag in element.tags) { - if (tag.startsWith("name:") || tag === "name") { - const region = new Region(); - region.countryAlpha2 = countryCode; - region.regionName = element.tags[tag]; - region.geoCoordinates = location; - const t = tag.split(':'); - region.lang = t.length > 1 ? t[1] : 'en'; - region.key = tag + '_' + element.id; - data.push(region); - } - } - } - } - } - await this.regionRepo.save(data); - this.logger.log(`Regions loaded: ${data.length}`); - } else { - this.logger.log(`Skipped adding regions ${this.configService.get("openstreet.retrieve")}`) - } - } - - public async getCoordinatesForRegion(regions: string[]): Promise { - const list = []; - for (const region of regions) { - list.push( - (await this.regionRepo.findOneBy({ - regionName: region, - }))?.geoCoordinates - ); - } - return list; - } -} diff --git a/backend/services/src/shared/programme-ledger/programme-ledger.module.ts b/backend/services/src/shared/programme-ledger/programme-ledger.module.ts deleted file mode 100644 index cfb52ce21..000000000 --- a/backend/services/src/shared/programme-ledger/programme-ledger.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Module, Logger } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { CompanyModule } from '../company/company.module'; -import { CaslModule } from '../casl/casl.module'; -import { ConstantEntity } from '../entities/constants.entity'; -import { Programme } from '../entities/programme.entity'; -import { LedgerDbModule } from '../ledger-db/ledger-db.module'; -import { UtilModule } from '../util/util.module'; -import { ProgrammeLedgerService } from './programme-ledger.service'; - -@Module({ - imports: [LedgerDbModule, ProgrammeLedgerModule, CaslModule, TypeOrmModule.forFeature([Programme]), TypeOrmModule.forFeature([ConstantEntity]), UtilModule], - providers: [ProgrammeLedgerService, Logger], - exports: [ProgrammeLedgerService] -}) -export class ProgrammeLedgerModule {} diff --git a/backend/services/src/shared/programme-ledger/programme-ledger.service.spec.ts b/backend/services/src/shared/programme-ledger/programme-ledger.service.spec.ts deleted file mode 100644 index bbd38dba7..000000000 --- a/backend/services/src/shared/programme-ledger/programme-ledger.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ProgrammeLedgerService } from './programme-ledger.service'; - -describe('ProgrammeLedgerService', () => { - let service: ProgrammeLedgerService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ProgrammeLedgerService], - }).compile(); - - service = module.get(ProgrammeLedgerService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/programme-ledger/programme-ledger.service.ts b/backend/services/src/shared/programme-ledger/programme-ledger.service.ts deleted file mode 100644 index 9f63c1eaa..000000000 --- a/backend/services/src/shared/programme-ledger/programme-ledger.service.ts +++ /dev/null @@ -1,1673 +0,0 @@ -import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; -import { InjectEntityManager } from "@nestjs/typeorm"; -import { PRECISION } from "@undp/carbon-credit-calculator/dist/esm/calculator"; -import { plainToClass } from "class-transformer"; -import { dom } from "ion-js"; -import axios from "axios"; -import { generateSerialNumber } from "@undp/serial-number-gen"; -import { EntityManager } from "typeorm"; -import { ProgrammeHistoryDto } from "../dto/programme.history.dto"; -import { CreditOverall } from "../entities/credit.overall.entity"; -import { Programme } from "../entities/programme.entity"; -import { ProgrammeTransfer } from "../entities/programme.transfer"; -import { TxType } from "../enum/txtype.enum"; -import { ProgrammeStage } from "../../shared/enum/programme-status.enum"; -import { - ArrayIn, - ArrayLike, - LedgerDBInterface, -} from "../ledger-db/ledger.db.interface"; -import { HelperService } from "../util/helpers.service"; -import { Company } from "../entities/company.entity"; -import { url } from "inspector"; -import { CompanyRole } from "../enum/company.role.enum"; -import { MitigationProperties } from "../dto/mitigation.properties"; -import { OwnershipUpdateDto } from "../dto/ownership.update"; - -@Injectable() -export class ProgrammeLedgerService { - constructor( - private readonly logger: Logger, - @InjectEntityManager() private entityManger: EntityManager, - private ledger: LedgerDBInterface, - private helperService: HelperService - ) {} - - public async createProgramme(programme: Programme): Promise { - this.logger.debug("Creating programme", JSON.stringify(programme)); - programme.txType = TxType.CREATE; - - const getQueries = {}; - getQueries[this.ledger.tableName] = { - externalId: programme.externalId, - }; - - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - if (programmes.length > 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeExistsWithSameExetrnalId", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let insertMap = {}; - insertMap[this.ledger.tableName] = programme; - - return [{}, {}, insertMap]; - } - ); - // let address: any[] = []; - // if (programme && programme.programmeProperties) { - // if (programme.currentStage === "AwaitingAuthorization") { - // const programmeProperties = programme.programmeProperties; - // if (programmeProperties.geographicalLocation) { - // for ( - // let index = 0; - // index < programmeProperties.geographicalLocation.length; - // index++ - // ) { - // address.push(programmeProperties.geographicalLocation[index]); - // } - // } - // await this.forwardGeocoding([...address]).then((response: any) => { - // programme.geographicalLocationCordintes = [...response]; - // }); - // } - // } - // if (programme) { - // await this.entityManger - // .save(plainToClass(Programme, programme)) - // .then((res: any) => { - // console.log("create programme in repo -- ", res); - // }) - // .catch((e: any) => { - // console.log("create programme in repo -- ", e); - // }); - // } - return programme; - } - - public async transferProgramme( - transfer: ProgrammeTransfer, - name: string, - reason: string, - isRetirement: boolean = false - ) { - this.logger.log(`Transfer programme ${JSON.stringify(transfer)}`); - - const getQueries = {}; - getQueries[`history(${this.ledger.tableName})`] = { - "data.programmeId": transfer.programmeId, - "data.txRef": new ArrayLike( - "data.txRef", - "%#" + transfer.requestId + "#%" - ), - }; - getQueries[this.ledger.tableName] = { - programmeId: transfer.programmeId, - }; - - const toAccountID = transfer.toAccount - ? transfer.toCompanyId + "#" + transfer.toAccount - : transfer.toCompanyId + ""; - const fromAccount = String(transfer.fromCompanyId); - getQueries[this.ledger.companyTableName] = { - txId: [fromAccount, toAccountID], - }; - let updatedProgramme = undefined; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const alreadyProcessed = results[`history(${this.ledger.tableName})`]; - if (alreadyProcessed.length > 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.transferRequestALreadyProcessed", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExistWIthId", - [transfer.programmeId] - ), - HttpStatus.BAD_REQUEST - ); - } - const programme = programmes[0]; - if (!transfer.creditAmount) { - transfer.creditAmount = programme.creditBalance; - } - - let companyCreditBalances = {}; - const companies = results[this.ledger.companyTableName].map( - (domValue) => { - return plainToClass( - CreditOverall, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - for (const company of companies) { - companyCreditBalances[company.txId] = company.credit; - } - - let companyCreditDistribution = {}; - if (programme.creditOwnerPercentage) { - const percentages = []; - const currentCredit = {}; - const frozenCredit = {}; - for (const i in programme.creditOwnerPercentage) { - currentCredit[programme.companyId[i]] = - (programme.creditBalance * programme.creditOwnerPercentage[i]) / - 100; - - frozenCredit[programme.companyId[i]] = programme.creditFrozen - ? programme.creditFrozen[i] - : 0; - } - if (!currentCredit[transfer.fromCompanyId]) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.companyIsNotTheOwnerOfProg", - [transfer.fromCompanyId] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - currentCredit[transfer.fromCompanyId] - - frozenCredit[transfer.fromCompanyId] < - transfer.creditAmount - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.companyHaveNoEnoughCredits", - [transfer.fromCompanyId] - ), - HttpStatus.BAD_REQUEST - ); - } - - for (const i in programme.creditOwnerPercentage) { - if (programme.companyId[i] == transfer.fromCompanyId) { - percentages.push( - programme.creditBalance - transfer.creditAmount != 0 - ? parseFloat( - ( - ((currentCredit[transfer.fromCompanyId] - - transfer.creditAmount) * - 100) / - (programme.creditBalance - transfer.creditAmount) - ).toFixed(6) - ) - : 0 - ); - } else { - percentages.push( - programme.creditBalance - transfer.creditAmount != 0 - ? parseFloat( - ( - (currentCredit[programme.companyId[i]] * 100) / - (programme.creditBalance - transfer.creditAmount) - ).toFixed(6) - ) - : 0 - ); - } - } - programme.creditOwnerPercentage = percentages; - this.logger.verbose("Updated owner percentages", percentages); - } - - companyCreditDistribution[fromAccount] = -transfer.creditAmount; - companyCreditDistribution[toAccountID] = transfer.creditAmount; - - const prvTxTime = programme.txTime; - programme.txTime = new Date().getTime(); - programme.txRef = `${name}#${transfer.requestId}#${transfer.retirementType}#${reason}`; - - const compIndex = programme.companyId.indexOf(transfer.fromCompanyId); - if (compIndex < 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.companyIsNotTheOwnerOfProg", - [transfer.fromCompanyId] - ), - HttpStatus.BAD_REQUEST - ); - } - if (isRetirement) { - // if (programme.creditBalance == transfer.creditAmount) { - // programme.currentStage = ProgrammeStage.RETIRED; - // } - programme.txType = TxType.RETIRE; - if (!programme.creditRetired) { - programme.creditRetired = new Array( - programme.creditOwnerPercentage.length - ).fill(0); - } - programme.creditRetired[compIndex] += transfer.creditAmount; - } else { - programme.txType = TxType.TRANSFER; - if (!programme.creditTransferred) { - programme.creditTransferred = new Array( - programme.creditOwnerPercentage.length - ).fill(0); - } - programme.creditTransferred[compIndex] += transfer.creditAmount; - } - programme.creditChange = transfer.creditAmount; - programme.creditBalance -= transfer.creditAmount; - - // if (programme.creditBalance <= 0) { - // programme.currentStage = ProgrammeStage.TRANSFERRED; - // } - - updatedProgramme = programme; - const uPayload = { - txTime: programme.txTime, - txRef: programme.txRef, - txType: programme.txType, - creditChange: programme.creditChange, - creditBalance: programme.creditBalance, - companyId: programme.companyId, - currentStage: programme.currentStage, - }; - - if (programme.creditOwnerPercentage) { - uPayload["creditOwnerPercentage"] = programme.creditOwnerPercentage; - } - - if (isRetirement) { - uPayload["creditRetired"] = programme.creditRetired; - } else { - uPayload["creditTransferred"] = programme.creditTransferred; - } - - let updateMap = {}; - let updateWhereMap = {}; - let insertMap = {}; - updateMap[this.ledger.tableName] = uPayload; - updateWhereMap[this.ledger.tableName] = { - programmeId: programme.programmeId, - currentStage: ProgrammeStage.AUTHORISED.valueOf(), - txTime: prvTxTime, - }; - - for (const com of [fromAccount, toAccountID]) { - if (companyCreditBalances[com] != undefined) { - updateMap[this.ledger.companyTableName + "#" + com] = { - credit: this.round2Precision( - companyCreditBalances[com] + companyCreditDistribution[com] - ), - txRef: transfer.requestId + "#" + programme.serialNo, - txType: TxType.TRANSFER, - }; - updateWhereMap[this.ledger.companyTableName + "#" + com] = { - txId: com, - }; - } else { - insertMap[this.ledger.companyTableName + "#" + com] = { - credit: this.round2Precision(companyCreditDistribution[com]), - txRef: transfer.requestId + "#" + programme.serialNo, - txType: TxType.TRANSFER, - txId: com, - }; - } - } - - return [updateMap, updateWhereMap, insertMap]; - } - ); - - const affected = resp[this.ledger.tableName]; - if (affected && affected.length > 0) { - return updatedProgramme; - } - return updatedProgramme; - } - - public async getProgrammeById(programmeId: string): Promise { - const p = ( - await this.ledger.fetchRecords({ - programmeId: programmeId, - }) - ).map((domValue) => { - return plainToClass(Programme, JSON.parse(JSON.stringify(domValue))); - }); - return p.length <= 0 ? null : p[0]; - } - - public async getProgrammeHistory( - programmeId: string - ): Promise { - return ( - await this.ledger.fetchHistory({ - programmeId: programmeId, - }) - )?.map((domValue) => { - return plainToClass( - ProgrammeHistoryDto, - JSON.parse(JSON.stringify(domValue)) - ); - }); - } - - public async getProgrammeHistoryByExternalId( - externalId: string - ): Promise { - return ( - await this.ledger.fetchHistory({ - externalId: externalId, - }) - )?.map((domValue) => { - return plainToClass( - ProgrammeHistoryDto, - JSON.parse(JSON.stringify(domValue)) - ); - }); - } - - public async updateCertifier( - programmeId: string, - certifierId: number, - add: boolean, - user: string - ) { - const getQueries = {}; - getQueries[this.ledger.tableName] = { - programmeId: programmeId, - }; - - let updatedProgramme; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let programme = programmes[0]; - const index = programme.certifierId - ? programme.certifierId.indexOf(certifierId) - : -1; - if (add) { - if (index >= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.alreadyCertified", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (programme.currentStage != ProgrammeStage.AUTHORISED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.unAuth", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (!programme.certifierId) { - programme.certifierId = [certifierId]; - } else { - programme.certifierId.push(certifierId); - } - - const reIndex = programme.revokedCertifierId - ? programme.revokedCertifierId.indexOf(certifierId) - : -1; - if (reIndex >= 0) { - programme.revokedCertifierId.splice(reIndex, 1); - } - } else { - if (!programme.certifierId.includes(certifierId)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.notCertifiedByCertifier", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - programme.certifierId.splice(index, 1); - - // if (programme.certifierId.length === 0) { - // programme.certifierId = undefined; - // } - - if (!programme.revokedCertifierId) { - programme.revokedCertifierId = [certifierId]; - } else { - const reIndex = programme.revokedCertifierId.indexOf(certifierId); - if (reIndex < 0) { - programme.revokedCertifierId.push(certifierId); - } - } - } - - programme.txRef = user; - programme.txTime = new Date().getTime(); - programme.txType = add ? TxType.CERTIFY : TxType.REVOKE; - - let updateMap = {}; - let updateWhere = {}; - updateMap[this.ledger.tableName] = { - certifierId: programme.certifierId, - txType: programme.txType, - txTime: programme.txTime, - txRef: programme.txRef, - }; - - if (programme.revokedCertifierId) { - updateMap[this.ledger.tableName]["revokedCertifierId"] = - programme.revokedCertifierId; - } - - updateWhere[this.ledger.tableName] = { - programmeId: programme.programmeId, - }; - - updatedProgramme = programme; - return [updateMap, updateWhere, {}]; - } - ); - - const affected = resp[this.ledger.tableName]; - if (affected && affected.length > 0) { - return updatedProgramme; - } - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.failedToUpdate", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - public async revokeCompanyCertifications( - companyId: number, - user: string, - sendRevokeEmail: Function - ): Promise { - this.logger.log( - `Freezing programme credits companyId:${companyId} user:${user}` - ); - const getQueries = {}; - companyId = Number(companyId); - getQueries[this.ledger.tableName] = { - certifierId: new ArrayIn("certifierId", companyId), - }; - - let programmesId = []; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - - let updateMap = {}; - let updateWhere = {}; - - for (const programme of programmes) { - const index = programme.certifierId.indexOf(companyId); - if (index < 0) { - continue; - } - - const prvTxTime = programme.txTime; - programme.txTime = new Date().getTime(); - programme.txRef = `${user}`; - programme.txType = TxType.REVOKE; - programme.certifierId.splice(index, 1); - - updateMap[this.ledger.tableName + "#" + programme.programmeId] = { - txType: programme.txType, - txTime: programme.txTime, - txRef: programme.txRef, - certifierId: programme.certifierId, - }; - updateWhere[this.ledger.tableName + "#" + programme.programmeId] = { - programmeId: programme.programmeId, - txTime: prvTxTime, - }; - - programmesId.push(programme.programmeId); - - sendRevokeEmail(programme); - } - // updatedProgramme = programme; - return [updateMap, updateWhere, {}]; - } - ); - - return programmesId; - } - - public async freezeCompany( - companyId: number, - user: any, - isFreeze: boolean - ): Promise { - this.logger.log( - `Freezing programme credits companyId:${companyId} user:${user}` - ); - const getQueries = {}; - companyId = Number(companyId); - getQueries[this.ledger.tableName] = { - companyId: new ArrayIn("companyId", companyId), - }; - - let programmesId = []; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - - let updateMap = {}; - let updateWhere = {}; - - for (const programme of programmes) { - const index = programme.companyId.indexOf(companyId); - if (index < 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.doesNotOwnByCompany", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (isFreeze) { - if (programme.companyId.length > 1) { - if (!programme.creditOwnerPercentage) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.noOwnershipPercForCompany", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - } else { - programme.creditOwnerPercentage = [100]; - } - - const freezeCredit = this.round2Precision( - (programme.creditBalance * - programme.creditOwnerPercentage[index]) / - 100 - ); - if (!programme.creditFrozen) { - programme.creditFrozen = new Array( - programme.creditOwnerPercentage.length - ).fill(0); - } - if (freezeCredit === 0) continue; - programme.creditFrozen[index] = freezeCredit; - programme.creditChange = freezeCredit; - } else { - if ( - programme.creditFrozen === undefined || - programme.creditFrozen[index] === null - ) - continue; - const unFrozenCredit = this.round2Precision( - programme.creditFrozen[index] - ); - if (unFrozenCredit === 0) continue; - programme.creditChange = unFrozenCredit; - programme.creditFrozen[index] = 0; - } - - const prvTxTime = programme.txTime; - (programme.txTime = new Date().getTime()), - (programme.txRef = user), - (programme.txType = isFreeze ? TxType.FREEZE : TxType.UNFREEZE); - - updateMap[this.ledger.tableName + "#" + programme.programmeId] = { - currentStage: programme.currentStage, - txType: programme.txType, - txTime: programme.txTime, - txRef: programme.txRef, - creditFrozen: programme.creditFrozen, - creditChange: programme.creditChange, - }; - updateWhere[this.ledger.tableName + "#" + programme.programmeId] = { - programmeId: programme.programmeId, - txTime: prvTxTime, - }; - - programmesId.push(programme.programmeId); - } - // updatedProgramme = programme; - return [updateMap, updateWhere, {}]; - } - ); - - return programmesId; - } - - public async freezeProgramme( - programmeId: string, - companyId: number, - reason: string, - user: string - ): Promise { - this.logger.log( - `Freezing programme credits:${programmeId} reason:${reason} companyId:${companyId} user:${user}` - ); - const getQueries = {}; - getQueries[this.ledger.tableName] = { - companyId: new ArrayIn("companyId", companyId), - }; - - let updatedProgramme; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - - let updateMap = {}; - let updateWhere = {}; - - for (const programme of programmes) { - const index = programme.companyId.indexOf(companyId); - if (index < 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.doesNotOwnByCompany", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (programme.companyId.length > 1) { - if (!programme.creditOwnerPercentage) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.noOwnershipPercForCompany", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - } else { - programme.creditOwnerPercentage = [100]; - } - - const freezeCredit = - (programme.creditBalance * programme.creditOwnerPercentage[index]) / - 100; - if (!programme.creditFrozen) { - programme.creditFrozen = new Array( - programme.creditOwnerPercentage.length - ).fill(0); - } - - const prvTxTime = programme.txTime; - (programme.txTime = new Date().getTime()), - (programme.txRef = `${user}#${reason}`), - (programme.txType = TxType.FREEZE); - programme.creditFrozen[index] = freezeCredit; - - updateMap[this.ledger.tableName + "#" + programme.programmeId] = { - currentStage: programme.currentStage, - txType: programme.txType, - txTime: programme.txTime, - txRef: programme.txRef, - creditFrozen: programme.creditFrozen, - }; - updateWhere[this.ledger.tableName + "#" + programme.programmeId] = { - programmeId: programme.programmeId, - txTime: prvTxTime, - }; - } - // updatedProgramme = programme; - return [updateMap, updateWhere, {}]; - } - ); - - const affected = resp[this.ledger.tableName]; - if (affected && affected.length > 0) { - return updatedProgramme; - } - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.failedToUpdate", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - // public async retireProgramme( - // programmeId: string, - // reason: string, - // user: string - // ): Promise { - // this.logger.log(`Retiring programme:${programmeId} reason:${reason} user:${user}`); - // const getQueries = {}; - // getQueries[this.ledger.tableName] = { - // programmeId: programmeId, - // }; - - // let updatedProgramme; - // const resp = await this.ledger.getAndUpdateTx( - // getQueries, - // (results: Record) => { - // const programmes: Programme[] = results[this.ledger.tableName].map( - // (domValue) => { - // return plainToClass( - // Programme, - // JSON.parse(JSON.stringify(domValue)) - // ); - // } - // ); - // if (programmes.length <= 0) { - // throw new HttpException( - // this.helperService.formatReqMessagesString("programme.programmeNotExist", []), - // HttpStatus.BAD_REQUEST - // ); - // } - - // let programme = programmes[0]; - // const prvTxTime = programme.txTime; - // programme.currentStage = ProgrammeStage.RETIRED, - // programme.txTime = new Date().getTime(), - // programme.txRef = `${user}#${reason}`, - // programme.txType = TxType.RETIRE - // programme.creditRetired = programme.creditBalance; - // programme.creditBalance = 0; - // programme.creditChange = programme.creditRetired; - - // let updateMap = {}; - // let updateWhere = {}; - // updateMap[this.ledger.tableName] = { - // currentStage: programme.currentStage, - // txType: programme.txType, - // txTime: programme.txTime, - // txRef: programme.txRef, - // creditRetired: programme.creditRetired, - // creditBalance: programme.creditBalance, - // creditChange: programme.creditChange - // }; - // updateWhere[this.ledger.tableName] = { - // programmeId: programme.programmeId, - // txTime: prvTxTime - // }; - - // updatedProgramme = programme; - // return [updateMap, updateWhere, {}]; - // } - // ); - - // const affected = resp[this.ledger.tableName]; - // if (affected && affected.length > 0) { - // return updatedProgramme; - // } - // throw new HttpException( - // this.helperService.formatReqMessagesString("programme.failedToUpdate", []), - // HttpStatus.INTERNAL_SERVER_ERROR - // ); - // } - - public async updateProgrammeStatus( - programmeId: string, - status: ProgrammeStage, - currentExpectedStatus: ProgrammeStage, - user: string - ): Promise { - this.logger.log(`Updating programme ${programmeId} status ${status}`); - const affected = await this.ledger.updateRecords( - { - currentStage: status.valueOf(), - txTime: new Date().getTime(), - txRef: user, - txType: status == ProgrammeStage.REJECTED ? TxType.REJECT : null, - }, - { - programmeId: programmeId, - currentStage: currentExpectedStatus.valueOf(), - } - ); - if (affected && affected.length > 0) { - return true; - } - return false; - } - - private round2Precision(val) { - if (val) return parseFloat(val.toFixed(PRECISION)); - else return 0; - } - - public async authProgrammeStatus( - programmeId: string, - countryCodeA2: string, - companyIds: number[], - issueCredit: number, - user: string - ): Promise { - this.logger.log(`Authorizing programme ${programmeId}`); - - const getQueries = {}; - getQueries[this.ledger.tableName] = { - programmeId: programmeId, - }; - getQueries[this.ledger.overallTableName] = { - txId: countryCodeA2, - }; - - getQueries[this.ledger.companyTableName] = { - txId: companyIds.map((e) => String(e)), - }; - - let updatedProgramme = undefined; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const creditOveralls = results[this.ledger.overallTableName].map( - (domValue) => { - return plainToClass( - CreditOverall, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - if (creditOveralls.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.overallCreditNotFoundforCountryCode", - [countryCodeA2] - ), - HttpStatus.BAD_REQUEST - ); - } - - let companyCreditBalances = {}; - const companies = results[this.ledger.companyTableName].map( - (domValue) => { - return plainToClass( - CreditOverall, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - this.logger.verbose(results[this.ledger.companyTableName]); - for (const company of companies) { - companyCreditBalances[company.txId] = company.credit; - } - - const programme = programmes[0]; - const overall = creditOveralls[0]; - const year = new Date(programme.startTime * 1000).getFullYear(); - const startBlock = Math.ceil(overall.credit + 1); - const endBlock = Math.ceil(overall.credit + programme.creditEst); - const serialNo = generateSerialNumber( - programme.countryCodeA2, - programme.sectoralScope, - programme.programmeId, - year, - startBlock, - endBlock, - programme.creditUnit - ); - programme.serialNo = serialNo; - programme.txTime = new Date().getTime(); - programme.currentStage = ProgrammeStage.AUTHORISED; - - if (!issueCredit) { - programme.creditIssued = 0; - // programme.creditPending = 0 - } else { - programme.creditIssued = issueCredit; - // programme.creditPending = programme.creditEst - issueCredit; - } - programme.creditBalance = programme.creditIssued; - programme.creditChange = programme.creditIssued; - programme.txRef = user; - programme.txType = TxType.AUTH; - updatedProgramme = programme; - - let companyCreditDistribution = {}; - if (programme.creditOwnerPercentage) { - for (const j in programme.creditOwnerPercentage) { - companyCreditDistribution[String(programme.companyId[j])] = - (programme.creditIssued * programme.creditOwnerPercentage[j]) / - 100; - } - } else if (programme.companyId.length == 1) { - companyCreditDistribution[String(programme.companyId[0])] = - programme.creditIssued; - } else { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.unExpectedProgOwnerPerc", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let updateMap = {}; - let updateWhereMap = {}; - let insertMap = {}; - updateMap[this.ledger.tableName] = { - currentStage: ProgrammeStage.AUTHORISED.valueOf(), - serialNo: serialNo, - creditIssued: programme.creditIssued, - creditBalance: programme.creditBalance, - creditChange: programme.creditChange, - txRef: programme.txRef, - txTime: programme.txTime, - txType: programme.txType, - }; - updateWhereMap[this.ledger.tableName] = { - programmeId: programmeId, - currentStage: ProgrammeStage.AWAITING_AUTHORIZATION.valueOf(), - }; - - updateMap[this.ledger.overallTableName] = { - credit: endBlock, - txRef: serialNo, - txType: TxType.AUTH, - }; - updateWhereMap[this.ledger.overallTableName] = { - txId: countryCodeA2, - }; - - for (const com of programme.companyId) { - if (companyCreditBalances[String(com)] != undefined) { - updateMap[this.ledger.companyTableName + "#" + com] = { - credit: this.round2Precision( - companyCreditBalances[String(com)] + - companyCreditDistribution[String(com)] - ), - txRef: serialNo, - txType: TxType.AUTH, - }; - updateWhereMap[this.ledger.companyTableName + "#" + com] = { - txId: String(com), - }; - } else { - insertMap[this.ledger.companyTableName + "#" + com] = { - credit: this.round2Precision( - companyCreditDistribution[String(com)] - ), - txRef: serialNo, - txType: TxType.AUTH, - txId: String(com), - }; - } - } - return [updateMap, updateWhereMap, insertMap]; - } - ); - - const affected = resp[this.ledger.tableName]; - if (affected && affected.length > 0) { - return updatedProgramme; - } - return updatedProgramme; - } - - public async issueProgrammeStatus( - programmeId: string, - countryCodeA2: string, - companyIds: number[], - issueCredit: number, - user: string - ): Promise { - this.logger.log(`Issue programme credit ${programmeId}`); - - const getQueries = {}; - getQueries[this.ledger.tableName] = { - programmeId: programmeId, - }; - - getQueries[this.ledger.companyTableName] = { - txId: companyIds.map((e) => String(e)), - }; - - let updatedProgramme = undefined; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let companyCreditBalances = {}; - const companies = results[this.ledger.companyTableName].map( - (domValue) => { - return plainToClass( - CreditOverall, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - this.logger.verbose(results[this.ledger.companyTableName]); - for (const company of companies) { - companyCreditBalances[company.txId] = company.credit; - } - - const programme = programmes[0]; - programme.txTime = new Date().getTime(); - - if (!issueCredit) { - programme.creditChange = programme.creditEst - programme.creditIssued; - programme.creditIssued = programme.creditEst; - // programme.creditPending = 0 - } else { - programme.creditIssued += issueCredit; - programme.creditChange = issueCredit; - // programme.creditPending = programme.creditEst - issueCredit; - } - const currentTotalBalance = programme.creditBalance; - programme.creditBalance += programme.creditChange; - programme.txRef = user; - programme.txType = TxType.ISSUE; - updatedProgramme = programme; - - let companyCreditDistribution = {}; - if (programme.creditOwnerPercentage) { - const percentages = []; - - for (const i in programme.creditOwnerPercentage) { - const currentCredit = - (currentTotalBalance * programme.creditOwnerPercentage[i]) / 100; - const changeCredit = - (programme.creditChange * programme.proponentPercentage[i]) / 100; - - companyCreditDistribution[String(programme.companyId[i])] = - changeCredit; - percentages.push( - parseFloat( - ( - ((currentCredit + changeCredit) * 100) / - programme.creditBalance - ).toFixed(6) - ) - ); - } - programme.creditOwnerPercentage = percentages; - this.logger.verbose("Updated owner percentages", percentages); - } else { - companyCreditDistribution[String(programme.companyId[0])] = - programme.creditChange; - } - - let updateMap = {}; - let updateWhereMap = {}; - updateMap[this.ledger.tableName] = { - creditIssued: programme.creditIssued, - creditBalance: programme.creditBalance, - creditChange: programme.creditChange, - txRef: programme.txRef, - txTime: programme.txTime, - txType: programme.txType, - creditOwnerPercentage: programme.creditOwnerPercentage, - }; - updateWhereMap[this.ledger.tableName] = { - programmeId: programmeId, - currentStage: ProgrammeStage.AUTHORISED.valueOf(), - }; - - for (const com of programme.companyId) { - console.log( - "Credit issue", - com, - companyCreditBalances[String(com)], - companyCreditDistribution[String(com)] - ); - if (companyCreditBalances[String(com)] != undefined) { - updateMap[this.ledger.companyTableName + "#" + com] = { - credit: this.round2Precision( - companyCreditBalances[String(com)] + - companyCreditDistribution[String(com)] - ), - txRef: programme.serialNo, - txType: TxType.ISSUE, - }; - updateWhereMap[this.ledger.companyTableName + "#" + com] = { - txId: String(com), - }; - } - } - return [updateMap, updateWhereMap, {}]; - } - ); - - const affected = resp[this.ledger.tableName]; - if (affected && affected.length > 0) { - return updatedProgramme; - } - return updatedProgramme; - } - - public async freezeIssuedCredit( - programmeId: string, - issueAmount: number, - txRef: string, - suspendedCompanies?: Company[] - ) { - const getQueries = {}; - getQueries[this.ledger.tableName] = { - programmeId: programmeId, - }; - - let updatedProgramme = undefined; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - let programme: Programme = programmes[0]; - - if (!programme.creditFrozen) { - programme.creditFrozen = new Array( - programme.creditOwnerPercentage.length - ).fill(0); - } - - let updateMap = {}; - let updateWhereMap = {}; - - suspendedCompanies.forEach(async (company) => { - const index = programme.companyId.indexOf(company.companyId); - const freezeCredit = - (issueAmount * programme.creditOwnerPercentage[index]) / 100; - programme.creditFrozen[index] += freezeCredit; - programme.creditChange = freezeCredit; - - (programme.txTime = new Date().getTime()), - (programme.txRef = `${txRef}##${company.name}`), - (programme.txType = TxType.FREEZE); - - updatedProgramme = programme; - - updateMap[this.ledger.tableName + "#" + company.companyId] = { - creditFrozen: programme.creditFrozen, - creditChange: programme.creditChange, - txRef: programme.txRef, - txTime: programme.txTime, - txType: programme.txType, - }; - updateWhereMap[this.ledger.tableName + "#" + company.companyId] = { - programmeId: programmeId, - }; - }); - - return [updateMap, updateWhereMap, {}]; - } - ); - - return updatedProgramme; - } - - public async addDocument( - externalId: string, - actionId: string, - documentUrl: string, - type: string, - creditEst: number, - certifierId: number - ) { - const getQueries = {}; - getQueries[this.ledger.tableName] = { - externalId: externalId, - }; - - let updatedProgramme = undefined; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - let programme: Programme = programmes[0]; - - let updateMap = {}; - let updateWhereMap = {}; - programme.txTime = new Date().getTime(); - programme.txType = TxType.ADD_DOCUMENT; - programme.txRef = CompanyRole.API; - - updateMap[this.ledger.tableName] = { - txRef: programme.txRef, - txTime: programme.txTime, - txType: programme.txType, - }; - - if (certifierId) { - const index = programme.certifierId - ? programme.certifierId.indexOf(certifierId) - : -1; - - if (index < 0) { - if (!programme.certifierId) { - programme.certifierId = [certifierId]; - } else { - programme.certifierId.push(certifierId); - } - - updateMap[this.ledger.tableName]['certifierId'] = programme.certifierId; - const reIndex = programme.revokedCertifierId - ? programme.revokedCertifierId.indexOf(certifierId) - : -1; - if (reIndex >= 0) { - programme.revokedCertifierId.splice(reIndex, 1); - updateMap[this.ledger.tableName]['revokedCertifierId'] = programme.revokedCertifierId; - } - } - } - - if (actionId) { - const actionIndex = programme.mitigationActions?.findIndex( - (e) => e.actionId == actionId - ); - console.log( - "Add document", - programme.mitigationActions, - actionId, - actionIndex - ); - if (!programme.mitigationActions || actionIndex < 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.noMitigationActionFound", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (!programme.mitigationActions[actionIndex].projectMaterial) { - programme.mitigationActions[actionIndex].projectMaterial = []; - } - - programme.mitigationActions[actionIndex].projectMaterial.push( - documentUrl - ); - - console.log( - "Addition mitigation", - actionId, - programme.mitigationActions - ); - - updateMap[this.ledger.tableName]["mitigationActions"] = - programme.mitigationActions; - } else { - if (!programme.programmeProperties.programmeMaterials) { - programme.programmeProperties.programmeMaterials = []; - } - programme.programmeProperties.programmeMaterials.push(documentUrl); - updateMap[this.ledger.tableName]["programmeProperties"] = - programme.programmeProperties; - } - - if (creditEst > 0) { - programme.currentStage = ProgrammeStage.AWAITING_AUTHORIZATION; - programme.creditEst = creditEst; - updateMap[this.ledger.tableName]["currentStage"] = - programme.currentStage; - updateMap[this.ledger.tableName]["creditEst"] = programme.creditEst; - } - - updatedProgramme = programme; - updateWhereMap[this.ledger.tableName] = { - programmeId: programme.programmeId, - }; - - return [updateMap, updateWhereMap, {}]; - } - ); - - return updatedProgramme; - } - - public async addMitigation( - externalId: string, - mitigation: MitigationProperties - ) { - const getQueries = {}; - getQueries[this.ledger.tableName] = { - externalId: externalId, - }; - - let updatedProgramme = undefined; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let programme: Programme = programmes[0]; - - const actionIndex = programme.mitigationActions?.findIndex( - (e) => e.actionId == mitigation.actionId - ); - if (programme.mitigationActions && actionIndex >= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.mitigationActionAlreadyExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let updateMap = {}; - let updateWhereMap = {}; - programme.txTime = new Date().getTime(); - programme.txType = TxType.ADD_MITIGATION; - programme.txRef = CompanyRole.API; - - if (!programme.mitigationActions) { - programme.mitigationActions = []; - } - - programme.mitigationActions.push(mitigation); - updateMap[this.ledger.tableName] = { - txRef: programme.txRef, - txTime: programme.txTime, - txType: programme.txType, - mitigationActions: programme.mitigationActions, - }; - - updatedProgramme = programme; - updateWhereMap[this.ledger.tableName] = { - programmeId: programme.programmeId, - }; - - return [updateMap, updateWhereMap, {}]; - } - ); - - return updatedProgramme; - } - - public async updateOwnership( - externalId: string, - companyIds: number[], - taxIds: string[], - percentages: number[], - investor: number, - owner: number, - investorName: string, - ownerName: string, - shareFromOwner: number - ) { - const getQueries = {}; - getQueries[this.ledger.tableName] = { - externalId: externalId, - }; - - let updatedProgramme = undefined; - const resp = await this.ledger.getAndUpdateTx( - getQueries, - (results: Record) => { - const programmes: Programme[] = results[this.ledger.tableName].map( - (domValue) => { - return plainToClass( - Programme, - JSON.parse(JSON.stringify(domValue)) - ); - } - ); - - if (programmes.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let programme: Programme = programmes[0]; - - let updateMap = {}; - let updateWhereMap = {}; - - const creditOwnership = {} - // const updatedCreditOwnership = {} - let ownershipPercentage = {} - let ownershipPercentageList = [] - - const ownerIndex = programme.companyId.map(e => Number(e)).indexOf(owner); - if (ownerIndex < 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.noOwnershipPercForCompany", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let investmentPerc = undefined - if (programme.creditBalance && Number(programme.creditBalance) != 0) { - const ownerCreditAmount = programme.creditBalance * programme.creditOwnerPercentage[ownerIndex] / 100; - for (const j in programme.companyId) { - // updatedCreditOwnership[companyIds[j]] - if (Number(companyIds[j]) === owner) { - const investorCredit = (ownerCreditAmount * shareFromOwner / 100); - if (!ownershipPercentage[investor]) { - ownershipPercentage[investor] = 0 - } - ownershipPercentage[investor] += parseFloat((investorCredit * 100 / programme.creditBalance).toFixed(6)) - ownershipPercentage[owner] = parseFloat(((ownerCreditAmount - investorCredit) * 100 / programme.creditBalance).toFixed(6)) - } else { - if (ownershipPercentage[companyIds[j]]) { - ownershipPercentage[companyIds[j]] += programme.creditOwnerPercentage[j] - } else { - ownershipPercentage[companyIds[j]] = programme.creditOwnerPercentage[j] - } - } - } - for (const x in companyIds) { - ownershipPercentageList.push(ownershipPercentage[companyIds[x]]) - if (Number(companyIds[x]) === investor) { - investmentPerc = percentages[x] - } - } - - } else { - ownershipPercentageList = percentages - for (const x in companyIds) { - if (Number(companyIds[x]) === investor) { - investmentPerc = percentages[x] - } - } - } - programme.txTime = new Date().getTime() - programme.txType = TxType.OWNERSHIP_UPDATE - programme.txRef = `${investor}#${investorName}#${owner}#${ownerName}#${investmentPerc}` - programme.proponentTaxVatId = taxIds; - programme.proponentPercentage = percentages; - programme.companyId = companyIds; - programme.creditOwnerPercentage = ownershipPercentageList; - - if(!programme.creditFrozen){ - programme.creditFrozen =new Array( - programme.creditOwnerPercentage.length - ).fill(0); - } - const investorIndex = programme.companyId.indexOf(investor); - if(!programme.creditFrozen[investorIndex]){ - programme.creditFrozen[investorIndex] = 0; - } - - updateMap[this.ledger.tableName] = { - txRef: programme.txRef, - txTime: programme.txTime, - txType: programme.txType, - proponentTaxVatId: programme.proponentTaxVatId, - proponentPercentage: programme.proponentPercentage, - companyId: programme.companyId, - creditOwnerPercentage: programme.creditOwnerPercentage, - creditFrozen: programme.creditFrozen - }; - - updatedProgramme = programme; - updateWhereMap[this.ledger.tableName] = { - programmeId: programme.programmeId, - }; - - return [updateMap, updateWhereMap, {}]; - } - ); - - return updatedProgramme; - } -} diff --git a/backend/services/src/shared/programme/programme.module.ts b/backend/services/src/shared/programme/programme.module.ts deleted file mode 100644 index 11800567d..000000000 --- a/backend/services/src/shared/programme/programme.module.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Logger, Module } from '@nestjs/common'; -import { ProgrammeService } from './programme.service'; -import { ProgrammeLedgerModule } from '../programme-ledger/programme-ledger.module'; -import { CaslModule } from '../casl/casl.module'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { Programme } from '../entities/programme.entity'; -import { UtilModule } from '../util/util.module'; -import { ConstantEntity } from '../entities/constants.entity'; -import { CompanyModule } from '../company/company.module'; -import { ProgrammeTransfer } from '../entities/programme.transfer'; -import { Company } from '../entities/company.entity'; -import { ProgrammeQueryEntity } from '../entities/programme.view.entity'; -import { ProgrammeTransferViewEntityQuery } from '../entities/programmeTransfer.view.entity'; -import { UserModule } from '../user/user.module'; -import { EmailHelperModule } from '../email-helper/email-helper.module'; -import { LocationModule } from '../location/location.module'; -import { AsyncOperationsModule } from '../async-operations/async-operations.module'; - -@Module({ - imports: [ - ProgrammeLedgerModule, - CaslModule, - TypeOrmModule.forFeature([Programme, ProgrammeTransfer, ConstantEntity, Company, ProgrammeQueryEntity, ProgrammeTransferViewEntityQuery]), - UtilModule, - CompanyModule, - UserModule, - EmailHelperModule, - LocationModule, - AsyncOperationsModule - ], - providers: [Logger, ProgrammeService], - exports: [ProgrammeService] -}) -export class ProgrammeModule {} - diff --git a/backend/services/src/shared/programme/programme.service.spec.ts b/backend/services/src/shared/programme/programme.service.spec.ts deleted file mode 100644 index e906f7895..000000000 --- a/backend/services/src/shared/programme/programme.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ProgrammeService } from './programme.service'; - -describe('ProgrammeService', () => { - let service: ProgrammeService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ProgrammeService], - }).compile(); - - service = module.get(ProgrammeService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/programme/programme.service.ts b/backend/services/src/shared/programme/programme.service.ts deleted file mode 100644 index c9f6e35de..000000000 --- a/backend/services/src/shared/programme/programme.service.ts +++ /dev/null @@ -1,2453 +0,0 @@ -import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; -import { ProgrammeDto } from "../dto/programme.dto"; -import { Programme } from "../entities/programme.entity"; -import { ProgrammeLedgerService } from "../programme-ledger/programme-ledger.service"; -import { instanceToPlain, plainToClass } from "class-transformer"; -import { ProgrammeStage } from "../enum/programme-status.enum"; -import { - AgricultureConstants, - AgricultureCreationRequest, - calculateCredit, - SolarConstants, - SolarCreationRequest, -} from "@undp/carbon-credit-calculator"; -import { QueryDto } from "../dto/query.dto"; -import { InjectRepository } from "@nestjs/typeorm"; -import { In, Repository } from "typeorm"; -import { PrimaryGeneratedColumnType } from "typeorm/driver/types/ColumnTypes"; -import { CounterService } from "../util/counter.service"; -import { CounterType } from "../util/counter.type.enum"; -import { ConstantEntity } from "../entities/constants.entity"; -import { DataResponseDto } from "../dto/data.response.dto"; -import { ConstantUpdateDto } from "../dto/constants.update.dto"; -import { ProgrammeApprove } from "../dto/programme.approve"; -import { DataListResponseDto } from "../dto/data.list.response"; -import { BasicResponseDto } from "../dto/basic.response.dto"; -import { ConfigService } from "@nestjs/config"; -import { TypeOfMitigation } from "../enum/typeofmitigation.enum"; -import { CompanyService } from "../company/company.service"; -import { ProgrammeTransferRequest } from "../dto/programme.transfer.request"; -import { EmailTemplates } from "../email-helper/email.template"; -import { User } from "../entities/user.entity"; -import { ProgrammeTransfer } from "../entities/programme.transfer"; -import { TransferStatus } from "../enum/transform.status.enum"; -import { ProgrammeTransferApprove } from "../dto/programme.transfer.approve"; -import { ProgrammeTransferReject } from "../dto/programme.transfer.reject"; -import { Company } from "../entities/company.entity"; -import { HelperService } from "../util/helpers.service"; -import { CompanyRole } from "../enum/company.role.enum"; -import { ProgrammeCertify } from "../dto/programme.certify"; -import { ProgrammeQueryEntity } from "../entities/programme.view.entity"; -import { ProgrammeTransferViewEntityQuery } from "../entities/programmeTransfer.view.entity"; -import { ProgrammeRetire } from "../dto/programme.retire"; -import { ProgrammeTransferCancel } from "../dto/programme.transfer.cancel"; -import { CompanyState } from "../enum/company.state.enum"; -import { ProgrammeReject } from "../dto/programme.reject"; -import { ProgrammeIssue } from "../dto/programme.issue"; -import { RetireType } from "../enum/retire.type.enum"; -import { EmailHelperService } from "../email-helper/email-helper.service"; -import { UserService } from "../user/user.service"; -import { use } from "passport"; -import { SystemActionType } from "../enum/system.action.type"; -import { CountryService } from "../util/country.service"; -import { DataResponseMessageDto } from "../dto/data.response.message"; -import { LocationInterface } from "../location/location.interface"; -import { ProgrammeDocumentDto } from "../dto/programme.document.dto"; -import { MitigationProperties } from "../dto/mitigation.properties"; -import { OwnershipUpdateDto } from "../dto/ownership.update"; -import { MitigationAddDto } from "../dto/mitigation.add.dto"; -import { AsyncAction, AsyncOperationsInterface } from "../async-operations/async-operations.interface"; -import { AsyncActionType } from "../enum/async.action.type.enum"; -import { ProgrammeAcceptedDto } from "../dto/programme.accepted.dto"; - -export declare function PrimaryGeneratedColumn( - options: PrimaryGeneratedColumnType -): Function; - -@Injectable() -export class ProgrammeService { - private userNameCache: any = {}; - - constructor( - private programmeLedger: ProgrammeLedgerService, - private counterService: CounterService, - private configService: ConfigService, - private companyService: CompanyService, - private userService: UserService, - private locationService: LocationInterface, - private helperService: HelperService, - private emailHelperService: EmailHelperService, - private readonly countryService: CountryService, - @InjectRepository(Programme) private programmeRepo: Repository, - @InjectRepository(ProgrammeQueryEntity) - private programmeViewRepo: Repository, - @InjectRepository(ProgrammeTransferViewEntityQuery) - private programmeTransferViewRepo: Repository, - @InjectRepository(Company) private companyRepo: Repository, - @InjectRepository(ProgrammeTransfer) - private programmeTransferRepo: Repository, - @InjectRepository(ConstantEntity) - private constantRepo: Repository, - private logger: Logger, - private asyncOperationsInterface: AsyncOperationsInterface - ) {} - - private toProgramme(programmeDto: ProgrammeDto): Programme { - const data = instanceToPlain(programmeDto); - this.logger.verbose("Converted programme", JSON.stringify(data)); - return plainToClass(Programme, data); - } - - // private async getCreditRequest( - // programmeDto: ProgrammeDto, - // constants: ConstantEntity - // ) { - // switch (programmeDto.typeOfMitigation) { - // case TypeOfMitigation.AGRICULTURE: - // const ar = new AgricultureCreationRequest(); - // ar.duration = programmeDto.endTime - programmeDto.startTime; - // ar.durationUnit = "s"; - // ar.landArea = programmeDto.agricultureProperties.landArea; - // ar.landAreaUnit = programmeDto.agricultureProperties.landAreaUnit; - // if (constants) { - // ar.agricultureConstants = constants.data as AgricultureConstants; - // } - // return ar; - // case TypeOfMitigation.SOLAR: - // const sr = new SolarCreationRequest(); - // sr.buildingType = programmeDto.solarProperties.consumerGroup; - // sr.energyGeneration = programmeDto.solarProperties.energyGeneration; - // sr.energyGenerationUnit = - // programmeDto.solarProperties.energyGenerationUnit; - // if (constants) { - // sr.solarConstants = constants.data as SolarConstants; - // } - // return sr; - // } - // throw Error( - // this.helperService.formatReqMessagesString( - // "programme.notImplementedForMitigationType", - // [programmeDto.typeOfMitigation] - // ) - // ); - // } - - async findById(id: any): Promise { - return await this.programmeRepo.findOneBy({ - programmeId: id, - }); - } - - async findPermissionForMinistryUser( - user: User, - programmeSectoralScope: any - ): Promise { - const orgDetails = await this.companyService.findByCompanyId( - user.companyId - ); - if (!orgDetails?.sectoralScope.includes(programmeSectoralScope as any)) { - return false; - } else return true; - } - - async transferReject(req: ProgrammeTransferReject, approver: User) { - this.logger.log( - `Programme reject ${JSON.stringify(req)} ${approver.companyId}` - ); - - const pTransfer = await this.programmeTransferRepo.findOneBy({ - requestId: req.requestId, - }); - - if (!pTransfer) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.transferReqNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const programmeDetails = await this.findById(pTransfer.programmeId); - if (programmeDetails) { - if (approver.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - approver, - programmeDetails.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - } - - if (pTransfer.status == TransferStatus.CANCELLED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.acceptOrRejAlreadyCancelled", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - !pTransfer.isRetirement && - pTransfer.fromCompanyId != approver.companyId - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.invalidApproverForTransferReq", - [] - ), - HttpStatus.FORBIDDEN - ); - } - if (pTransfer.isRetirement && pTransfer.toCompanyId != approver.companyId) { - if(approver.companyRole !== CompanyRole.MINISTRY) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.invalidApproverForRetirementReq", - [] - ), - HttpStatus.FORBIDDEN - ); - } - } - - const result = await this.programmeTransferRepo - .update( - { - requestId: req.requestId, - status: TransferStatus.PENDING, - }, - { - status: pTransfer.isRetirement - ? TransferStatus.NOTRECOGNISED - : TransferStatus.REJECTED, - txTime: new Date().getTime(), - txRef: `${req.comment}#${approver.companyId}#${approver.id}`, - } - ) - .catch((err) => { - this.logger.error(err); - return err; - }); - - const initiatorCompanyDetails = await this.companyService.findByCompanyId( - pTransfer.initiatorCompanyId - ); - - if (result.affected > 0) { - if (pTransfer.isRetirement && pTransfer.toCompanyMeta) { - const countryName = await this.countryService.getCountryName( - pTransfer.toCompanyMeta.country - ); - await this.emailHelperService.sendEmailToOrganisationAdmins( - pTransfer.fromCompanyId, - EmailTemplates.CREDIT_RETIREMENT_NOT_RECOGNITION, - { - credits: pTransfer.creditAmount, - country: countryName, - }, - 0, - pTransfer.programmeId - ); - } else if ( - initiatorCompanyDetails.companyRole === CompanyRole.GOVERNMENT - ) { - await this.emailHelperService.sendEmailToGovernmentAdmins( - EmailTemplates.CREDIT_TRANSFER_GOV_REJECTED, - { credits: pTransfer.creditAmount }, - pTransfer.programmeId, - pTransfer.fromCompanyId - ); - } else { - await this.emailHelperService.sendEmailToOrganisationAdmins( - pTransfer.initiatorCompanyId, - EmailTemplates.CREDIT_TRANSFER_REJECTED, - { credits: pTransfer.creditAmount }, - pTransfer.fromCompanyId, - pTransfer.programmeId - ); - } - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString( - "programme.transferReqRejectSuccess", - [] - ) - ); - } - - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.noPendReqFound", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - async getTransferByProgrammeId( - programmeId: string, - abilityCondition: string, - user: User - ): Promise { - const query: QueryDto = { - page: 1, - size: 30, - filterAnd: [ - { - key: "programmeId", - operation: "=", - value: String(programmeId), - }, - ], - filterOr: undefined, - sort: undefined, - filterBy: undefined - }; - - const resp = await this.programmeTransferViewRepo - .createQueryBuilder("programme_transfer") - .where( - this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQLWithTable( - "programme_transfer", - abilityCondition - ) - ) - ) - .orderBy( - query?.sort?.key && - this.helperService.generateSortCol(query?.sort?.key), - query?.sort?.order - ) - .offset(query.size * query.page - query.size) - .limit(query.size) - .getManyAndCount(); - - if (resp && resp.length > 0) { - for (const e of resp[0]) { - console.log(e); - e.certifier = - e.certifier.length > 0 && e.certifier[0] === null ? [] : e.certifier; - if ( - e.isRetirement && - e.retirementType == RetireType.CROSS_BORDER && - e.toCompanyMeta.country - ) { - e.toCompanyMeta["countryName"] = - await this.countryService.getCountryName(e.toCompanyMeta.country); - } - - let usrId = undefined; - let userCompany = undefined; - if (e["txRef"] != undefined && e["txRef"] != null) { - const parts = e["txRef"]?.split("#"); - if (parts.length > 2) { - usrId = parts[2]; - userCompany = parts[1]; - } - } else { - usrId = e["initiator"]; - userCompany = e["initiatorCompanyId"]; - } - - if ( - user.companyRole === CompanyRole.GOVERNMENT || - Number(userCompany) === Number(user.companyId) - ) { - e["userName"] = await this.getUserName(usrId); - } - } - } - return new DataListResponseDto( - resp.length > 0 ? resp[0] : undefined, - resp.length > 1 ? resp[1] : undefined - ); - } - - async queryProgrammeTransfers( - query: QueryDto, - abilityCondition: string, - user: User - ): Promise { - let queryBuilder = await this.programmeTransferViewRepo - .createQueryBuilder("programme_transfer") - .where( - this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQLWithTable( - "programme_transfer", - abilityCondition - ) - ) - ); - - if (query.filterBy !== null && query.filterBy !== undefined && query.filterBy.key === 'ministryLevel') { - queryBuilder = queryBuilder.andWhere("programme_transfer.programmeSectoralScope IN (:...allowedScopes)", { - allowedScopes: query.filterBy.value - }); - } - const resp = await queryBuilder.orderBy( - query?.sort?.key && - this.helperService.generateSortCol(query?.sort?.key), - query?.sort?.order, - query?.sort?.nullFirst !== undefined - ? query?.sort?.nullFirst === true - ? "NULLS FIRST" - : "NULLS LAST" - : undefined - ) - .offset(query.size * query.page - query.size) - .limit(query.size) - .getManyAndCount(); - - if (resp && resp.length > 0) { - for (const e of resp[0]) { - e.certifier = - e.certifier.length > 0 && e.certifier[0] === null ? [] : e.certifier; - - if (e.toCompanyMeta && e.toCompanyMeta.country) { - e.toCompanyMeta["countryName"] = - await this.countryService.getCountryName(e.toCompanyMeta.country); - } - } - } - return new DataListResponseDto( - resp.length > 0 ? resp[0] : undefined, - resp.length > 1 ? resp[1] : undefined - ); - } - - async transferApprove(req: ProgrammeTransferApprove, approver: User) { - // TODO: Handle transaction, can happen - console.log("Approver", approver); - const transfer = await this.programmeTransferRepo.findOneBy({ - requestId: req.requestId, - }); - - if (!transfer) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.transferReqNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - const programmeD = await this.findById(transfer.programmeId); - if (programmeD) { - if (approver.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - approver, - programmeD.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - } - - if (transfer.status == TransferStatus.CANCELLED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.acceptOrRejAlreadyCancelled", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - transfer.status == TransferStatus.APPROVED || - transfer.status == TransferStatus.RECOGNISED - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.transferAlreadyApproved", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - !transfer.isRetirement && - transfer.fromCompanyId != approver.companyId - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.invalidApproverForTransferReq", - [] - ), - HttpStatus.FORBIDDEN - ); - } - if (transfer.isRetirement && transfer.toCompanyId != approver.companyId) { - if(approver.companyRole !== CompanyRole.MINISTRY) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.invalidApproverForRetirementReq", - [] - ), - HttpStatus.FORBIDDEN - ); - } - } - - const receiver = await this.companyService.findByCompanyId( - transfer.toCompanyId - ); - const giver = await this.companyService.findByCompanyId( - transfer.fromCompanyId - ); - - if (receiver.state === CompanyState.SUSPENDED) { - await this.companyService.companyTransferCancel( - transfer.toCompanyId, - `${transfer.comment}#${approver.companyId}#${approver.id}#${SystemActionType.SUSPEND_AUTO_CANCEL}#${receiver.name}` - ); - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.receiveCompanySuspended", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (giver.state === CompanyState.SUSPENDED) { - await this.companyService.companyTransferCancel( - transfer.fromCompanyId, - `${transfer.comment}#${approver.companyId}#${approver.id}#${SystemActionType.SUSPEND_AUTO_CANCEL}#${receiver.name}` - ); - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.cerditSendingCompSuspended", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (transfer.status != TransferStatus.PROCESSING) { - const trq = await this.programmeTransferRepo - .update( - { - requestId: req.requestId, - status: TransferStatus.PENDING, - }, - { - status: TransferStatus.PROCESSING, - txTime: new Date().getTime(), - } - ) - .catch((err) => { - this.logger.error(err); - return err; - }); - - if (trq.affected <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.noPendingTransferReq", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - } - - const initiatorCompanyDetails = await this.companyService.findByCompanyId( - transfer.initiatorCompanyId - ); - - const transferResult = await this.doTransfer( - transfer, - `${this.getUserRef(approver)}#${receiver.companyId}#${receiver.name}#${ - giver.companyId - }#${giver.name}`, - req.comment, - transfer.isRetirement - ); - - if (transferResult.statusCode === 200) { - if (transfer.isRetirement && transfer.toCompanyMeta) { - const countryName = await this.countryService.getCountryName( - transfer.toCompanyMeta.country - ); - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_RETIREMENT_RECOGNITION, - { - credits: transfer.creditAmount, - country: countryName, - }, - 0, - transfer.programmeId - ); - } else if ( - initiatorCompanyDetails.companyRole === CompanyRole.GOVERNMENT - ) { - await this.emailHelperService.sendEmailToGovernmentAdmins( - EmailTemplates.CREDIT_TRANSFER_GOV_ACCEPTED_TO_INITIATOR, - { credits: transfer.creditAmount }, - transfer.programmeId, - approver.companyId - ); - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.toCompanyId, - EmailTemplates.CREDIT_TRANSFER_GOV_ACCEPTED_TO_RECEIVER, - { - credits: transfer.creditAmount, - government: initiatorCompanyDetails.name, - }, - transfer.fromCompanyId, - transfer.programmeId - ); - } else { - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.toCompanyId, - EmailTemplates.CREDIT_TRANSFER_ACCEPTED, - { credits: transfer.creditAmount }, - approver.companyId, - transfer.programmeId - ); - } - } - - return transferResult; - } - - private async doTransfer( - transfer: ProgrammeTransfer, - user: string, - reason: string, - isRetirement: boolean - ) { - const hostAddress = this.configService.get("host"); - const programme = await this.programmeLedger.transferProgramme( - transfer, - user, - reason, - isRetirement - ); - - this.logger.log("Programme updated"); - const result = await this.programmeTransferRepo - .update( - { - requestId: transfer.requestId, - }, - { - status: transfer.isRetirement - ? TransferStatus.RECOGNISED - : TransferStatus.APPROVED, - txTime: new Date().getTime(), - authTime: new Date().getTime(), - } - ) - .catch((err) => { - this.logger.error(err); - return err; - }); - - if (result.affected > 0) { - this.checkPendingTransferValidity(programme); - return new DataResponseDto(HttpStatus.OK, programme); - } - - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.internalErrorStatusUpdating", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - async transferCancel(req: ProgrammeTransferCancel, requester: User) { - this.logger.log( - `Programme transfer cancel by ${requester.companyId}-${ - requester.id - } received ${JSON.stringify(req)}` - ); - - const transfer = await this.programmeTransferRepo.findOneBy({ - requestId: req.requestId, - }); - - if (!transfer) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.transferReqNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const programmeDetails = await this.findById(transfer.programmeId); - if (programmeDetails) { - if (requester.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - requester, - programmeDetails.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - } - - if (transfer.status != TransferStatus.PENDING) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.acceptOrRejCancelledReq", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const result = await this.programmeTransferRepo - .update( - { - requestId: req.requestId, - status: TransferStatus.PENDING, - }, - { - status: TransferStatus.CANCELLED, - txTime: new Date().getTime(), - txRef: `${req.comment}#${requester.companyId}#${requester.id}`, - } - ) - .catch((err) => { - this.logger.error(err); - return err; - }); - - if (result.affected > 0) { - const initiatorCompanyDetails = await this.companyService.findByCompanyId( - transfer.initiatorCompanyId - ); - if (transfer.isRetirement && transfer.toCompanyMeta) { - const countryName = await this.countryService.getCountryName( - transfer.toCompanyMeta.country - ); - await this.emailHelperService.sendEmailToGovernmentAdmins( - EmailTemplates.CREDIT_RETIREMENT_CANCEL, - { - credits: transfer.creditAmount, - organisationName: initiatorCompanyDetails.name, - country: countryName, - }, - transfer.programmeId - ); - } else if ( - initiatorCompanyDetails.companyRole === CompanyRole.GOVERNMENT - ) { - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_TRANSFER_GOV_CANCELLATION, - { - credits: transfer.creditAmount, - government: initiatorCompanyDetails.name, - }, - transfer.toCompanyId, - transfer.programmeId - ); - } else { - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_TRANSFER_CANCELLATION, - { credits: transfer.creditAmount }, - transfer.initiatorCompanyId, - transfer.programmeId - ); - } - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString( - "programme.transferCancelSuccess", - [] - ) - ); - } - return new BasicResponseDto( - HttpStatus.BAD_REQUEST, - this.helperService.formatReqMessagesString( - "programme.transferReqNotExistinGiv", - [] - ) - ); - } - - async transferRequest(req: ProgrammeTransferRequest, requester: User) { - this.logger.log( - `Programme transfer request by ${requester.companyId}-${ - requester.id - } received ${JSON.stringify(req)}` - ); - - // TODO: Move this to casl factory - // if (requester.role == Role.ViewOnly) { - // throw new HttpException("View only user cannot create requests", HttpStatus.FORBIDDEN) - // } - - // if (![CompanyRole.GOVERNMENT, CompanyRole.PROGRAMME_DEVELOPER].includes(requester.companyRole)) { - // throw new HttpException("Unsupported company role", HttpStatus.FORBIDDEN) - // } - - if ( - req.companyCredit && - req.companyCredit.reduce((a, b) => a + b, 0) <= 0 - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.companytotalAmount>0", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (req.fromCompanyIds.length > 1) { - if (!req.companyCredit) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.companyCreditNeedsToDefineForMultipleComp", - [] - ), - HttpStatus.BAD_REQUEST - ); - } else if (req.fromCompanyIds.length != req.companyCredit.length) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.invalidCompCreditForGivenComp", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - } - - if ( - req.fromCompanyIds && - req.companyCredit && - req.fromCompanyIds.length != req.companyCredit.length - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.invalidCompCreditFromGivenComp", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const indexTo = req.fromCompanyIds.indexOf(req.toCompanyId); - if (indexTo >= 0 && req.companyCredit[indexTo] > 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.cantTransferCreditWithinSameComp", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const programme = await this.programmeLedger.getProgrammeById( - req.programmeId - ); - - if (!programme) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (requester.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - requester, - programme.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - this.logger.verbose(`Transfer programme ${JSON.stringify(programme)}`); - - if (programme.currentStage != ProgrammeStage.AUTHORISED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotInCreditIssuedState", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - // if (programme.creditBalance - (programme.creditFrozen ? programme.creditFrozen.reduce((a, b) => a + b, 0) : 0) < req.creditAmount) { - // throw new HttpException("Not enough balance for the transfer", HttpStatus.BAD_REQUEST) - // } - if ( - requester.companyRole != CompanyRole.GOVERNMENT && requester.companyRole != CompanyRole.MINISTRY && - ![...req.fromCompanyIds, req.toCompanyId].includes(requester.companyId) - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.cantInitiateTransferForOtherComp", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (!req.fromCompanyIds) { - req.fromCompanyIds = programme.companyId; - } - if (!programme.creditOwnerPercentage) { - programme.creditOwnerPercentage = [100]; - } - if (!req.companyCredit) { - req.companyCredit = programme.creditOwnerPercentage.map( - (p, i) => - (programme.creditBalance * p) / 100 - - (programme.creditFrozen ? programme.creditFrozen[i] : 0) - ); - } - - const requestedCompany = await this.companyService.findByCompanyId( - requester.companyId - ); - - const allTransferList: ProgrammeTransfer[] = []; - const autoApproveTransferList: ProgrammeTransfer[] = []; - const ownershipMap = {}; - const frozenCredit = {}; - - for (const i in programme.companyId) { - ownershipMap[programme.companyId[i]] = programme.creditOwnerPercentage[i]; - if (programme.creditFrozen) { - frozenCredit[programme.companyId[i]] = programme.creditFrozen[i]; - } - } - - const hostAddress = this.configService.get("host"); - - const fromCompanyListMap = {}; - for (const j in req.fromCompanyIds) { - const fromCompanyId = req.fromCompanyIds[j]; - this.logger.log( - `Transfer request from ${fromCompanyId} to programme owned by ${programme.companyId}` - ); - const fromCompany = await this.companyService.findByCompanyId( - fromCompanyId - ); - fromCompanyListMap[fromCompanyId] = fromCompany; - - if (!programme.companyId.includes(fromCompanyId)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.fromCompInReqIsNotOwnerOfProgramme", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - console.log( - programme.creditBalance, - ownershipMap[fromCompanyId], - frozenCredit[fromCompanyId] - ); - const companyAvailableCredit = - (programme.creditBalance * ownershipMap[fromCompanyId]) / 100 - - (frozenCredit[fromCompanyId] ? frozenCredit[fromCompanyId] : 0); - - let transferCompanyCredit; - if (req.fromCompanyIds.length == 1 && !req.companyCredit) { - transferCompanyCredit = companyAvailableCredit; - } else { - transferCompanyCredit = req.companyCredit[j]; - } - - if (companyAvailableCredit < transferCompanyCredit) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.companyHaveNoEnoughBalanceForTransfer", - [fromCompany.name, companyAvailableCredit] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (transferCompanyCredit == 0) { - continue; - } - - const transfer = new ProgrammeTransfer(); - transfer.programmeId = req.programmeId; - transfer.fromCompanyId = fromCompanyId; - transfer.toCompanyId = req.toCompanyId; - transfer.initiator = requester.id; - transfer.initiatorCompanyId = requester.companyId; - transfer.txTime = new Date().getTime(); - transfer.createdTime = transfer.txTime; - transfer.comment = req.comment; - transfer.creditAmount = transferCompanyCredit; - transfer.toAccount = req.toAccount; - transfer.isRetirement = false; - - if (requester.companyId != fromCompanyId) { - transfer.status = TransferStatus.PENDING; - } else { - transfer.status = TransferStatus.PROCESSING; - autoApproveTransferList.push(transfer); - } - allTransferList.push(transfer); - } - const results = await this.programmeTransferRepo.insert(allTransferList); - console.log(results); - for (const i in allTransferList) { - allTransferList[i].requestId = results.identifiers[i].requestId; - } - - let updateProgramme = undefined; - for (const trf of autoApproveTransferList) { - this.logger.log(`Credit send received ${trf}`); - const toCompany = await this.companyService.findByCompanyId( - trf.toCompanyId - ); - console.log("To Company", toCompany); - updateProgramme = ( - await this.doTransfer( - trf, - `${this.getUserRef(requester)}#${toCompany.companyId}#${ - toCompany.name - }#${fromCompanyListMap[trf.fromCompanyId].companyId}#${ - fromCompanyListMap[trf.fromCompanyId].name - }`, - req.comment, - false - ) - ).data; - await this.emailHelperService.sendEmailToOrganisationAdmins( - trf.toCompanyId, - EmailTemplates.CREDIT_SEND_DEVELOPER, - { - organisationName: requestedCompany.name, - credits: trf.creditAmount, - programmeName: programme.title, - serialNumber: programme.serialNo, - pageLink: hostAddress + "/creditTransfers/viewAll", - } - ); - } - if (updateProgramme) { - return new DataResponseDto(HttpStatus.OK, updateProgramme); - } - - allTransferList.forEach(async (transfer) => { - if (requester.companyRole === CompanyRole.GOVERNMENT) { - if (transfer.toCompanyId === requester.companyId) { - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_TRANSFER_REQUISITIONS, - { - organisationName: requestedCompany.name, - credits: transfer.creditAmount, - programmeName: programme.title, - serialNumber: programme.serialNo, - pageLink: hostAddress + "/creditTransfers/viewAll", - } - ); - } else { - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_TRANSFER_GOV, - { - credits: transfer.creditAmount, - programmeName: programme.title, - serialNumber: programme.serialNo, - pageLink: hostAddress + "/creditTransfers/viewAll", - government: requestedCompany.name, - }, - transfer.toCompanyId - ); - } - } else if (requester.companyId != transfer.fromCompanyId) { - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_TRANSFER_REQUISITIONS, - { - organisationName: requestedCompany.name, - credits: transfer.creditAmount, - programmeName: programme.title, - serialNumber: programme.serialNo, - pageLink: hostAddress + "/creditTransfers/viewAll", - } - ); - } - }); - - return new DataListResponseDto(allTransferList, allTransferList.length); - } - - async addDocument(document: ProgrammeDocumentDto): Promise { - this.logger.log('Add Document triggered') - - const certifierId = (await this.companyService.findByTaxId(document.certifierTaxId))?.companyId; - const resp = await this.programmeLedger.addDocument(document.externalId, document.actionId, document.data, document.type, 0, certifierId); - return new DataResponseDto(HttpStatus.OK, resp); - } - - async programmeAccept(accept: ProgrammeAcceptedDto): Promise { - this.logger.log('Add accept triggered') - const certifierId = (await this.companyService.findByTaxId(accept.certifierTaxId))?.companyId; - const resp = await this.programmeLedger.addDocument(accept.externalId, undefined, accept.data, accept.type, accept.creditEst, certifierId); - return new DataResponseDto(HttpStatus.OK, resp); - } - - async addMitigation(mitigation: MitigationAddDto): Promise { - this.logger.log('Add mitigation triggered') - const resp = await this.programmeLedger.addMitigation(mitigation.externalId, mitigation.mitigation); - return new DataResponseDto(HttpStatus.OK, resp); - } - - async updateOwnership(update: OwnershipUpdateDto): Promise { - this.logger.log('Ownership update triggered') - - if ( - update.proponentTaxVatId.length != - update.proponentPercentage.length - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentPercAndTaxIdsNotMatched", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - update.proponentPercentage.reduce((a, b) => a + b, 0) != 100 - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentPercSum=100", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const companyIds = []; - - let investorCompanyId; - let ownerCompanyId; - let investorCompanyName; - let ownerCompanyName; - for (const taxId of update.proponentTaxVatId) { - const compo = await this.companyService.findByTaxId(taxId); - if (!compo) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentTaxIdNotInSystem", - [taxId] - ), - HttpStatus.BAD_REQUEST - ); - } - if (compo.taxId === update.investorTaxId) { - investorCompanyId = Number(compo.companyId); - investorCompanyName = compo.name; - } else if (compo.taxId === update.ownerTaxId) { - ownerCompanyId = Number(compo.companyId); - ownerCompanyName = compo.name; - } - companyIds.push(compo.companyId) - } - - const resp = await this.programmeLedger.updateOwnership(update.externalId, companyIds, update.proponentTaxVatId, update.proponentPercentage, investorCompanyId, ownerCompanyId, investorCompanyName, ownerCompanyName, update.shareFromOwner); - if(resp) - this.checkPendingTransferValidity(resp); - return new DataResponseDto(HttpStatus.OK, resp); - } - - async create(programmeDto: ProgrammeDto): Promise { - this.logger.verbose("ProgrammeDTO received", programmeDto); - const programme: Programme = this.toProgramme(programmeDto); - this.logger.verbose("Programme create", programme); - - if ( - programmeDto.proponentTaxVatId.length > 1 && - (!programmeDto.proponentPercentage || - programmeDto.proponentPercentage.length != - programmeDto.proponentTaxVatId.length) - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentPercMustDefinedForEvryProponentTaxId", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - programmeDto.proponentPercentage && - programmeDto.proponentTaxVatId.length != - programmeDto.proponentPercentage.length - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentPercAndTaxIdsNotMatched", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - programmeDto.proponentPercentage && - programmeDto.proponentPercentage.reduce((a, b) => a + b, 0) != 100 - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentPercSum=100", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if ( - programmeDto.proponentTaxVatId.length !== - new Set(programmeDto.proponentTaxVatId).size - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.duplicatedProponentTaxIds", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - const companyIds = []; - const companyNames = []; - for (const taxId of programmeDto.proponentTaxVatId) { - const projectCompany = await this.companyService.findByTaxId(taxId); - if (!projectCompany) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentTaxIdNotInSystem", - [taxId] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (projectCompany.companyRole != CompanyRole.PROGRAMME_DEVELOPER) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.proponentIsNotAProgrammeDev", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - companyIds.push(projectCompany.companyId); - companyNames.push(projectCompany.name); - } - - programme.programmeId = await this.counterService.incrementCount( - CounterType.PROGRAMME, - 3 - ); - programme.countryCodeA2 = this.configService.get("systemCountry"); - - // let constants = undefined; - // if (!programmeDto.creditEst) { - // constants = await this.getLatestConstant(programmeDto.typeOfMitigation); - - // const req = await this.getCreditRequest(programmeDto, constants); - // try { - // programme.creditEst = Math.round(await calculateCredit(req)); - // } catch (err) { - // this.logger.log(`Credit calculate failed ${err.message}`); - // throw new HttpException(err.message, HttpStatus.BAD_REQUEST); - // } - // } - - // if (programme.creditEst <= 0) { - // throw new HttpException( - // this.helperService.formatReqMessagesString( - // "programme.noEnoughCreditsToCreateProgramme", - // [] - // ), - // HttpStatus.BAD_REQUEST - // ); - // } - // programme.creditBalance = programme.creditIssued; - // programme.creditChange = programme.creditIssued; - programme.programmeProperties.creditYear = new Date( - programme.startTime * 1000 - ).getFullYear(); - // programme.constantVersion = constants - // ? String(constants.version) - // : "default"; - programme.currentStage = ProgrammeStage.NEW; - programme.companyId = companyIds; - programme.txTime = new Date().getTime(); - if (programme.proponentPercentage) { - programme.creditOwnerPercentage = programme.proponentPercentage; - } - programme.createdTime = programme.txTime; - if (!programme.creditUnit) { - programme.creditUnit = this.configService.get("defaultCreditUnit"); - } - - let orgNamesList = ""; - if (companyNames.length > 1) { - const lastItem = companyNames.pop(); - orgNamesList = companyNames.join(",") + " and " + lastItem; - } else { - orgNamesList = companyNames[0]; - } - - if (programme.companyId.length === 1 && !programme.proponentPercentage) { - programme.proponentPercentage = [100]; - programme.creditOwnerPercentage = [100]; - } - const savedProgramme = await this.programmeLedger.createProgramme( - programme - ); - if (savedProgramme) { - const hostAddress = this.configService.get("host"); - await this.emailHelperService.sendEmailToGovernmentAdmins( - EmailTemplates.PROGRAMME_CREATE, - { - organisationName: orgNamesList, - programmePageLink: - hostAddress + - `/programmeManagement/view?id=${programme.programmeId}`, - } - ); - } - - return savedProgramme; - } - - async query( - query: QueryDto, - abilityCondition: string - ): Promise { - const skip = query.size * query.page - query.size; - let resp = await this.programmeViewRepo - .createQueryBuilder("programme") - .where( - this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQLWithTable( - "programme", - abilityCondition - ), - "programme" - ) - ) - .orderBy( - query?.sort?.key && - `"programme".${this.helperService.generateSortCol(query?.sort?.key)}`, - query?.sort?.order, - query?.sort?.nullFirst !== undefined - ? query?.sort?.nullFirst === true - ? "NULLS FIRST" - : "NULLS LAST" - : undefined - ) - .offset(skip) - .limit(query.size) - .getManyAndCount(); - - if (resp.length > 0) { - resp[0] = resp[0].map((e) => { - e.certifier = - e.certifier.length > 0 && e.certifier[0] === null ? [] : e.certifier; - e.company = - e.company.length > 0 && e.company[0] === null ? [] : e.company; - return e; - }); - } - - return new DataListResponseDto( - resp.length > 0 ? resp[0] : undefined, - resp.length > 1 ? resp[1] : undefined - ); - } - - async getProgrammeEventsByExternalId(externalId: string): Promise { - return await this.programmeLedger.getProgrammeHistoryByExternalId(externalId); - } - - - async getProgrammeEvents(programmeId: string, user: User): Promise { - const resp = await this.programmeLedger.getProgrammeHistory(programmeId); - if (resp == null) { - return []; - } - for (const el of resp) { - const refs = this.getCompanyIdAndUserIdFromRef(el.data.txRef); - if ( - refs && !isNaN(refs?.companyId) && !isNaN(Number(refs.id)) && - (user.companyRole === CompanyRole.GOVERNMENT || - Number(refs?.companyId) === Number(user.companyId)) - ) { - el.data["userName"] = await this.getUserName(refs.id); - } - } - return resp; - } - - async updateCustomConstants( - customConstantType: TypeOfMitigation, - constants: ConstantUpdateDto - ) { - let config; - if (customConstantType == TypeOfMitigation.AGRICULTURE) { - config = new AgricultureConstants(); - const recv = instanceToPlain(constants.agricultureConstants); - for (const key in recv) { - if (recv.hasOwnProperty(key) && recv[key] != undefined) { - config[key] = recv[key]; - } - } - } else if (customConstantType == TypeOfMitigation.SOLAR) { - config = new SolarConstants(); - const recv = instanceToPlain(constants.solarConstants); - for (const key in recv) { - if (recv.hasOwnProperty(key) && recv[key] != undefined) { - config[key] = recv[key]; - } - } - } - - const existing = await this.getLatestConstant(customConstantType); - if (existing && JSON.stringify(existing.data) == JSON.stringify(config)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.noDiffInConfigFromThePrevVersion", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - const resp = await this.constantRepo.save({ - id: customConstantType, - data: config, - }); - return new DataResponseDto(HttpStatus.OK, resp); - } - - async getLatestConstant(customConstantType: TypeOfMitigation) { - return await this.constantRepo.findOne({ - where: [{ id: customConstantType }], - order: { version: "DESC" }, - }); - } - - async certify(req: ProgrammeCertify, add: boolean, user: User) { - this.logger.log( - `Programme ${req.programmeId} certification received by ${user.id}` - ); - const progDetails = await this.findById(req.programmeId); - - if (add && user.companyRole != CompanyRole.CERTIFIER) { - throw new HttpException( - this.helperService.formatReqMessagesString("programme.unAuth", []), - HttpStatus.FORBIDDEN - ); - } - - if ( - !add && - ![ - CompanyRole.CERTIFIER, - CompanyRole.GOVERNMENT, - CompanyRole.MINISTRY, - ].includes(user.companyRole) - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.certifierOrGovCanOnlyPerformCertificationRevoke", - [] - ), - HttpStatus.FORBIDDEN - ); - } else if(!add && user.companyRole === CompanyRole.MINISTRY) { - if ( progDetails) { - const permission = await this.findPermissionForMinistryUser( - user, - progDetails.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - } - - let certifierId; - if ( - user.companyRole === CompanyRole.GOVERNMENT || - user.companyRole === CompanyRole.MINISTRY - ) { - if (!req.certifierId) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.certifierIdRequiredForGov", - [] - ), - HttpStatus.FORBIDDEN - ); - } - certifierId = req.certifierId; - } else { - certifierId = user.companyId; - } - - const userCompany = await this.companyRepo.findOne({ - where: { companyId: user.companyId }, - }); - if (userCompany && userCompany.state === CompanyState.SUSPENDED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.organisationDeactivated", - [] - ), - HttpStatus.FORBIDDEN - ); - } - - const updated = await this.programmeLedger.updateCertifier( - req.programmeId, - certifierId, - add, - this.getUserRefWithRemarks(user, req.comment) - ); - updated.company = await this.companyRepo.find({ - where: { companyId: In(updated.companyId) }, - }); - if (updated && updated.certifierId && updated.certifierId.length > 0) { - updated.certifier = await this.companyRepo.find({ - where: { companyId: In(updated.certifierId) }, - }); - } - - if (add) { - await this.emailHelperService.sendEmailToProgrammeOwnerAdmins( - req.programmeId, - EmailTemplates.PROGRAMME_CERTIFICATION, - {}, - user.companyId - ); - } else { - if (user.companyRole === CompanyRole.GOVERNMENT || user.companyRole === CompanyRole.MINISTRY) { - await this.emailHelperService.sendEmailToProgrammeOwnerAdmins( - req.programmeId, - EmailTemplates.PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_PROGRAMME, - {}, - req.certifierId, - user.companyId - ); - await this.emailHelperService.sendEmailToOrganisationAdmins( - req.certifierId, - EmailTemplates.PROGRAMME_CERTIFICATION_REVOKE_BY_GOVT_TO_CERT, - {}, - user.companyId, - req.programmeId - ); - } else { - await this.emailHelperService.sendEmailToProgrammeOwnerAdmins( - req.programmeId, - EmailTemplates.PROGRAMME_CERTIFICATION_REVOKE_BY_CERT, - {}, - user.companyId - ); - } - } - - if (add) { - return new DataResponseMessageDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString( - "programme.certifyPendingProgramme", - [] - ), - updated - ); - } else { - return new DataResponseMessageDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString( - "programme.certificationRevocation", - [] - ), - updated - ); - } - } - - async retireProgramme(req: ProgrammeRetire, requester: User) { - this.logger.log( - `Programme ${req.programmeId} retiring Comment: ${req.comment} type: ${req.type}` - ); - - if ( - req.companyCredit && - req.companyCredit.reduce((a, b) => a + b, 0) <= 0 - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.totalAmount>0", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (req.fromCompanyIds && req.fromCompanyIds.length > 1) { - if ( - req.companyCredit && - req.fromCompanyIds.length != req.companyCredit.length - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.invalidCompCreditForGivenComp", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - } - - // if (req.type === RetireType.CROSS_BORDER && !req.toCompanyMeta.country) { - // throw new HttpException("Country is required for cross border retirement", HttpStatus.BAD_REQUEST) - // } - - const programme = await this.programmeLedger.getProgrammeById( - req.programmeId - ); - - if (!programme) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - this.logger.verbose(`Transfer programme ${JSON.stringify(programme)}`); - - if (programme.currentStage != ProgrammeStage.AUTHORISED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotInCreditIssuedState", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (!programme.creditOwnerPercentage) { - programme.creditOwnerPercentage = [100]; - } - const requestedCompany = await this.companyService.findByCompanyId( - requester.companyId - ); - const toCompany = await this.companyService.findGovByCountry( - this.configService.get("systemCountry") - ); - - if (requestedCompany.companyRole != CompanyRole.GOVERNMENT && requestedCompany.companyRole != CompanyRole.MINISTRY) { - if (!req.fromCompanyIds) { - req.fromCompanyIds = [requester.companyId]; - } - - if (!programme.companyId.includes(requester.companyId)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.govOrProgrammeOwnerOnlyCreditRetirement", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (!req.fromCompanyIds.includes(requester.companyId)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.reqNotIncludedInFromCompanyId", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (req.fromCompanyIds.length > 1) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.notAllowedToRetireOtherCompCredits", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (req.type !== RetireType.CROSS_BORDER) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeDevAllowedInitiateOnlyCrossBorderTransfer", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (!req.companyCredit) { - const reqIndex = programme.companyId.indexOf(requester.companyId); - req.companyCredit = [ - (programme.creditBalance * - programme.creditOwnerPercentage[reqIndex]) / - 100 - - (programme.creditFrozen ? programme.creditFrozen[reqIndex] : 0), - ]; - } - } else { - if(requestedCompany.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - requester, - programme.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - if (!req.fromCompanyIds) { - req.fromCompanyIds = programme.companyId; - } - if (!req.companyCredit) { - req.companyCredit = programme.creditOwnerPercentage.map( - (p, i) => - (programme.creditBalance * p) / 100 - - (programme.creditFrozen ? programme.creditFrozen[i] : 0) - ); - } - } - - const allTransferList: ProgrammeTransfer[] = []; - const autoApproveTransferList: ProgrammeTransfer[] = []; - const ownershipMap = {}; - const frozenCredit = {}; - - for (const i in programme.companyId) { - ownershipMap[programme.companyId[i]] = programme.creditOwnerPercentage[i]; - if (programme.creditFrozen) { - frozenCredit[programme.companyId[i]] = programme.creditFrozen[i]; - } - } - - const fromCompanyMap = {}; - for (const j in req.fromCompanyIds) { - const fromCompanyId = req.fromCompanyIds[j]; - this.logger.log( - `Retire request from ${fromCompanyId} to programme owned by ${programme.companyId}` - ); - const fromCompany = await this.companyService.findByCompanyId( - fromCompanyId - ); - fromCompanyMap[fromCompanyId] = fromCompany; - if (!programme.companyId.includes(fromCompanyId)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.retireReqFromCOmpOwnTheProgramme", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - const companyAvailableCredit = - (programme.creditBalance * ownershipMap[fromCompanyId]) / 100 - - (frozenCredit[fromCompanyId] ? frozenCredit[fromCompanyId] : 0); - - let transferCompanyCredit; - if (req.fromCompanyIds.length == 1 && !req.companyCredit) { - transferCompanyCredit = companyAvailableCredit; - } else { - transferCompanyCredit = req.companyCredit[j]; - } - - if ( - req.type != RetireType.CROSS_BORDER && - transferCompanyCredit < companyAvailableCredit - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.requiredToRetireFullCreditAmountForGivenRetirementType", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (companyAvailableCredit < transferCompanyCredit) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.companyHaveNoEnoughBalanceForTransfer", - [fromCompany.name, companyAvailableCredit] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (transferCompanyCredit == 0) { - continue; - } - - const transfer = new ProgrammeTransfer(); - transfer.programmeId = req.programmeId; - transfer.fromCompanyId = fromCompanyId; - transfer.toCompanyId = toCompany.companyId; - transfer.initiator = requester.id; - transfer.initiatorCompanyId = requester.companyId; - transfer.txTime = new Date().getTime(); - transfer.createdTime = transfer.txTime; - transfer.comment = req.comment; - transfer.creditAmount = transferCompanyCredit; - transfer.toAccount = - req.type == RetireType.CROSS_BORDER ? "international" : "local"; - transfer.isRetirement = true; - transfer.toCompanyMeta = req.toCompanyMeta; - transfer.retirementType = req.type; - // await this.programmeTransferRepo.save(transfer); - - const hostAddress = this.configService.get("host"); - if (requester.companyId != toCompany.companyId) { - if(requester.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - requester, - programme.sectoralScope - ); - if(permission) { - transfer.status = TransferStatus.PROCESSING; - autoApproveTransferList.push(transfer); - } - } - else { - transfer.status = TransferStatus.PENDING; - await this.emailHelperService.sendEmailToGovernmentAdmins( - EmailTemplates.CREDIT_RETIREMENT_BY_DEV, - { - credits: transfer.creditAmount, - programmeName: programme.title, - serialNumber: programme.serialNo, - organisationName: fromCompany.name, - pageLink: hostAddress + "/creditTransfers/viewAll", - } - ); - } - } else { - transfer.status = TransferStatus.PROCESSING; - autoApproveTransferList.push(transfer); - const reason = - req.type === RetireType.CROSS_BORDER - ? "cross border transfer" - : transfer.retirementType === RetireType.LEGAL_ACTION - ? "legal action" - : "other"; - await this.emailHelperService.sendEmailToOrganisationAdmins( - fromCompany.companyId, - EmailTemplates.CREDIT_RETIREMENT_BY_GOV, - { - credits: transfer.creditAmount, - programmeName: programme.title, - serialNumber: programme.serialNo, - government: toCompany.name, - reason: reason, - pageLink: hostAddress + "/creditTransfers/viewAll", - } - ); - } - allTransferList.push(transfer); - } - const results = await this.programmeTransferRepo.insert(allTransferList); - console.log(results); - for (const i in allTransferList) { - allTransferList[i].requestId = results.identifiers[i].requestId; - } - - let updateProgramme = undefined; - for (const trf of autoApproveTransferList) { - this.logger.log(`Retire auto approve received ${trf}`); - updateProgramme = ( - await this.doTransfer( - trf, - `${this.getUserRef(requester)}#${toCompany.companyId}#${ - toCompany.name - }#${fromCompanyMap[trf.fromCompanyId].companyId}#${ - fromCompanyMap[trf.fromCompanyId].name - }`, - req.comment, - true - ) - ).data; - } - if (updateProgramme) { - return new DataResponseDto(HttpStatus.OK, updateProgramme); - } - return new DataListResponseDto(allTransferList, allTransferList.length); - } - - async issueProgrammeCredit(req: ProgrammeIssue, user: User) { - this.logger.log( - `Programme ${req.programmeId} approve. Comment: ${req.comment}` - ); - const program = await this.programmeLedger.getProgrammeById( - req.programmeId - ); - if (!program) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (user.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - user, - program.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - - if (program.currentStage != ProgrammeStage.AUTHORISED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.notInAUthorizedState", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - if (program.creditEst - program.creditIssued < req.issueAmount) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.issuedCreditAmountcantExceedPendingCredit", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - let updated: any = await this.programmeLedger.issueProgrammeStatus( - req.programmeId, - this.configService.get("systemCountry"), - program.companyId, - req.issueAmount, - this.getUserRefWithRemarks(user, req.comment) - ); - if (!updated) { - return new BasicResponseDto( - HttpStatus.BAD_REQUEST, - this.helperService.formatReqMessagesString( - "programme.notFOundAPendingProgrammeForTheId", - [req.programmeId] - ) - ); - } - - const issueCReq: AsyncAction = { - actionType: AsyncActionType.IssueCredit, - actionProps: { - externalId: program.externalId, - issueAmount: req.issueAmount, - }, - }; - await this.asyncOperationsInterface.AddAction( - issueCReq - ); - - const hostAddress = this.configService.get("host"); - updated.companyId.forEach(async (companyId) => { - await this.emailHelperService.sendEmailToOrganisationAdmins( - companyId, - EmailTemplates.CREDIT_ISSUANCE, - { - programmeName: updated.title, - credits: req.issueAmount, - serialNumber: updated.serialNo, - pageLink: - hostAddress + `/programmeManagement/view?id=${updated.programmeId}`, - } - ); - }); - - const companyData = await this.companyService.findByCompanyIds({ - companyIds: program.companyId, - }); - - const suspendedCompanies = companyData.filter( - (company) => company.state == CompanyState.SUSPENDED - ); - - if (suspendedCompanies.length > 0) { - updated = await this.programmeLedger.freezeIssuedCredit( - req.programmeId, - req.issueAmount, - this.getUserRef(user), - suspendedCompanies - ); - if (!updated) { - return new BasicResponseDto( - HttpStatus.BAD_REQUEST, - this.helperService.formatReqMessagesString( - "programme.internalErrorCreditFreezing", - [req.programmeId] - ) - ); - } - } - - updated.company = await this.companyRepo.find({ - where: { companyId: In(updated.companyId) }, - }); - if (updated.certifierId && updated.certifierId.length > 0) { - updated.certifier = await this.companyRepo.find({ - where: { companyId: In(updated.certifierId) }, - }); - } - - return new DataResponseDto(HttpStatus.OK, updated); - } - - async approveProgramme(req: ProgrammeApprove, user: User) { - this.logger.log( - `Programme ${req.programmeId} approve. Comment: ${req.comment}` - ); - const program = await this.programmeLedger.getProgrammeById( - req.programmeId - ); - if (!program) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - if (user.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - user, - program.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - - if (program.currentStage != ProgrammeStage.AWAITING_AUTHORIZATION) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.notInPendingState", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - if (program.creditEst < req.issueAmount) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.issuedCreditCannotExceedEstCredit", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - const updated: any = await this.programmeLedger.authProgrammeStatus( - req.programmeId, - this.configService.get("systemCountry"), - program.companyId, - req.issueAmount, - this.getUserRefWithRemarks(user, req.comment) - ); - if (!updated) { - return new BasicResponseDto( - HttpStatus.BAD_REQUEST, - this.helperService.formatReqMessagesString( - "programme.inotFOundAPendingProgrammeForTheId", - [req.programmeId] - )`Does not found a pending programme for the given programme id ${req.programmeId}` - ); - } - - const authRe: AsyncAction = { - actionType: AsyncActionType.AuthProgramme, - actionProps: { - externalId: program.externalId, - issueAmount: req.issueAmount, - serialNo: updated.serialNo, - authOrganisationName: (user as any).companyName - }, - }; - await this.asyncOperationsInterface.AddAction( - authRe - ); - - updated.company = await this.companyRepo.find({ - where: { companyId: In(updated.companyId) }, - }); - if (updated.certifierId && updated.certifierId.length > 0) { - updated.certifier = await this.companyRepo.find({ - where: { companyId: In(updated.certifierId) }, - }); - } - - const hostAddress = this.configService.get("host"); - let authDate = new Date(updated.txTime); - let date = authDate.getDate().toString().padStart(2, "0"); - let month = authDate.toLocaleString("default", { month: "long" }); - let year = authDate.getFullYear(); - let formattedDate = `${date} ${month} ${year}`; - - updated.company.forEach(async (company) => { - await this.emailHelperService.sendEmailToOrganisationAdmins( - company.companyId, - EmailTemplates.PROGRAMME_AUTHORISATION, - { - programmeName: updated.title, - authorisedDate: formattedDate, - serialNumber: updated.serialNo, - programmePageLink: - hostAddress + `/programmeManagement/view?id=${updated.programmeId}`, - } - ); - }); - - return new DataResponseDto(HttpStatus.OK, updated); - } - - async rejectProgramme(req: ProgrammeReject, user: User) { - this.logger.log( - `Programme ${req.programmeId} reject. Comment: ${req.comment}` - ); - const programme = await this.findById(req.programmeId); - const currentStage = programme.currentStage; - if (currentStage === ProgrammeStage.REJECTED) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.rejectAlreadyRejectedProg", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - const updated = await this.programmeLedger.updateProgrammeStatus( - req.programmeId, - ProgrammeStage.REJECTED, - ProgrammeStage.AWAITING_AUTHORIZATION, - this.getUserRefWithRemarks(user, req.comment) - ); - if (!updated) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.programmeNotExist", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (user.companyRole === CompanyRole.MINISTRY) { - const permission = await this.findPermissionForMinistryUser( - user, - programme.sectoralScope - ); - if (!permission) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - - const authRe: AsyncAction = { - actionType: AsyncActionType.RejectProgramme, - actionProps: { - externalId: programme.externalId, - comment: req.comment - }, - }; - await this.asyncOperationsInterface.AddAction( - authRe - ); - - await this.emailHelperService.sendEmailToProgrammeOwnerAdmins( - req.programmeId, - EmailTemplates.PROGRAMME_REJECTION, - { reason: req.comment } - ); - - return new BasicResponseDto(HttpStatus.OK, "Successfully updated"); - } - - private getUserName = async (usrId: any) => { - this.logger.debug(`Getting user [${usrId}]`); - if (usrId == "undefined" || usrId == "null") { - return null; - } - const userId = Number(usrId); - if (userId == undefined || userId == null) { - return null; - } - if (this.userNameCache[userId]) { - this.logger.debug( - `Getting user - cached ${userId} ${this.userNameCache[userId]}` - ); - return this.userNameCache[userId]; - } - const user = await this.userService.findById(Number(userId)); - this.logger.debug(`Getting user - user ${user}`); - if (user) { - this.logger.debug(`Getting user - user ${user.name}`); - this.userNameCache[userId] = user.name; - return user.name; - } - return null; - }; - - private getCompanyIdAndUserIdFromRef = (ref: string) => { - if (!ref) { - return null; - } - if (ref == CompanyRole.API.toString()) { - return null; - } - - const parts = ref.split("#"); - if (parts.length > 2) { - return { - id: parts[2], - companyId: Number(parts[0]), - }; - } - if (parts.length > 0) { - return { - companyId: Number(parts[0]), - }; - } - return null; - }; - - async findByExternalId(externalId: string): Promise { - return await this.programmeRepo.findOne({ - where: { - externalId: externalId, - }, - }); - } - - async regenerateRegionCoordinates() { - this.logger.log(`Regenrate coordinates:`) - const allProgrammes = await this.programmeRepo.find(); - for (const programme of allProgrammes) { - const programmeProperties = programme.programmeProperties; - let address: any[] = []; - if (programmeProperties.geographicalLocation) { - for ( - let index = 0; - index < programmeProperties.geographicalLocation.length; - index++ - ) { - address.push(programmeProperties.geographicalLocation[index]); - } - } - await this.locationService.getCoordinatesForRegion([...address]).then( - (response: any) => { - console.log( - "response from forwardGeoCoding function -> ", - response - ); - programme.geographicalLocationCordintes = [...response]; - } - ); - - const result = await this.programmeRepo - .update( - { - programmeId: programme.programmeId, - }, - { - geographicalLocationCordintes: programme.geographicalLocationCordintes - } - ) - .catch((err) => { - this.logger.error(err); - return err; - }); - this.logger.log(`Updated programme: ${programme.programmeId} ${programme.geographicalLocationCordintes}`) - } - } - private getUserRef = (user: any) => { - return `${user.companyId}#${user.companyName}#${user.id}`; - }; - - private getUserRefWithRemarks = (user: any, remarks: string) => { - return `${user.companyId}#${user.companyName}#${user.id}#${remarks}`; - }; - - private checkPendingTransferValidity = async(programme:Programme) => { - const hostAddress = this.configService.get("host"); - const transfers = await this.programmeTransferRepo.find({ - where: { - programmeId: programme.programmeId, - status: TransferStatus.PENDING, - }, - }); - - for (let transfer of transfers) { - const companyIndex = programme.companyId.indexOf( - transfer.fromCompanyId - ); - const companyProponent = programme.creditOwnerPercentage[companyIndex]; - const creditBalance = - (programme.creditBalance * companyProponent) / 100; - if (transfer.creditAmount > creditBalance) { - const result = await this.programmeTransferRepo - .update( - { - requestId: transfer.requestId, - }, - { - status: TransferStatus.CANCELLED, - txTime: new Date().getTime(), - authTime: new Date().getTime(), - txRef: `#${SystemActionType.LOW_CREDIT_AUTO_CANCEL}#`, - } - ) - .catch((err) => { - this.logger.error(err); - return err; - }); - - if (result.affected === 0) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "programme.internalErrorStatusUpdating", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } else { - if (transfer.isRetirement && transfer.toCompanyMeta) { - const countryName = await this.countryService.getCountryName( - transfer.toCompanyMeta.country - ); - - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_RETIREMENT_CANCEL_SYS_TO_INITIATOR, - { - credits: transfer.creditAmount, - serialNumber: programme.serialNo, - programmeName: programme.title, - country: countryName, - pageLink: hostAddress + "/creditTransfers/viewAll", - } - ); - - await this.emailHelperService.sendEmailToGovernmentAdmins( - EmailTemplates.CREDIT_RETIREMENT_CANCEL_SYS_TO_GOV, - { - credits: transfer.creditAmount, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - country: countryName, - }, - "", - transfer.initiatorCompanyId - ); - } else { - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.initiatorCompanyId, - EmailTemplates.CREDIT_TRANSFER_CANCELLATION_SYS_TO_INITIATOR, - { - credits: transfer.creditAmount, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }, - transfer.toCompanyId - ); - - await this.emailHelperService.sendEmailToOrganisationAdmins( - transfer.fromCompanyId, - EmailTemplates.CREDIT_TRANSFER_CANCELLATION_SYS_TO_SENDER, - { - credits: transfer.creditAmount, - serialNumber: programme.serialNo, - programmeName: programme.title, - pageLink: hostAddress + "/creditTransfers/viewAll", - }, - transfer.toCompanyId, - "", - transfer.initiatorCompanyId - ); - } - } - } - } - } - -} diff --git a/backend/services/src/shared/rbac/roles.decorator.ts b/backend/services/src/shared/rbac/roles.decorator.ts deleted file mode 100644 index 1e2cc1f8f..000000000 --- a/backend/services/src/shared/rbac/roles.decorator.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { SetMetadata } from '@nestjs/common'; -import { Role } from '../casl/role.enum'; - -export const ROLES_KEY = 'roles'; -export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles); \ No newline at end of file diff --git a/backend/services/src/shared/rbac/roles.guard.ts b/backend/services/src/shared/rbac/roles.guard.ts deleted file mode 100644 index e579a08a1..000000000 --- a/backend/services/src/shared/rbac/roles.guard.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; -import { Reflector } from '@nestjs/core'; -import { Role } from '../casl/role.enum'; -import { ROLES_KEY } from './roles.decorator'; - -@Injectable() -export class RolesGuard implements CanActivate { - constructor(private reflector: Reflector) {} - - canActivate(context: ExecutionContext): boolean { - const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [ - context.getHandler(), - context.getClass(), - ]); - if (!requiredRoles) { - return true; - } - const { user } = context.switchToHttp().getRequest(); - return requiredRoles.some((role) => user.roles?.includes(role)); - } -} \ No newline at end of file diff --git a/backend/services/src/shared/registry-client/registry-client.module.ts b/backend/services/src/shared/registry-client/registry-client.module.ts deleted file mode 100644 index a816ef046..000000000 --- a/backend/services/src/shared/registry-client/registry-client.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Logger, Module } from '@nestjs/common'; -import { RegistryClientService } from './registry-client.service'; -import { ConfigModule } from '@nestjs/config'; -import configuration from '../configuration'; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - ], - providers: [RegistryClientService, Logger], - exports: [RegistryClientService] -}) -export class RegistryClientModule {} diff --git a/backend/services/src/shared/registry-client/registry-client.service.spec.ts b/backend/services/src/shared/registry-client/registry-client.service.spec.ts deleted file mode 100644 index 965afc032..000000000 --- a/backend/services/src/shared/registry-client/registry-client.service.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { RegistryClientService } from './registry-client.service'; - -describe('RegistryClentService', () => { - let service: RegistryClientService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [RegistryClientService], - }).compile(); - - service = module.get(RegistryClientService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); - - -}); diff --git a/backend/services/src/shared/registry-client/registry-client.service.ts b/backend/services/src/shared/registry-client/registry-client.service.ts deleted file mode 100644 index b2e909b5b..000000000 --- a/backend/services/src/shared/registry-client/registry-client.service.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Injectable, Logger } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { UserDto } from "../dto/user.dto"; -import axios from "axios"; -import { ProgrammeApprove } from "../dto/programme.approve"; - -@Injectable() -export class RegistryClientService { - constructor(private configService: ConfigService, private logger: Logger) {} - - private async sendHttp(endpoint: string, data: any) { - if (!this.configService.get("registry.syncEnable")) { - this.logger.debug("Company created ignored due to registry sync disable"); - return; - } - - return await axios - .post(this.configService.get("registry.endpoint") + endpoint, data, { - headers: { - api_key: `${this.configService.get("registry.apiToken")}`, - }, - }) - .catch((ex) => { - console.log("Exception", ex.response?.data?.message); - if ( - ex.response?.data?.statusCode == 400 && - ex.response?.data?.message?.indexOf("already exist") >= 0 - ) { - return true; - } - throw ex; - }); - } - - private async sendHttpPut(endpoint: string, data: any) { - if (!this.configService.get("registry.syncEnable")) { - this.logger.debug("Company created ignored due to registry sync disable"); - return; - } - - return await axios - .put(this.configService.get("registry.endpoint") + endpoint, data, { - headers: { - api_key: `${this.configService.get("registry.apiToken")}`, - }, - }) - .catch((ex) => { - console.log("Exception", ex.response?.data?.statusCode); - if ( - ex.response?.data?.statusCode == 400 && - ex.response?.data?.message?.indexOf("already exist") >= 0 - ) { - return true; - } - throw ex; - }); - } - - public async createCompany(userDto: UserDto) { - const resp = await this.sendHttp("/national/user/add", userDto); - console.log( - "Successfully create company on MRV", - userDto.company.name - ); - return resp; - } - - public async authProgramme(approve) { - const resp = await this.sendHttpPut("/national/programme/authProgramme", approve); - console.log( - "Successfully authoirised programme on MRV", - approve - ); - return resp; - } - - public async rejectProgramme(reject) { - const resp = await this.sendHttpPut("/national/programme/rejectProgramme", reject); - console.log( - "Successfully rejected programme on MRV", - reject - ); - return resp; - } - - - public async issueCredit(issue) { - const resp = await this.sendHttpPut("/national/programme/issueCredit", issue); - console.log( - "Successfully issued programme on MRV", - issue - ); - return resp; - } -} diff --git a/backend/services/src/shared/server.ts b/backend/services/src/shared/server.ts deleted file mode 100644 index a4df0f551..000000000 --- a/backend/services/src/shared/server.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { createLogger } from "winston"; -import { - utilities as nestWinstonModuleUtilities, - WinstonModule, -} from "nest-winston"; -import { createServer, proxy } from "aws-serverless-express"; -import { eventContext } from "aws-serverless-express/middleware"; - -import { AbstractHttpAdapter, NestFactory } from "@nestjs/core"; -import { - ExpressAdapter, - NestExpressApplication, -} from "@nestjs/platform-express"; -import { Server } from "http"; -import * as winston from "winston"; -import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; -import { BadRequestException, INestApplication } from "@nestjs/common"; -import { ValidationPipe } from "@nestjs/common"; -import { TrimPipe } from "./validation/trim-pipe.transform"; -import { ValidationException } from "./validation/validation.exception"; -import { ValidationExceptionFilter } from "./validation/validation-exception.filter"; -import { useContainer } from "class-validator"; -import { UtilModule } from "./util/util.module"; -import * as bodyParser from "body-parser"; - -const express = require("express"); - -// NOTE: If you get ERR_CONTENT_DECODING_FAILED in your browser, this is likely -// due to a compressed response (e.g. gzip) which has not been handled correctly -// by aws-serverless-express and/or API Gateway. Add the necessary MIME types to -// binaryMimeTypes below -const binaryMimeTypes: string[] = []; - -function setupSwagger( - nestApp: INestApplication, - name: string, - httpBase: String -): void { - const config = new DocumentBuilder() - .setTitle(`${name.replace("APIModule", " API")}`) - .setDescription( - `RESTful Web API Documentation. - ` - ) - .setVersion("0.5") - .addBearerAuth() - .addApiKey() - .addServer(`${process.env.DOMAIN_MAP == 'true' ? "/" : ("/" + process.env.NODE_ENV)}`) - .build(); - // ${process.env.NODE_ENV} - const document = SwaggerModule.createDocument(nestApp, config); - - SwaggerModule.setup(`${httpBase}`, nestApp, document, { - customSiteTitle: "API Documentation", - customCss: ` - .topbar-wrapper img {content:url(\'https://carbon-common-dev.s3.amazonaws.com/logo-h.png\'); height:50px; width:auto;} - .swagger-ui .topbar { background-color: #f4f5fa; } - .swagger-ui { background-color: white; } - #links-header { position: absolute; top: 25px; right: calc((100% - 1440px)/2); } - #links-header a { margin-right: 15px;} - `, - swaggerOptions: { - docExpansion: "alpha", - operationSorter: "alpha", - tagSorter: "alpha", - }, - }); -} - -export function getLogger(module) { - const instance = createLogger({ - transports: [ - new winston.transports.Console({ - format: winston.format.combine( - winston.format.timestamp(), - winston.format.ms(), - nestWinstonModuleUtilities.format.nestLike(module.name, { - // options - }) - ), - level: process.env.LOG_LEVEL, - }), - ], - }); - - return WinstonModule.createLogger({ - instance, - }); -} - -export async function buildNestApp( - module: any, - httpBase: string, - expressApp?: AbstractHttpAdapter -): Promise { - const nestApp = await NestFactory.create( - module, - new ExpressAdapter(expressApp), - { - logger: getLogger(module), - } - ); - useContainer(nestApp.select(UtilModule), { fallbackOnErrors: true }); - nestApp.setGlobalPrefix(httpBase); - nestApp.use(bodyParser.json({ limit: "50mb" })); - nestApp.enableCors(); - nestApp.useGlobalPipes(new TrimPipe()); - nestApp.useGlobalPipes( - new ValidationPipe({ - exceptionFactory: (errors) => new ValidationException(errors), - }) - ); - nestApp.useGlobalFilters(new ValidationExceptionFilter()); - nestApp.use(eventContext()); - setupSwagger(nestApp, module.name, httpBase); - return nestApp; -} - -export async function bootstrapServer( - cachedServer: Server, - module: any, - httpBase: string -): Promise { - if (!cachedServer) { - const expressApp = express(); - const nestApp = await buildNestApp(module, httpBase, expressApp); - await nestApp.init(); - cachedServer = createServer(expressApp, undefined, binaryMimeTypes); - } - return cachedServer; -} diff --git a/backend/services/src/shared/typeorm.config.service.ts b/backend/services/src/shared/typeorm.config.service.ts deleted file mode 100644 index 1fec74deb..000000000 --- a/backend/services/src/shared/typeorm.config.service.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from "@nestjs/typeorm"; - -@Injectable() -export class TypeOrmConfigService implements TypeOrmOptionsFactory { - - constructor(private configService: ConfigService) {} - - createTypeOrmOptions(): TypeOrmModuleOptions { - return this.configService.get('database'); - } -} \ No newline at end of file diff --git a/backend/services/src/shared/user/user.module.ts b/backend/services/src/shared/user/user.module.ts deleted file mode 100644 index 567c22197..000000000 --- a/backend/services/src/shared/user/user.module.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { forwardRef, Logger, Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { User } from '../../shared/entities/user.entity'; -import { UserService } from './user.service'; -import { CaslModule } from '../../shared/casl/casl.module'; -import { TypeOrmConfigService } from '../../shared/typeorm.config.service'; -import configuration from '../../shared/configuration'; -import { ConfigModule } from '@nestjs/config'; -import { CompanyModule } from '../company/company.module'; -import { UtilModule } from '../util/util.module'; -import { EmailHelperModule } from '../email-helper/email-helper.module'; -import { FileHandlerModule } from '../file-handler/filehandler.module'; -import { AsyncOperationsModule } from '../async-operations/async-operations.module'; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`] - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - imports: undefined - }), - TypeOrmModule.forFeature([User]), - CaslModule, - forwardRef(() => CompanyModule), - forwardRef(() => EmailHelperModule), - UtilModule, - FileHandlerModule, - AsyncOperationsModule, - ], - providers: [UserService, Logger], - exports: [UserService] -}) -export class UserModule {} diff --git a/backend/services/src/shared/user/user.service.spec.ts b/backend/services/src/shared/user/user.service.spec.ts deleted file mode 100644 index 873de8ac4..000000000 --- a/backend/services/src/shared/user/user.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { UserService } from './user.service'; - -describe('UserService', () => { - let service: UserService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [UserService], - }).compile(); - - service = module.get(UserService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/user/user.service.ts b/backend/services/src/shared/user/user.service.ts deleted file mode 100644 index c0c362000..000000000 --- a/backend/services/src/shared/user/user.service.ts +++ /dev/null @@ -1,830 +0,0 @@ -import { - forwardRef, - HttpException, - HttpStatus, - Inject, - Injectable, - Logger, - UseFilters, -} from "@nestjs/common"; -import { - InjectConnection, - InjectEntityManager, - InjectRepository, -} from "@nestjs/typeorm"; -import { UserDto } from "../../shared/dto/user.dto"; -import { - Connection, - EntityManager, - QueryFailedError, - Repository, -} from "typeorm"; -import { User } from "../../shared/entities/user.entity"; -import { QueryDto } from "../../shared/dto/query.dto"; -import { EmailTemplates } from "../email-helper/email.template"; -import { PG_UNIQUE_VIOLATION } from "@drdgvhbh/postgres-error-codes"; -import { UserUpdateDto } from "../../shared/dto/user.update.dto"; -import { PasswordUpdateDto } from "../../shared/dto/password.update.dto"; -import { BasicResponseDto } from "../../shared/dto/basic.response.dto"; -import { Role } from "../../shared/casl/role.enum"; -import { nanoid } from "nanoid"; -import { API_KEY_SEPARATOR } from "../../shared/constants"; -import { DataResponseDto } from "../../shared/dto/data.response.dto"; -import { DataListResponseDto } from "../../shared/dto/data.list.response"; -import { ConfigService } from "@nestjs/config"; -import { CompanyRole } from "../../shared/enum/company.role.enum"; -import { plainToClass } from "class-transformer"; -import { Company } from "../../shared/entities/company.entity"; -import { CompanyService } from "../company/company.service"; -import { HelperService } from "../util/helpers.service"; -import { CounterService } from "../util/counter.service"; -import { CounterType } from "../util/counter.type.enum"; -import { FileHandlerInterface } from "../file-handler/filehandler.interface"; -import { CountryService } from "../util/country.service"; -import { - AsyncAction, - AsyncOperationsInterface, -} from "../async-operations/async-operations.interface"; -import { AsyncActionType } from "../enum/async.action.type.enum"; -import { DataResponseMessageDto } from "../dto/data.response.message"; -import { AsyncOperationType } from "../enum/async.operation.type.enum"; - -@Injectable() -export class UserService { - constructor( - @InjectRepository(User) private userRepo: Repository, - private logger: Logger, - private configService: ConfigService, - private helperService: HelperService, - @InjectEntityManager() private entityManger: EntityManager, - @Inject(forwardRef(() => CompanyService)) - private companyService: CompanyService, - private counterService: CounterService, - private countryService: CountryService, - private fileHandler: FileHandlerInterface, - private asyncOperationsInterface: AsyncOperationsInterface - ) {} - - private async generateApiKey(email) { - return Buffer.from( - `${email}${API_KEY_SEPARATOR}${await nanoid()}` - ).toString("base64"); - } - - async getAdminUserDetails(companyId) { - const result = await this.userRepo.find({ - where: { - role: Role.Admin, - companyId: parseInt(companyId), - }, - }); - - return result; - } - - async getUserCredentials(username: string): Promise { - const users = await this.userRepo.find({ - select: [ - "id", - "email", - "password", - "role", - "apiKey", - "companyId", - "companyRole", - "name", - ], - where: { - email: username, - }, - }); - return users && users.length > 0 ? users[0] : undefined; - } - - async findOne(username: string): Promise { - const users = await this.userRepo.find({ - where: { - email: username, - }, - }); - return users && users.length > 0 ? users[0] : undefined; - } - - async getRoot(): Promise { - const users = await this.userRepo.find({ - where: { - role: Role.Root, - }, - }); - return users && users.length > 0 ? users[0] : undefined; - } - - async getUserProfileDetails(id: number) { - const userProfileDetails = await this.findById(id); - const organisationDetails = await this.companyService.findByCompanyId( - userProfileDetails.companyId - ); - return { - user: userProfileDetails, - Organisation: organisationDetails, - }; - } - - async findById(id: number): Promise { - return await this.userRepo.findOneBy({ - id: id, - }); - } - - async update( - userDto: UserUpdateDto, - abilityCondition: string - ): Promise { - this.logger.verbose("User update received", abilityCondition); - - userDto.email = userDto.email?.toLowerCase() - - const { id, ...update } = userDto; - const user = await this.findById(id); - if (!user) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.noUserFound", []), - HttpStatus.NOT_FOUND - ); - } - - const result = await this.userRepo - .createQueryBuilder() - .update(User) - .set(update) - .where( - `id = ${id} ${ - abilityCondition - ? " AND (" + - this.helperService.parseMongoQueryToSQL(abilityCondition) + - ")" - : "" - }` - ) - .execute() - .catch((err: any) => { - this.logger.error(err); - return err; - }); - if (result.affected) { - return new DataResponseMessageDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString("user.editUserSuccess", []), - await this.findById(id) - ); - } - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - - async resetPassword( - id: number, - passwordResetDto: PasswordUpdateDto, - abilityCondition: string - ) { - this.logger.verbose("User password reset received", id); - - const user = await this.userRepo - .createQueryBuilder() - .where( - `id = '${id}' ${ - abilityCondition - ? " AND (" + - this.helperService.parseMongoQueryToSQL(abilityCondition) + ")" - : "" - }` - ) - .addSelect(["User.password"]) - .getOne(); - if (!user || user.password != passwordResetDto.oldPassword) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.oldPasswordIncorrect", - [] - ), - HttpStatus.UNAUTHORIZED - ); - } - const result = await this.userRepo - .update( - { - id: id, - }, - { - password: passwordResetDto.newPassword, - } - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - if (result.affected > 0) { - const templateData = { - name: user.name, - countryName: this.configService.get("systemCountryName"), - }; - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: EmailTemplates.CHANGE_PASSOWRD.id, - sender: user.email, - subject: this.helperService.getEmailTemplateMessage( - EmailTemplates.CHANGE_PASSOWRD["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - EmailTemplates.CHANGE_PASSOWRD["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString("user.resetSuccess", []) - ); - } - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.passwordUpdateFailed", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - async regenerateApiKey(email, abilityCondition) { - email = email?.toLowerCase() - this.logger.verbose("Regenerated api key received", email); - const user = await this.userRepo - .createQueryBuilder() - .where( - `email = '${email}' ${ - abilityCondition - ? " AND (" + - this.helperService.parseMongoQueryToSQL(abilityCondition) + ")" - : "" - }` - ) - .getOne(); - if (!user) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.noUserFound", []), - HttpStatus.UNAUTHORIZED - ); - } - const apiKey = await this.generateApiKey(email); - const result = await this.userRepo - .update( - { - id: user.id, - }, - { - apiKey: apiKey, - } - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - - if (result.affected > 0) { - const templateData = { - name: user.name, - apiKey: apiKey, - }; - - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: EmailTemplates.API_KEY_EMAIL.id, - sender: user.email, - subject: this.helperService.getEmailTemplateMessage( - EmailTemplates.API_KEY_EMAIL["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - EmailTemplates.API_KEY_EMAIL["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString("user.resetSuccess", []) - ); - } - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.passwordUpdateFailed", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - async createUserWithPassword( - name: string, - companyRole: CompanyRole, - taxId: string, - password: string, - email: string, - userRole: Role, - phoneNo: string, - APIkey: string - ) { - let company: Company; - if ( - companyRole != CompanyRole.GOVERNMENT && - companyRole != CompanyRole.MINISTRY - ) { - if (!taxId || taxId === "") { - throw new HttpException( - "Tax id cannot be empty:" + email, - HttpStatus.BAD_REQUEST - ); - } - company = await this.companyService.findByTaxId(taxId); - } else { - if (companyRole === CompanyRole.GOVERNMENT) { - company = await this.companyService.findGovByCountry( - this.configService.get("systemCountry") - ); - } else if (companyRole === CompanyRole.MINISTRY) { - company = await this.companyService.findMinByCountry( - this.configService.get("systemCountry") - ); - } - } - - if (!company) { - throw new HttpException( - "Company does not exist" + email, - HttpStatus.BAD_REQUEST - ); - } - const user = new User(); - user.email = email; - user.password = password; - user.companyId = company.companyId; - user.companyRole = company.companyRole; - user.name = name; - user.createdTime = new Date().getTime(); - user.country = this.configService.get("systemCountry"); - user.phoneNo = phoneNo; - user.role = userRole; - user.apiKey = APIkey; - - console.log("Inserting user", user.email); - return await this.userRepo - .createQueryBuilder() - .insert() - .values(user) - .orUpdate( - ["password", "companyId", "companyRole", "name", "role", "phoneNo"], - ["email"] - ) - .execute(); - } - - async create( - userDto: UserDto, - companyId: number, - companyRole: CompanyRole - ): Promise { - this.logger.verbose(`User create received ${userDto.email} ${companyId}`); - userDto.email = userDto.email?.toLowerCase(); - const createdUserDto = {...userDto}; - if(userDto.company){ - createdUserDto.company={...userDto.company} - } - const user = await this.findOne(userDto.email); - if (user) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.createExistingUser", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - let { company, ...userFields } = userDto; - if ( - !company && - userDto.companyId && - companyRole === CompanyRole.GOVERNMENT - ) { - const adminUserdetails = await this.getAdminUserDetails( - userDto.companyId - ); - if (adminUserdetails?.length > 0) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - } - if (company) { - if ( - companyRole != CompanyRole.GOVERNMENT && - companyRole != CompanyRole.API && - companyRole !== CompanyRole.MINISTRY - ) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - if ( - userFields.role && - ![Role.Admin, Role.Root].includes(userFields.role) - ) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.companyCreateUserShouldbeAdmin", - [] - ), - HttpStatus.BAD_REQUEST - ); - } else if (!userFields.role) { - userFields.role = Role.Admin; - } - - if(company.companyRole === CompanyRole.MINISTRY && companyRole === CompanyRole.MINISTRY) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.minUserCannotCreateMin", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - - if (company.companyRole != CompanyRole.CERTIFIER || !company.country) { - company.country = this.configService.get("systemCountry"); - } - - console.log( - "Company Log", - company, - this.configService.get("systemCountry") - ); - - if (company.companyRole == CompanyRole.GOVERNMENT) { - const companyGov = await this.companyService.findGovByCountry( - company.country - ); - if (companyGov) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.governmentUserAlreadyExist", - [company.country] - ), - HttpStatus.BAD_REQUEST - ); - } - } - - company.createdTime = new Date().getTime(); - } - - if ( - CompanyRole.GOVERNMENT != companyRole && - userDto.companyId && - userDto.companyId != companyId - ) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - - const u: User = plainToClass(User, userFields); - if (userDto.company) { - u.companyRole = userDto.company.companyRole; - } else if (u.companyId) { - const company = await this.companyService.findByCompanyId(u.companyId); - if (!company) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.addUserToUnRegisteredCompany", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - u.companyRole = company.companyRole; - } else { - u.companyId = companyId; - u.companyRole = companyRole; - } - - if (u.companyRole != CompanyRole.CERTIFIER || !u.country) { - u.country = this.configService.get("systemCountry"); - } - - u.password = this.helperService.generateRandomPassword(); - if (userDto.role == Role.Admin) { - u.apiKey = await this.generateApiKey(userDto.email); - } - - const hostAddress = this.configService.get("host"); - - if (company) { - company.companyId = parseInt( - await this.counterService.incrementCount(CounterType.COMPANY, 3) - ); - if (company.logo && this.helperService.isBase64(company.logo)) { - const response: any = await this.fileHandler.uploadFile( - `profile_images/${company.companyId}_${new Date().getTime()}.png`, - company.logo - ); - if (response) { - company.logo = response; - if (process.env.ASYNC_OPERATIONS_TYPE === AsyncOperationType.Queue) { - createdUserDto.company.logo = response; - } - } else { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.companyUpdateFailed", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - } - - if (!company.hasOwnProperty("website")) { - company["website"] = ""; - } - - if (company.email) { - const templateData = { - organisationName: company.name, - countryName: this.configService.get("systemCountryName"), - organisationRole: - company.companyRole === CompanyRole.PROGRAMME_DEVELOPER - ? "Programme Developer" - : company.companyRole, - home: hostAddress, - }; - - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: EmailTemplates.ORGANISATION_CREATE.id, - sender: company.email, - subject: this.helperService.getEmailTemplateMessage( - EmailTemplates.ORGANISATION_CREATE["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - EmailTemplates.ORGANISATION_CREATE["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - } - } - - const templateData = { - name: u.name, - countryName: this.configService.get("systemCountryName"), - tempPassword: u.password, - home: hostAddress, - email: u.email, - liveChat: this.configService.get("liveChat"), - helpDoc: hostAddress + "/help", - }; - - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: EmailTemplates.USER_CREATE.id, - sender: u.email, - subject: this.helperService.getEmailTemplateMessage( - EmailTemplates.USER_CREATE["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - EmailTemplates.USER_CREATE["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - - u.createdTime = new Date().getTime(); - - if (company && companyRole !== CompanyRole.API && userFields.role !== Role.Root && company.companyRole !== CompanyRole.API) { - const registryCompanyCreateAction: AsyncAction = { - actionType: AsyncActionType.RegistryCompanyCreate, - actionProps: createdUserDto, - }; - await this.asyncOperationsInterface.AddAction( - registryCompanyCreateAction - ); - } - - const usr = await this.entityManger - .transaction(async (em) => { - if (company) { - const c: Company = await em.save( - plainToClass(Company, company) - ); - u.companyId = c.companyId; - u.companyRole = company.companyRole; - } - const user = await em.save(u); - return user; - }) - .catch((err: any) => { - console.log(err); - if (err instanceof QueryFailedError) { - console.log(err); - switch (err.driverError.code) { - case PG_UNIQUE_VIOLATION: - if (err.driverError.detail.includes("email")) { - throw new HttpException( - `${ - err.driverError.table == "company" - ? this.helperService.formatReqMessagesString( - "user.orgEmailExist", - [] - ) - : "Email already exist" - }`, - HttpStatus.BAD_REQUEST - ); - } else if (err.driverError.detail.includes("taxId")) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.taxIdExistAlready", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - } - this.logger.error(`User add error ${err}`); - } else { - this.logger.error(`User add error ${err}`); - } - return err; - }); - - const { apiKey, password, ...resp } = usr; - - const response = new DataResponseMessageDto( - HttpStatus.CREATED, - this.helperService.formatReqMessagesString("user.createUserSuccess", []), - resp - ); - - return response; - } - - async query(query: QueryDto, abilityCondition: string): Promise { - const resp = await this.userRepo - .createQueryBuilder("user") - .where( - this.helperService.generateWhereSQL( - query, - this.helperService.parseMongoQueryToSQLWithTable( - '"user"', - abilityCondition - ), - '"user"' - ) - ) - .leftJoinAndMapOne( - "user.company", - Company, - "company", - "company.companyId = user.companyId" - ) - .orderBy( - query?.sort?.key ? `"user"."${query?.sort?.key}"` : `"user"."id"`, - query?.sort?.order ? query?.sort?.order : "DESC" - ) - .offset(query.size * query.page - query.size) - .limit(query.size) - .getManyAndCount(); - - return new DataListResponseDto( - resp.length > 0 ? resp[0] : undefined, - resp.length > 1 ? resp[1] : undefined - ); - } - - async delete(userId: number, ability: string): Promise { - this.logger.verbose( - this.helperService.formatReqMessagesString("user.noUserFound", []), - userId - ); - - const result = await this.userRepo - .createQueryBuilder() - .where( - `id = '${userId}' ${ - ability - ? ` AND (${this.helperService.parseMongoQueryToSQL(ability)})` - : "" - }` - ) - .getMany(); - if (result.length <= 0) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.userUnAUth", []), - HttpStatus.FORBIDDEN - ); - } - - if (result[0].role == Role.Root) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.rootUserDelete", []), - HttpStatus.FORBIDDEN - ); - } else if (result[0].role == Role.Admin) { - const admins = await this.userRepo - .createQueryBuilder() - .where( - `"companyId" = '${result[0].companyId}' and role = '${Role.Admin}'` - ) - .getMany(); - if (admins.length <= 1) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.deleteOneAdminWhenOnlyOneAdmin", - [] - ), - HttpStatus.FORBIDDEN - ); - } - } - - const result2 = await this.userRepo.delete({ id: userId }); - if (result2.affected > 0) { - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString("user.deleteUserSuccess", []) - ); - } - throw new HttpException( - this.helperService.formatReqMessagesString("user.userDeletionFailed", []), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - - async getGovAdminAndManagerUsers() { - const result = await this.userRepo - .createQueryBuilder("user") - .where("user.role in (:admin, :manager)", { - admin: Role.Admin, - manager: Role.Manager, - }) - .andWhere("user.companyRole= :companyRole", { - companyRole: CompanyRole.GOVERNMENT, - }) - .select(["user.name", "user.email"]) - .getRawMany(); - - return result; - - //return result.map((item) => {return item.user_email}); - } - - async getOrganisationAdminAndManagerUsers(organisationId) { - const result = await this.userRepo - .createQueryBuilder("user") - .where("user.role in (:admin,:manager)", { - admin: Role.Admin, - manager: Role.Manager, - }) - .andWhere("user.companyId= :companyId", { companyId: organisationId }) - .select(["user.name", "user.email"]) - .getRawMany(); - - return result; - } -} diff --git a/backend/services/src/shared/util/configurationSettings.service.ts b/backend/services/src/shared/util/configurationSettings.service.ts deleted file mode 100644 index f53b2b3b8..000000000 --- a/backend/services/src/shared/util/configurationSettings.service.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Repository } from "typeorm"; -import { BasicResponseDto } from "../dto/basic.response.dto"; -import { ConfigurationSettings } from "../entities/configuration.settings"; -import { ConfigurationSettingsType } from "../enum/configuration.settings.type.enum"; -import { HelperService } from "./helpers.service"; - -@Injectable() -export class ConfigurationSettingsService { - constructor( - @InjectRepository(ConfigurationSettings) - private configSettingsRepo: Repository, - private logger: Logger, - private helperService: HelperService - ) {} - - async getSetting(type: number, defaultValue?: string) { - return await this.configSettingsRepo - .findOneBy({ - id: type, - }) - .then(async (value) => { - if (value) return value.settingValue; - else { - return defaultValue; - } - }); - } - - async updateSetting(type: ConfigurationSettingsType, settingValue: any) { - const result = await this.configSettingsRepo - .upsert([{ id: type, settingValue: settingValue }], ["id"]) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - - if (result.identifiers) { - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString( - "common.settingsSavedMsg", - [] - ) - ); - } else { - throw new HttpException( - this.helperService.formatReqMessagesString( - "common.settingsSaveFailedMsg", - [] - ), - HttpStatus.INTERNAL_SERVER_ERROR - ); - } - } -} diff --git a/backend/services/src/shared/util/counter.service.spec.ts b/backend/services/src/shared/util/counter.service.spec.ts deleted file mode 100644 index 1c3fce9a8..000000000 --- a/backend/services/src/shared/util/counter.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { CounterService } from './counter.service'; - -describe('CounterService', () => { - let service: CounterService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [CounterService], - }).compile(); - - service = module.get(CounterService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/services/src/shared/util/counter.service.ts b/backend/services/src/shared/util/counter.service.ts deleted file mode 100644 index a0c31bbed..000000000 --- a/backend/services/src/shared/util/counter.service.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { Counter } from '../entities/counter.entity'; -import { CounterType } from './counter.type.enum'; - -@Injectable() -export class CounterService { - - constructor(@InjectRepository(Counter) private counterRepo: Repository) { - } - - padLeft(number: number, length: number, character: string = '0'): string { - let result = String(number); - for (let i = result.length; i < length; ++i) { - result = character + result; - } - return result; - }; - - async incrementCount(type: CounterType, length: number, increment: number = 1): Promise { - // const resp = await this.counterRepo.increment({ id: type }, "counter", increment) - // if (resp.affected <= 0) { - // throw Error("Unexpected behavior on counter increase") - // } - - const resp = await this.counterRepo - .createQueryBuilder() - .update() - .whereInIds(type) - .set({ counter: () => `counter + ${increment}` }) - .returning("counter") - .execute().catch( e => { - }); - if (resp && resp['raw'] && resp['raw'].length > 0) { - return this.padLeft(resp['raw'][0]['counter'], length); - } else { - return await this.counterRepo.findOneBy({ - id: type, - }).then(async o => { - if (o) { - throw Error('Internal error on unique id generation') - } else { - await this.counterRepo.save({ id: type, counter: 1 }) - return this.padLeft(1, length); - } - }); - } - } - - async getCount(type: CounterType): Promise { - return await this.counterRepo.findOneBy({ - id: type, - }).then(async o => { - if (o) { - return o.counter; - } else { - await this.counterRepo.save({ id: type, counter: 0 }) - return 0; - } - - }); - - } -} diff --git a/backend/services/src/shared/util/counter.type.enum.ts b/backend/services/src/shared/util/counter.type.enum.ts deleted file mode 100644 index b4dfafb45..000000000 --- a/backend/services/src/shared/util/counter.type.enum.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum CounterType { - USER = 0, - PROGRAMME = 1, - ITMO = 2, - COMPANY = 3, - REPLICATE_SEQ = 4, - REPLICATE_SEQ_COMP = 5, - ASYNC_OPERATIONS = 6 -} diff --git a/backend/services/src/shared/util/country.service.ts b/backend/services/src/shared/util/country.service.ts deleted file mode 100644 index 6675eea84..000000000 --- a/backend/services/src/shared/util/country.service.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { DataListResponseDto } from '../dto/data.list.response'; -import { QueryDto } from '../dto/query.dto'; -import { Country } from '../entities/country.entity'; -import { HelperService } from './helpers.service'; - -@Injectable() -export class CountryService { - constructor(@InjectRepository(Country) private countryRepo: Repository, private helperService: HelperService) { - } - - async insertCountry(country: Country) { - return this.countryRepo.save(country) - } - - async isValidCountry(alpha2: string) { - return (await this.countryRepo.findOneBy({ - alpha2: alpha2 - })) != null; - } - - async getCountryName(alpha2: string) { - return (await this.countryRepo.findOneBy({ - alpha2: alpha2 - }))?.name; - } - - async getCountryList(query: QueryDto) { - - const resp = await this.countryRepo - .createQueryBuilder() - .select([ - '"alpha2"', - '"name"' - ]) - .where( - this.helperService.generateWhereSQL( - query, - undefined - ) - ) - .orderBy(query?.sort?.key && `"${query?.sort?.key}"`, query?.sort?.order) - .offset(query.size * query.page - query.size) - .limit(query.size) - .getRawMany(); - - console.log(resp) - return new DataListResponseDto( - resp, - undefined - ); - } - - async getAvailableCountries() { - const resp = await this.countryRepo - .find({ - select:{ - name: true, - alpha2: true - } - }) - - return resp; - } -} diff --git a/backend/services/src/shared/util/helpers.service.ts b/backend/services/src/shared/util/helpers.service.ts deleted file mode 100644 index b6abb5a16..000000000 --- a/backend/services/src/shared/util/helpers.service.ts +++ /dev/null @@ -1,476 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import e from "express"; -import { QueryDto } from "../dto/query.dto"; -import { StatList } from "../dto/stat.list.dto"; -import { ProgrammeStage } from "../enum/programme-status.enum"; -import { Stat } from "../dto/stat.dto"; -import { programmeStatusRequestDto } from "../dto/programmeStatus.request.dto"; -import { chartStatsRequestDto } from "../dto/chartStats.request.dto"; -import { ConfigService } from "@nestjs/config"; -import { I18nService } from "nestjs-i18n"; - -@Injectable() -export class HelperService { - constructor( - private configService: ConfigService, - private i18n: I18nService - ) {} - - public isBase64(text: string): boolean { - return Buffer.from(text, 'base64').toString('base64') === text - } - - private prepareValue(value: any, table?: string, toLower?: boolean) { - if (value instanceof Array) { - return "(" + value.map((e) => `'${e}'`).join(",") + ")"; - } else if (this.isQueryDto(value)) { - return this.generateWhereSQL(value, undefined, table); - } else if (typeof value === "string") { - if (value === "NULL") { - return value; - } - if (toLower != true) { - return "'" + value + "'"; - } else { - return "LOWER('" + value + "')"; - } - } - return value; - } - - private prepareKey(col: string, table?: string) { - let key; - if (col.includes("->>")) { - const parts = col.split("->>"); - key = `"${parts[0]}"->>'${parts[1]}'`; - } else { - key = `"${col}"`; - } - return `${table ? table + "." : ""}${key}`; - } - - private isLower(key: string) { - if ( - [ - "email", - "name", - "companyName", - "taxId", - "country", - "title", - "externalId", - "serialNo", - "programmeTitle", - ].includes(key) - ) - return true; - } - - public generateSortCol(col: string) { - if (col.includes("->>")) { - const parts = col.split("->>"); - return `"${parts[0]}"->>'${parts[1]}'`; - } else if (col.includes("[")) { - const parts = col.split("["); - return `"${parts[0]}"[${parts[1]}`; - } else { - return `"${col}"`; - } - } - - public generateRandomPassword() { - var pass = ""; - var str = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789@$"; - - for (let i = 1; i <= 8; i++) { - var char = Math.floor(Math.random() * str.length + 1); - - pass += str.charAt(char); - } - - return pass; - } - - public formatReqMessagesString(langTag: string, vargs: any[]) { - const str: any = this.i18n.t(langTag); - const parts: any = str.split("{}"); - let insertAt = 1; - for (const arg of vargs) { - parts.splice(insertAt, 0, arg); - insertAt += 2; - } - return parts.join(""); - } - - public generateWhereSQLChartStastics( - data: chartStatsRequestDto, - extraSQL: string, - table?: string - ) { - let sql = ""; - let col = ""; - let colFilter = "createdTime"; - - if (data?.type === "TOTAL_PROGRAMS") { - col = "currentStage"; - sql = `${table ? table + "." : ""}"${colFilter}" > ${this.prepareValue( - data?.startDate - )} and ${table ? table + "." : ""}"${colFilter}" < ${this.prepareValue( - data?.endDate - )}`; - } else if (data?.type === "TOTAL_CREDITS_CERTIFIED") { - col = "certifierId"; - sql = `${table ? table + "." : ""}"${colFilter}" > ${this.prepareValue( - data?.startDate - )} and ${table ? table + "." : ""}"${colFilter}" < ${this.prepareValue( - data?.endDate - )}`; - } - - if (sql != "") { - if (data?.companyId !== "") { - let colCheck = "companyId"; - let companyId = data?.companyId; - sql = `(${sql}) and ${ - table ? table + "." : "" - }"${colCheck}" @> '{${companyId}}'`; - } - } else { - if (data?.companyId !== "") { - let colCheck = "companyId"; - let companyId = data?.companyId; - sql = `${table ? table + "." : ""}"${colCheck}" @> '{${companyId}}'`; - } - } - - if (sql != "") { - if (extraSQL) { - sql = `(${sql}) and (${extraSQL})`; - } - } else if (extraSQL) { - sql = extraSQL; - } - return sql; - } - - private isQueryDto(obj) { - if ( - obj && - typeof obj === "object" && - (obj["filterAnd"] || obj["filterOr"]) - ) { - return true; - } - return false; - } - - public generateWhereSQLChartStasticsWithoutTimeRange( - data: programmeStatusRequestDto, - extraSQL: string, - table?: string - ) { - let sql = ""; - let col = ""; - - if (data?.type === "TRANSFER_REQUEST_SENT") { - col = "fromCompanyId"; - sql = `${table ? table + "." : ""}"${col}" is not null`; - } else if (data?.type === "TRANSFER_REQUEST_RECEIVED") { - col = "toCompanyId"; - sql = `${table ? table + "." : ""}"${col}" is not null`; - } else if (data?.type === "PROGRAMS_CERTIFIED") { - col = "certifierId"; - sql = `${table ? table + "." : ""}"${col}" is not null`; - } else if (data?.type === "PROGRAMS_UNCERTIFIED") { - col = "certifierId"; - sql = `${table ? table + "." : ""}"${col}" is null`; - } - - if (sql != "") { - if (extraSQL) { - sql = `(${sql}) and (${extraSQL})`; - } - } else if (extraSQL) { - sql = extraSQL; - } - return sql; - } - - public generateWhereSQLStastics( - data: programmeStatusRequestDto, - extraSQL: string, - table?: string - ) { - let sql = ""; - let col = ""; - let colFilter = "createdTime"; - - if (data?.type === "PROGRAMS_BY_STATUS") { - col = "currentStage"; - sql = `${table ? table + "." : ""}"${col}" = ${this.prepareValue( - ProgrammeStage[data?.value] - )}`; - } else if (data?.type.includes("CREDIT_CERTIFIED")) { - col = "certifierId"; - sql = `${ - table ? table + "." : "" - }"${col}" is not null and "${col}" != '{}'`; - } else if (data?.type === "CREDIT_UNCERTIFIED") { - col = "certifierId"; - sql = `${table ? table + "." : ""}"${col}" is null`; - } else if (data?.type === "CREDIT_REVOKED") { - col = "certifierId"; - sql = `${table ? table + "." : ""}"${col}" = '{}'`; - } else if (data?.type === "CREDIT_STATS_FROZEN") { - } - - if ( - data?.startTime && - data?.endTime && - data?.type.includes("CREDIT_STATS") - ) { - sql = `${table ? table + "." : ""}"${colFilter}" > ${this.prepareValue( - data?.startTime - )} and ${table ? table + "." : ""}"${colFilter}" < ${this.prepareValue( - data?.endTime - )}`; - } else if (data?.startTime && data?.endTime) { - if (sql != "") { - sql = `(${sql}) and ${ - table ? table + "." : "" - }"${colFilter}" > ${this.prepareValue(data?.startTime)} and ${ - table ? table + "." : "" - }"${colFilter}" < ${this.prepareValue(data?.endTime)}`; - } else { - sql = `${table ? table + "." : ""}"${colFilter}" > ${this.prepareValue( - data?.startTime - )} and ${table ? table + "." : ""}"${colFilter}" < ${this.prepareValue( - data?.endTime - )}`; - } - } - - if (sql != "") { - if (data?.companyId !== "") { - let colCheck = "companyId"; - let companyId = data?.companyId; - sql = `(${sql}) and ${ - table ? table + "." : "" - }"${colCheck}" @> '{${companyId}}'`; - } - } else { - if (data?.companyId !== "") { - let colCheck = "companyId"; - let companyId = data?.companyId; - sql = `${table ? table + "." : ""}"${colCheck}" @> '{${companyId}}'`; - } - } - - if (sql != "") { - if (extraSQL) { - sql = `(${sql}) and (${extraSQL})`; - } - } else if (extraSQL) { - sql = extraSQL; - } - console.log(sql); - - return sql; - } - - public generateWhereSQL(query: QueryDto, extraSQL: string, table?: string, ignoreCol?: string[]) { - let sql = ""; - if (query.filterAnd) { - if (ignoreCol) { - query.filterAnd = query.filterAnd.filter(e=> (ignoreCol.indexOf(e.key) >= 0)) - } - sql += query.filterAnd - .map((e) => { - if (this.isQueryDto(e.value)) { - return `(${this.prepareValue(e.value, table)})`; - } else if (e.operation === "ANY") { - return `${this.prepareValue( - e.value, - table - )} = ANY(${this.prepareKey(e.key, table)})`; - } else if (e.keyOperation) { - return `${e.keyOperation}(${this.prepareKey(e.key, table)}) ${ - e.operation - } ${this.prepareValue(e.value, table, true)}`; - } else if (this.isLower(e.key) && typeof e.value === "string") { - return `LOWER(${this.prepareKey(e.key, table)}) ${ - e.operation - } ${this.prepareValue(e.value, table, true)}`; - } else { - return `${this.prepareKey(e.key, table)} ${ - e.operation - } ${this.prepareValue(e.value, table)}`; - } - }) - .join(" and "); - } - if (query.filterOr) { - if (ignoreCol) { - query.filterOr = query.filterOr.filter(e=> (ignoreCol.indexOf(e.key) >= 0)) - } - const orSQl = query.filterOr - .map((e) => { - if (this.isQueryDto(e.value)) { - return `(${this.prepareValue(e.value, table)})`; - } else if (e.operation === "ANY") { - return `${this.prepareValue( - e.value, - table - )} = ANY(${this.prepareKey(e.key, table)})`; - } else if (e.keyOperation) { - return `${e.keyOperation}(${this.prepareKey(e.key, table)}) ${ - e.operation - } ${this.prepareValue(e.value, table, true)}`; - } else if (this.isLower(e.key) && typeof e.value === "string") { - return `LOWER(${this.prepareKey(e.key, table)}) ${ - e.operation - } ${this.prepareValue(e.value, table, true)}`; - } else { - return `${this.prepareKey(e.key, table)} ${ - e.operation - } ${this.prepareValue(e.value, table)}`; - } - }) - .join(" or "); - if (sql != "") { - sql = `(${sql}) and (${orSQl})`; - } else { - sql = orSQl; - } - } - - if (sql != "") { - if (extraSQL) { - sql = `(${sql}) and (${extraSQL})`; - } - } else if (extraSQL) { - sql = extraSQL; - } - console.log(sql); - - return sql; - } - - public parseMongoQueryToSQL(mongoQuery, isNot = false, key = undefined) { - return this.parseMongoQueryToSQLWithTable( - undefined, - mongoQuery, - isNot, - key - ); - } - - public parseMongoQueryToSQLWithTable( - table, - mongoQuery, - isNot = false, - key = undefined - ) { - let final = undefined; - for (let operator in mongoQuery) { - if (operator.startsWith("$")) { - if (operator == "$and" || operator == "$or") { - const val = mongoQuery[operator] - .map((st) => this.parseMongoQueryToSQLWithTable(table, st)) - .join(` ${operator.replace("$", "")} `); - final = final == undefined ? val : `${final} and ${val}`; - } else if (operator == "$not") { - return this.parseMongoQueryToSQLWithTable( - table, - mongoQuery["$not"], - !isNot - ); - } else if (operator == "$eq") { - const value = - typeof mongoQuery["$eq"] === "number" - ? String(mongoQuery["$eq"]) - : `'${mongoQuery["$eq"]}'`; - return `${table ? table + "." : ""}"${key}" ${ - isNot ? "!=" : "=" - } ${value}`; - } else if (operator == "$ne") { - const value = - typeof mongoQuery["$ne"] === "number" - ? String(mongoQuery["$ne"]) - : `'${mongoQuery["$ne"]}'`; - return `${table ? table + "." : ""}"${key}" ${ - isNot ? "=" : "!=" - } ${value}`; - } else if (operator == "$in") { - const value = `('${mongoQuery["$in"].join("', '")}')`; - return `${table ? table + "." : ""}"${key}" ${ - isNot ? " NOT IN " : " IN " - } ${value}`; - } else if (operator == "$elemMatch") { - return `'${mongoQuery["$elemMatch"]["$eq"]}' ${ - isNot ? " <> ANY " : " =ANY " - }(${table ? table + "." : ""}"${key}")`; - } - } else { - return this.parseMongoQueryToSQLWithTable( - table, - mongoQuery[operator], - isNot, - operator - ); - } - } - return final; - } - - public getEmailTemplateMessage(template: string, data, isSubject: boolean) :string{ - if (template == undefined) { - return template; - } - for (const key in data) { - if (data.hasOwnProperty(key)) { - var find = `{{${key}}}`; - var re = new RegExp(find, 'g'); - template = template.replace(re, data[key]); - } - } - - if(isSubject) - return `🏭📋 🇦🇶 Carbon Registry: ${template}`; - else - return template; -} - - // public async uploadCompanyLogoS3(companyId: number, companyLogo: string) { - // var AWS = require("aws-sdk"); - // const s3 = new AWS.S3(); - // const imgBuffer = Buffer.from(companyLogo, "base64"); - // var uploadParams = { - // Bucket: this.configService.get("s3CommonBucket.name"), - // Key: "", - // Body: imgBuffer, - // ContentEncoding: "base64", - // ContentType: "image/png", - // }; - - // uploadParams.Key = `profile_images/${companyId}_${new Date().getTime()}.png`; - - // return await s3 - // .upload(uploadParams, function (err, data) { - // if (err) { - // return { - // status: false, - // statusText: err, - // }; - // } - // if (data) { - // return { - // status: true, - // statusText: data.Location, - // }; - // } - // }) - // .promise(); - // } -} diff --git a/backend/services/src/shared/util/mutualexclusive.decorator.ts b/backend/services/src/shared/util/mutualexclusive.decorator.ts deleted file mode 100644 index 0d8ec7e00..000000000 --- a/backend/services/src/shared/util/mutualexclusive.decorator.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {registerDecorator, ValidationOptions, ValidationArguments} from "class-validator"; - -const META_KEY = (tag) => `custom:__@rst/validator_mutually_exclusive_${tag}__`; - -export default function MutuallyExclusive(tag: string = 'default', validationOptions?: ValidationOptions) { - return function (object: Object, propertyName: string) { - const key = META_KEY(tag); - const existing = Reflect.getMetadata(key, object) || []; - - Reflect.defineMetadata(key, [...existing, propertyName], object); - - registerDecorator({ - name: "MutuallyExclusive", - target: object.constructor, - propertyName: propertyName, - constraints: [tag], - options: validationOptions, - validator: { - validate(value: any, args: ValidationArguments) { - const mutuallyExclusiveProps: Array = Reflect.getMetadata(key, args.object); - return mutuallyExclusiveProps.reduce((p, c) => args.object[c] !== undefined ? ++p : p, 0) === 1; - }, - defaultMessage(validationArguments?: ValidationArguments) { - const mutuallyExclusiveProps: Array = Reflect.getMetadata(key, validationArguments.object); - return `Following properties are mutually exclusive: ${mutuallyExclusiveProps.join(', ')}`; - } - } - }); - }; -} \ No newline at end of file diff --git a/backend/services/src/shared/util/passwordReset.service.ts b/backend/services/src/shared/util/passwordReset.service.ts deleted file mode 100644 index bfb2b37d5..000000000 --- a/backend/services/src/shared/util/passwordReset.service.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { HttpException, HttpStatus, Injectable, Logger } from "@nestjs/common"; -import { InjectRepository } from "@nestjs/typeorm"; -import { Repository } from "typeorm"; -import { DataListResponseDto } from "../dto/data.list.response"; -import { QueryDto } from "../dto/query.dto"; -import { Country } from "../entities/country.entity"; -import { HelperService } from "./helpers.service"; -import { PasswordReset } from "../entities/userPasswordResetToken.entity"; -import { PasswordResetDto } from "../dto/passwordReset.dto"; -import { User } from "../entities/user.entity"; -import { BasicResponseDto } from "../dto/basic.response.dto"; -import { ConfigService } from "@nestjs/config"; -import { AsyncAction, AsyncOperationsInterface } from "../async-operations/async-operations.interface"; -import { AsyncActionType } from "../enum/async.action.type.enum"; -import { EmailTemplates } from "../email-helper/email.template"; - -@Injectable() -export class PasswordResetService { - constructor( - @InjectRepository(PasswordReset) - private passwordResetRepo: Repository, - @InjectRepository(User) private userRepo: Repository, - private helperService: HelperService, - private configService: ConfigService, - private logger: Logger, - private asyncOperationsInterface: AsyncOperationsInterface, - ) {} - - async insertPasswordResetD(passwordResetD) { - await this.passwordResetRepo.save(passwordResetD); - } - - async deletePasswordResetD(email) { - await this.passwordResetRepo.delete({ email: email }); - } - - async resetPassword( - reqId: string, - passwordResetDto: PasswordResetDto, - abilityCondition: string - ) { - const passwordResetD = await this.passwordResetRepo.findBy({ - token: reqId, - }); - if (!(passwordResetD.length > 0)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.resetPasswordReqNotFound", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - const currentDate = Date.now(); - const tokenExpiryTime = passwordResetD[0].expireTime; - const id = passwordResetD[0].id; - const email = passwordResetD[0].email; - const userD = await this.userRepo.findBy({ - email: email, - }); - if (!(userD.length > 0)) { - throw new HttpException( - this.helperService.formatReqMessagesString("user.noUserFound", []), - HttpStatus.EXPECTATION_FAILED - ); - } - const userId = userD[0].id; - const userName = userD[0].name; - if (currentDate > tokenExpiryTime) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.resetPasswordReqExpired", - [] - ), - HttpStatus.EXPECTATION_FAILED - ); - } - const result = await this.userRepo - .update( - { - id: userId, - }, - { - password: passwordResetDto.newPassword, - } - ) - .catch((err: any) => { - this.logger.error(err); - return err; - }); - if (result.affected > 0) { - const templateData = { - name: userName, - countryName: this.configService.get("systemCountryName"), - } - - const action: AsyncAction = { - actionType: AsyncActionType.Email, - actionProps: { - emailType: EmailTemplates.CHANGE_PASSOWRD.id, - sender: email, - subject: this.helperService.getEmailTemplateMessage( - EmailTemplates.CHANGE_PASSOWRD["subject"], - templateData, - true - ), - emailBody: this.helperService.getEmailTemplateMessage( - EmailTemplates.CHANGE_PASSOWRD["html"], - templateData, - false - ), - }, - }; - await this.asyncOperationsInterface.AddAction(action); - - this.passwordResetRepo.delete({ email: email }); - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString("user.resetSuccess", []) - ); - } - } - - async checkPasswordResetRequestId(reqId: string, abilityCondition: string) { - const passwordResetD = await this.passwordResetRepo.findBy({ - token: reqId, - }); - if (!(passwordResetD.length > 0)) { - throw new HttpException( - this.helperService.formatReqMessagesString( - "user.resetPasswordReqNotFound", - [] - ), - HttpStatus.BAD_REQUEST - ); - } - return new BasicResponseDto( - HttpStatus.OK, - this.helperService.formatReqMessagesString("user.reqIdFound", []) - ); - } -} diff --git a/backend/services/src/shared/util/util.module.ts b/backend/services/src/shared/util/util.module.ts deleted file mode 100644 index 9307eda2a..000000000 --- a/backend/services/src/shared/util/util.module.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { forwardRef, Logger, Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { AcceptLanguageResolver, I18nModule, QueryResolver } from "nestjs-i18n"; -import * as path from "path"; -import { TypeOrmModule } from "@nestjs/typeorm"; -import configuration from "../configuration"; -import { Counter } from "../entities/counter.entity"; -import { Country } from "../entities/country.entity"; -import { TypeOrmConfigService } from "../typeorm.config.service"; -import { CounterService } from "./counter.service"; -import { CountryService } from "./country.service"; -import { HelperService } from "./helpers.service"; -import { IsValidCountryConstraint } from "./validcountry.decorator"; -import { PasswordReset } from "../entities/userPasswordResetToken.entity"; -import { PasswordResetService } from "./passwordReset.service"; -import { User } from "../entities/user.entity"; -import { UserModule } from "../user/user.module"; -import { AsyncOperationsModule } from "../async-operations/async-operations.module"; -import { ConfigurationSettingsService } from "./configurationSettings.service"; -import { ConfigurationSettings } from "../entities/configuration.settings"; - -@Module({ - imports: [ - ConfigModule.forRoot({ - isGlobal: true, - load: [configuration], - envFilePath: [`.env.${process.env.NODE_ENV}`, `.env`], - }), - TypeOrmModule.forRootAsync({ - useClass: TypeOrmConfigService, - imports: undefined, - }), - I18nModule.forRoot({ - fallbackLanguage: "en", - loaderOptions: { - path: path.join(__dirname, "../../i18n/"), - watch: true, - }, - resolvers: [ - { use: QueryResolver, options: ["lang"] }, - AcceptLanguageResolver, - ], - }), - TypeOrmModule.forFeature([ - Counter, - Country, - PasswordReset, - User, - ConfigurationSettings, - ]), - forwardRef(() => AsyncOperationsModule), - ], - providers: [ - CounterService, - CountryService, - IsValidCountryConstraint, - HelperService, - PasswordResetService, - Logger, - ConfigurationSettingsService, - ], - exports: [ - CounterService, - CountryService, - HelperService, - PasswordResetService, - ConfigurationSettingsService, - ], -}) -export class UtilModule {} diff --git a/backend/services/src/shared/util/validcountry.decorator.ts b/backend/services/src/shared/util/validcountry.decorator.ts deleted file mode 100644 index b44c3ae2c..000000000 --- a/backend/services/src/shared/util/validcountry.decorator.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Injectable } from "@nestjs/common"; -import { - ValidatorConstraint, - ValidatorConstraintInterface, - ValidationArguments, - ValidationOptions, - registerDecorator, -} from "class-validator"; -import { CountryService } from "./country.service"; - -@ValidatorConstraint({ name: "isValidCountry", async: true }) -@Injectable() -export class IsValidCountryConstraint implements ValidatorConstraintInterface { - defaultMessage(): string { - return "Country is invalid"; - } - constructor(protected readonly countryService: CountryService) {} - - validate(alpha2Code: any, args: ValidationArguments) { - return this.countryService.isValidCountry(alpha2Code); - } -} - -export function IsValidCountry(validationOptions?: ValidationOptions) { - return function (object: Object, propertyName: string) { - registerDecorator({ - target: object.constructor, - propertyName: propertyName, - options: validationOptions, - constraints: [], - validator: IsValidCountryConstraint, - }); - }; -} diff --git a/backend/services/src/shared/validation/trim-pipe.transform.ts b/backend/services/src/shared/validation/trim-pipe.transform.ts deleted file mode 100644 index 8cd3a69ce..000000000 --- a/backend/services/src/shared/validation/trim-pipe.transform.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - Injectable, PipeTransform, - ArgumentMetadata, BadRequestException -} from '@nestjs/common' - -@Injectable() -export class TrimPipe implements PipeTransform { - private isObj(obj: any): boolean { - return typeof obj === 'object' && obj !== null - } - - private trim(values) { - Object.keys(values).forEach(key => { - if (key !== 'password') { - if (this.isObj(values[key])) { - values[key] = this.trim(values[key]) - } else { - if (typeof values[key] === 'string') { - values[key] = values[key].trim() - } - } - } - }) - return values - } - - transform(values: any, metadata: ArgumentMetadata) { - const { type } = metadata - if (this.isObj(values) && type === 'body') { - return this.trim(values) - } - - return values; - } -} \ No newline at end of file diff --git a/backend/services/src/shared/validation/validation-exception.filter.ts b/backend/services/src/shared/validation/validation-exception.filter.ts deleted file mode 100644 index 82cad580b..000000000 --- a/backend/services/src/shared/validation/validation-exception.filter.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { - ExceptionFilter, - Catch, - ArgumentsHost, - BadRequestException, -} from "@nestjs/common"; -import { Request, Response } from "express"; -import { ValidationException } from "./validation.exception"; - -@Catch(ValidationException) -export class ValidationExceptionFilter implements ExceptionFilter { - catch(exception: ValidationException, host: ArgumentsHost) { - const ctx = host.switchToHttp(); - const response = ctx.getResponse(); - const baseException = new BadRequestException(); - - let message = "Bad request"; - - const errorsHandler = (error) => { - const eMsgs = Object.values(error.constraints); - let isEmpty = false; - let isInvalidRole = false; - let isCompanyIdNotNumber = false; - eMsgs?.map((error: any) => { - if (error.includes("empty")) { - isEmpty = true; - } - if (error.includes("Invalid role")) { - isInvalidRole = true; - } - if (error.includes("companyId must be a number")) { - isCompanyIdNotNumber = true; - } - }); - const propertyNameCap = - error.property.charAt(0).toUpperCase() + error.property.slice(1); - if (isEmpty) { - return [`${propertyNameCap} is required`]; - } else { - if (String(error.property) === "email") { - return ["Email is invalid"]; - } else { - return isInvalidRole ? [`${propertyNameCap} is invalid`] : eMsgs; - } - } - }; - - console.log(JSON.stringify(exception)); - // Custom exception handling, to provide rich error message - if ( - exception.errors.length == 2 && - exception.errors[0].constraints && - exception.errors[1].constraints && - exception.errors.filter((e) => !!e.constraints["isNotEmpty"]).length == 2 - ) { - message = - exception.errors.map((e) => e.property).join(" and ") + - " should not be empty"; - } else if (exception.errors.length > 0 && exception.errors[0].constraints) { - const erList = Object.values(exception.errors[0].constraints); - if (erList.length > 0) { - message = "Bad request"; - } - } - - response.status(baseException.getStatus()).json({ - statusCode: baseException.getStatus(), - message: message, - errors: exception.errors.map((error) => { - let resp = {}; - if (error.constraints) { - resp = { - [error.property]: errorsHandler(error), - }; - } - if (error.children) { - error.children.forEach((er_child) => { - if (er_child.constraints) { - resp[error.property + "." + er_child.property] = - errorsHandler(er_child); - } - }); - } - return resp; - }), - }); - } -} diff --git a/backend/services/src/shared/validation/validation.exception.ts b/backend/services/src/shared/validation/validation.exception.ts deleted file mode 100644 index af8c99aaf..000000000 --- a/backend/services/src/shared/validation/validation.exception.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ValidationError } from '@nestjs/common'; - -export class ValidationException { - constructor(public errors: ValidationError[]) {} -} \ No newline at end of file diff --git a/backend/services/src/shared/validation/validation.module.ts b/backend/services/src/shared/validation/validation.module.ts deleted file mode 100644 index d6f7d2af1..000000000 --- a/backend/services/src/shared/validation/validation.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TrimPipe } from './trim-pipe.transform'; - -@Module({ - providers: [TrimPipe], - exports: [TrimPipe] -}) -export class ValidationModule {} diff --git a/backend/services/yarn.lock b/backend/services/yarn.lock index 8483a7819..a10277a69 100644 --- a/backend/services/yarn.lock +++ b/backend/services/yarn.lock @@ -61,6 +61,15 @@ "@aws-sdk/types" "^3.222.0" tslib "^1.11.1" +"@aws-crypto/crc32c@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz#016c92da559ef638a84a245eecb75c3e97cb664f" + integrity sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + "@aws-crypto/ie11-detection@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688" @@ -68,6 +77,19 @@ dependencies: tslib "^1.11.1" +"@aws-crypto/sha1-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz#f9083c00782b24714f528b1a1fef2174002266a3" + integrity sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + "@aws-crypto/sha256-browser@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz#05f160138ab893f1c6ba5be57cfd108f05827766" @@ -168,7 +190,7 @@ "@aws-sdk/util-waiter" "3.329.0" tslib "^2.5.0" -"@aws-sdk/client-qldb-session@^3.195.0", "@aws-sdk/client-qldb-session@^3.204.0": +"@aws-sdk/client-qldb-session@^3.195.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-qldb-session/-/client-qldb-session-3.306.0.tgz#56c38d62b385b7fcaef24b506a3c9156c700f2ad" integrity sha512-Tvdnmk2DxTCJM4NQiE2uD0VijTtfLxGHUr2Rs7WtXwZMlfQnIJ+xp8ItHmU2nHzEvzTCbLeoTDj6AtOkoimShQ== @@ -209,45 +231,195 @@ "@aws-sdk/util-utf8" "3.303.0" tslib "^2.5.0" -"@aws-sdk/client-qldb@^3.209.0": - version "3.306.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-qldb/-/client-qldb-3.306.0.tgz#53a4f4e5e56b854e951318e5ce6708add274d29b" - integrity sha512-ogznhrXGMYPPZ5EJ4JQMN/B4Mqh9fUsh8uDO3v2H/lvHzKFsMVmXSrwceHJ7dvG0ylKoyg50aTzwEQEPqrMvcw== +"@aws-sdk/client-qldb-session@^3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-qldb-session/-/client-qldb-session-3.408.0.tgz#54f4bd68942f81761ecbb9077081c7bea246efbf" + integrity sha512-jVrfHE3oySJwGsH7JvRDdAFhIrPDCQizsi9TArK+3L/7/XeG4FESXx3/8wWsPkyweHGXo/ARQJDBn+U6kIe49Q== dependencies: "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/client-sts" "3.306.0" - "@aws-sdk/config-resolver" "3.306.0" - "@aws-sdk/credential-provider-node" "3.306.0" - "@aws-sdk/fetch-http-handler" "3.306.0" - "@aws-sdk/hash-node" "3.306.0" - "@aws-sdk/invalid-dependency" "3.306.0" - "@aws-sdk/middleware-content-length" "3.306.0" - "@aws-sdk/middleware-endpoint" "3.306.0" - "@aws-sdk/middleware-host-header" "3.306.0" - "@aws-sdk/middleware-logger" "3.306.0" - "@aws-sdk/middleware-recursion-detection" "3.306.0" - "@aws-sdk/middleware-retry" "3.306.0" - "@aws-sdk/middleware-serde" "3.306.0" - "@aws-sdk/middleware-signing" "3.306.0" - "@aws-sdk/middleware-stack" "3.306.0" - "@aws-sdk/middleware-user-agent" "3.306.0" - "@aws-sdk/node-config-provider" "3.306.0" - "@aws-sdk/node-http-handler" "3.306.0" - "@aws-sdk/protocol-http" "3.306.0" - "@aws-sdk/smithy-client" "3.306.0" - "@aws-sdk/types" "3.306.0" - "@aws-sdk/url-parser" "3.306.0" - "@aws-sdk/util-base64" "3.303.0" - "@aws-sdk/util-body-length-browser" "3.303.0" - "@aws-sdk/util-body-length-node" "3.303.0" - "@aws-sdk/util-defaults-mode-browser" "3.306.0" - "@aws-sdk/util-defaults-mode-node" "3.306.0" - "@aws-sdk/util-endpoints" "3.306.0" - "@aws-sdk/util-retry" "3.306.0" - "@aws-sdk/util-user-agent-browser" "3.306.0" - "@aws-sdk/util-user-agent-node" "3.306.0" - "@aws-sdk/util-utf8" "3.303.0" + "@aws-sdk/client-sts" "3.408.0" + "@aws-sdk/credential-provider-node" "3.408.0" + "@aws-sdk/middleware-host-header" "3.408.0" + "@aws-sdk/middleware-logger" "3.408.0" + "@aws-sdk/middleware-recursion-detection" "3.408.0" + "@aws-sdk/middleware-signing" "3.408.0" + "@aws-sdk/middleware-user-agent" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@aws-sdk/util-endpoints" "3.408.0" + "@aws-sdk/util-user-agent-browser" "3.408.0" + "@aws-sdk/util-user-agent-node" "3.408.0" + "@smithy/config-resolver" "^2.0.5" + "@smithy/fetch-http-handler" "^2.0.5" + "@smithy/hash-node" "^2.0.5" + "@smithy/invalid-dependency" "^2.0.5" + "@smithy/middleware-content-length" "^2.0.5" + "@smithy/middleware-endpoint" "^2.0.5" + "@smithy/middleware-retry" "^2.0.5" + "@smithy/middleware-serde" "^2.0.5" + "@smithy/middleware-stack" "^2.0.0" + "@smithy/node-config-provider" "^2.0.6" + "@smithy/node-http-handler" "^2.0.5" + "@smithy/protocol-http" "^2.0.5" + "@smithy/smithy-client" "^2.0.5" + "@smithy/types" "^2.2.2" + "@smithy/url-parser" "^2.0.5" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.6" + "@smithy/util-defaults-mode-node" "^2.0.6" + "@smithy/util-retry" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@aws-sdk/client-qldb@^3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-qldb/-/client-qldb-3.408.0.tgz#4b150c985d9d87b0d01d83e3e3f0693e685fe759" + integrity sha512-Yyl80wMTye1r7Q1YJmepOWV1hBoL4f3J+nvjQgulKTX/S66fkjrsaEkM3/5irNpwSzmOKZMb8QBs0D1vq+r8WA== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.408.0" + "@aws-sdk/credential-provider-node" "3.408.0" + "@aws-sdk/middleware-host-header" "3.408.0" + "@aws-sdk/middleware-logger" "3.408.0" + "@aws-sdk/middleware-recursion-detection" "3.408.0" + "@aws-sdk/middleware-signing" "3.408.0" + "@aws-sdk/middleware-user-agent" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@aws-sdk/util-endpoints" "3.408.0" + "@aws-sdk/util-user-agent-browser" "3.408.0" + "@aws-sdk/util-user-agent-node" "3.408.0" + "@smithy/config-resolver" "^2.0.5" + "@smithy/fetch-http-handler" "^2.0.5" + "@smithy/hash-node" "^2.0.5" + "@smithy/invalid-dependency" "^2.0.5" + "@smithy/middleware-content-length" "^2.0.5" + "@smithy/middleware-endpoint" "^2.0.5" + "@smithy/middleware-retry" "^2.0.5" + "@smithy/middleware-serde" "^2.0.5" + "@smithy/middleware-stack" "^2.0.0" + "@smithy/node-config-provider" "^2.0.6" + "@smithy/node-http-handler" "^2.0.5" + "@smithy/protocol-http" "^2.0.5" + "@smithy/smithy-client" "^2.0.5" + "@smithy/types" "^2.2.2" + "@smithy/url-parser" "^2.0.5" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.6" + "@smithy/util-defaults-mode-node" "^2.0.6" + "@smithy/util-retry" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@aws-sdk/client-s3@^3.408.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.425.0.tgz#66cb97b88ee3ffb0c448a612bd27e484ace0d2a5" + integrity sha512-swuBTVIKvZPYSeksC8GNSeNkshzbBXhNAnzMW4JDcOnjMF0YXuHlCNwaPaVewP2D/ap2Ozlh9GIjF4EfgdTyvQ== + dependencies: + "@aws-crypto/sha1-browser" "3.0.0" + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.425.0" + "@aws-sdk/credential-provider-node" "3.425.0" + "@aws-sdk/middleware-bucket-endpoint" "3.425.0" + "@aws-sdk/middleware-expect-continue" "3.425.0" + "@aws-sdk/middleware-flexible-checksums" "3.425.0" + "@aws-sdk/middleware-host-header" "3.425.0" + "@aws-sdk/middleware-location-constraint" "3.425.0" + "@aws-sdk/middleware-logger" "3.425.0" + "@aws-sdk/middleware-recursion-detection" "3.425.0" + "@aws-sdk/middleware-sdk-s3" "3.425.0" + "@aws-sdk/middleware-signing" "3.425.0" + "@aws-sdk/middleware-ssec" "3.425.0" + "@aws-sdk/middleware-user-agent" "3.425.0" + "@aws-sdk/region-config-resolver" "3.425.0" + "@aws-sdk/signature-v4-multi-region" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-endpoints" "3.425.0" + "@aws-sdk/util-user-agent-browser" "3.425.0" + "@aws-sdk/util-user-agent-node" "3.425.0" + "@aws-sdk/xml-builder" "3.310.0" + "@smithy/config-resolver" "^2.0.11" + "@smithy/eventstream-serde-browser" "^2.0.10" + "@smithy/eventstream-serde-config-resolver" "^2.0.10" + "@smithy/eventstream-serde-node" "^2.0.10" + "@smithy/fetch-http-handler" "^2.2.1" + "@smithy/hash-blob-browser" "^2.0.10" + "@smithy/hash-node" "^2.0.10" + "@smithy/hash-stream-node" "^2.0.10" + "@smithy/invalid-dependency" "^2.0.10" + "@smithy/md5-js" "^2.0.10" + "@smithy/middleware-content-length" "^2.0.12" + "@smithy/middleware-endpoint" "^2.0.10" + "@smithy/middleware-retry" "^2.0.13" + "@smithy/middleware-serde" "^2.0.10" + "@smithy/middleware-stack" "^2.0.4" + "@smithy/node-config-provider" "^2.0.13" + "@smithy/node-http-handler" "^2.1.6" + "@smithy/protocol-http" "^3.0.6" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + "@smithy/url-parser" "^2.0.10" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.13" + "@smithy/util-defaults-mode-node" "^2.0.15" + "@smithy/util-retry" "^2.0.3" + "@smithy/util-stream" "^2.0.14" + "@smithy/util-utf8" "^2.0.0" + "@smithy/util-waiter" "^2.0.10" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + +"@aws-sdk/client-sqs@^3.408.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sqs/-/client-sqs-3.425.0.tgz#68f357c12918b243f44fe1c24f83aa3aec39628e" + integrity sha512-ndaxdLn2CL0+zddBgDvgbQIVyf3DjYEzp3rw6mEDJ1M8FdpHZhN61h9rME0vuog3wsJgLbGEa3tco9RKiQlCLw== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.425.0" + "@aws-sdk/credential-provider-node" "3.425.0" + "@aws-sdk/middleware-host-header" "3.425.0" + "@aws-sdk/middleware-logger" "3.425.0" + "@aws-sdk/middleware-recursion-detection" "3.425.0" + "@aws-sdk/middleware-sdk-sqs" "3.425.0" + "@aws-sdk/middleware-signing" "3.425.0" + "@aws-sdk/middleware-user-agent" "3.425.0" + "@aws-sdk/region-config-resolver" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-endpoints" "3.425.0" + "@aws-sdk/util-user-agent-browser" "3.425.0" + "@aws-sdk/util-user-agent-node" "3.425.0" + "@smithy/config-resolver" "^2.0.11" + "@smithy/fetch-http-handler" "^2.2.1" + "@smithy/hash-node" "^2.0.10" + "@smithy/invalid-dependency" "^2.0.10" + "@smithy/md5-js" "^2.0.10" + "@smithy/middleware-content-length" "^2.0.12" + "@smithy/middleware-endpoint" "^2.0.10" + "@smithy/middleware-retry" "^2.0.13" + "@smithy/middleware-serde" "^2.0.10" + "@smithy/middleware-stack" "^2.0.4" + "@smithy/node-config-provider" "^2.0.13" + "@smithy/node-http-handler" "^2.1.6" + "@smithy/protocol-http" "^3.0.6" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + "@smithy/url-parser" "^2.0.10" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.13" + "@smithy/util-defaults-mode-node" "^2.0.15" + "@smithy/util-retry" "^2.0.3" + "@smithy/util-utf8" "^2.0.0" + fast-xml-parser "4.2.5" tslib "^2.5.0" "@aws-sdk/client-sso-oidc@3.306.0": @@ -402,6 +574,85 @@ "@aws-sdk/util-utf8" "3.310.0" tslib "^2.5.0" +"@aws-sdk/client-sso@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.408.0.tgz#f6e8e9b5bc86713e3baba79d0c122d4c9cc5cc82" + integrity sha512-g0Y904ghLTg9JLJnmbuvf10Hrzwqn2pko6aCAK10vCI5Y2nQ6BAUXuPonxhZIlp+JHsk0B2FUBqquc+bErUspA== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/middleware-host-header" "3.408.0" + "@aws-sdk/middleware-logger" "3.408.0" + "@aws-sdk/middleware-recursion-detection" "3.408.0" + "@aws-sdk/middleware-user-agent" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@aws-sdk/util-endpoints" "3.408.0" + "@aws-sdk/util-user-agent-browser" "3.408.0" + "@aws-sdk/util-user-agent-node" "3.408.0" + "@smithy/config-resolver" "^2.0.5" + "@smithy/fetch-http-handler" "^2.0.5" + "@smithy/hash-node" "^2.0.5" + "@smithy/invalid-dependency" "^2.0.5" + "@smithy/middleware-content-length" "^2.0.5" + "@smithy/middleware-endpoint" "^2.0.5" + "@smithy/middleware-retry" "^2.0.5" + "@smithy/middleware-serde" "^2.0.5" + "@smithy/middleware-stack" "^2.0.0" + "@smithy/node-config-provider" "^2.0.6" + "@smithy/node-http-handler" "^2.0.5" + "@smithy/protocol-http" "^2.0.5" + "@smithy/smithy-client" "^2.0.5" + "@smithy/types" "^2.2.2" + "@smithy/url-parser" "^2.0.5" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.6" + "@smithy/util-defaults-mode-node" "^2.0.6" + "@smithy/util-retry" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@aws-sdk/client-sso@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.425.0.tgz#1d1fd056d3b611e7ad0babe6a3682183b70e11bb" + integrity sha512-kdBStHoVznez8chM/pMNYyk1jKUcPEb8og6U2FpNcmbOCppOjGX4PKlMn5EVurkhzXferUvHrr/oXK2d03w6+Q== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/middleware-host-header" "3.425.0" + "@aws-sdk/middleware-logger" "3.425.0" + "@aws-sdk/middleware-recursion-detection" "3.425.0" + "@aws-sdk/middleware-user-agent" "3.425.0" + "@aws-sdk/region-config-resolver" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-endpoints" "3.425.0" + "@aws-sdk/util-user-agent-browser" "3.425.0" + "@aws-sdk/util-user-agent-node" "3.425.0" + "@smithy/config-resolver" "^2.0.11" + "@smithy/fetch-http-handler" "^2.2.1" + "@smithy/hash-node" "^2.0.10" + "@smithy/invalid-dependency" "^2.0.10" + "@smithy/middleware-content-length" "^2.0.12" + "@smithy/middleware-endpoint" "^2.0.10" + "@smithy/middleware-retry" "^2.0.13" + "@smithy/middleware-serde" "^2.0.10" + "@smithy/middleware-stack" "^2.0.4" + "@smithy/node-config-provider" "^2.0.13" + "@smithy/node-http-handler" "^2.1.6" + "@smithy/protocol-http" "^3.0.6" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + "@smithy/url-parser" "^2.0.10" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.13" + "@smithy/util-defaults-mode-node" "^2.0.15" + "@smithy/util-retry" "^2.0.3" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + "@aws-sdk/client-sts@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.306.0.tgz#b68616833291fbe0e9354572f0934a1b023a1a79" @@ -486,6 +737,93 @@ fast-xml-parser "4.1.2" tslib "^2.5.0" +"@aws-sdk/client-sts@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.408.0.tgz#527d5b143913e9b1736be20f90938924a910545a" + integrity sha512-PpNmhCuFjVrgGBy00RVh3evBxzFfvUrALDqpBnPYhz489Qzg2I+T90FqdSUedPQPYe+qhq0YJMPKc9leYBEB/w== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/credential-provider-node" "3.408.0" + "@aws-sdk/middleware-host-header" "3.408.0" + "@aws-sdk/middleware-logger" "3.408.0" + "@aws-sdk/middleware-recursion-detection" "3.408.0" + "@aws-sdk/middleware-sdk-sts" "3.408.0" + "@aws-sdk/middleware-signing" "3.408.0" + "@aws-sdk/middleware-user-agent" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@aws-sdk/util-endpoints" "3.408.0" + "@aws-sdk/util-user-agent-browser" "3.408.0" + "@aws-sdk/util-user-agent-node" "3.408.0" + "@smithy/config-resolver" "^2.0.5" + "@smithy/fetch-http-handler" "^2.0.5" + "@smithy/hash-node" "^2.0.5" + "@smithy/invalid-dependency" "^2.0.5" + "@smithy/middleware-content-length" "^2.0.5" + "@smithy/middleware-endpoint" "^2.0.5" + "@smithy/middleware-retry" "^2.0.5" + "@smithy/middleware-serde" "^2.0.5" + "@smithy/middleware-stack" "^2.0.0" + "@smithy/node-config-provider" "^2.0.6" + "@smithy/node-http-handler" "^2.0.5" + "@smithy/protocol-http" "^2.0.5" + "@smithy/smithy-client" "^2.0.5" + "@smithy/types" "^2.2.2" + "@smithy/url-parser" "^2.0.5" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.6" + "@smithy/util-defaults-mode-node" "^2.0.6" + "@smithy/util-retry" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + +"@aws-sdk/client-sts@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.425.0.tgz#51b04533a787a69f70fc63daba4769577491be80" + integrity sha512-+UeyIdXExYkyxhmQxiBPW5er2e9OaESdUtVvnaUEoOSYHObwq5ywpM75sFihnzEwwAApxua/y2nQstSIf30aCA== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/credential-provider-node" "3.425.0" + "@aws-sdk/middleware-host-header" "3.425.0" + "@aws-sdk/middleware-logger" "3.425.0" + "@aws-sdk/middleware-recursion-detection" "3.425.0" + "@aws-sdk/middleware-sdk-sts" "3.425.0" + "@aws-sdk/middleware-signing" "3.425.0" + "@aws-sdk/middleware-user-agent" "3.425.0" + "@aws-sdk/region-config-resolver" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-endpoints" "3.425.0" + "@aws-sdk/util-user-agent-browser" "3.425.0" + "@aws-sdk/util-user-agent-node" "3.425.0" + "@smithy/config-resolver" "^2.0.11" + "@smithy/fetch-http-handler" "^2.2.1" + "@smithy/hash-node" "^2.0.10" + "@smithy/invalid-dependency" "^2.0.10" + "@smithy/middleware-content-length" "^2.0.12" + "@smithy/middleware-endpoint" "^2.0.10" + "@smithy/middleware-retry" "^2.0.13" + "@smithy/middleware-serde" "^2.0.10" + "@smithy/middleware-stack" "^2.0.4" + "@smithy/node-config-provider" "^2.0.13" + "@smithy/node-http-handler" "^2.1.6" + "@smithy/protocol-http" "^3.0.6" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + "@smithy/url-parser" "^2.0.10" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.13" + "@smithy/util-defaults-mode-node" "^2.0.15" + "@smithy/util-retry" "^2.0.3" + "@smithy/util-utf8" "^2.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + "@aws-sdk/config-resolver@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.306.0.tgz#e04d9ccd2a4ca2e189f164cf3d4b2ebc5658ca90" @@ -524,6 +862,26 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/credential-provider-env@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.408.0.tgz#199a793e5477e30417f6be9f82aa0262ba96328e" + integrity sha512-GCpgHEHxRTzKaMkwDC2gLb3xlD+ZxhKPUJ1DVcO7I9E3eCGJsYVedIi0/2XE+NP+HVoy8LyW2qH8QQWh64JKow== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-env@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.425.0.tgz#1f5be812aeed558efaebce641e4c030b86875544" + integrity sha512-J20etnLvMKXRVi5FK4F8yOCNm2RTaQn5psQTGdDEPWJNGxohcSpzzls8U2KcMyUJ+vItlrThr4qwgpHG3i/N0w== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/credential-provider-imds@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.306.0.tgz#dd089ddb8c8199492137072b37abb1c1f1cb4c95" @@ -576,6 +934,38 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/credential-provider-ini@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.408.0.tgz#68e88fb1a7da62421d2252e57c25b0421da342a9" + integrity sha512-vXuayXiwHncd3Xush0jQYrnu2aPPlE+fpdnpEdZGgUJwdbv2vSeYZ73ldH1LzCd179BEDVT0J7nHc7fposo3kg== + dependencies: + "@aws-sdk/credential-provider-env" "3.408.0" + "@aws-sdk/credential-provider-process" "3.408.0" + "@aws-sdk/credential-provider-sso" "3.408.0" + "@aws-sdk/credential-provider-web-identity" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@smithy/credential-provider-imds" "^2.0.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-ini@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.425.0.tgz#f5435becf95c1b45f981c5c1913e59544598127f" + integrity sha512-Ftux1yPVr1Bq/DOhDP2KrzJRVw13410uW0i9MpUlveQz51Fs2doifPKa99UwI/ilF3nton6Yv/NsfKFnb2hoSA== + dependencies: + "@aws-sdk/credential-provider-env" "3.425.0" + "@aws-sdk/credential-provider-process" "3.425.0" + "@aws-sdk/credential-provider-sso" "3.425.0" + "@aws-sdk/credential-provider-web-identity" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@smithy/credential-provider-imds" "^2.0.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/credential-provider-node@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.306.0.tgz#627eec0babc2fcc3ae3c949a0629b4b1ffbe0be8" @@ -608,6 +998,40 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/credential-provider-node@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.408.0.tgz#91dd0f6e6f2434c8fb682276d125204d06ce4639" + integrity sha512-AzDtlj2Mb01K5+AiDI14HsIs9I/pI4nM3kxeOZZvocaaThF5OFR+4wR2v2plhfGJ8QAPEE/KnqcJ3JlJ7orShg== + dependencies: + "@aws-sdk/credential-provider-env" "3.408.0" + "@aws-sdk/credential-provider-ini" "3.408.0" + "@aws-sdk/credential-provider-process" "3.408.0" + "@aws-sdk/credential-provider-sso" "3.408.0" + "@aws-sdk/credential-provider-web-identity" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@smithy/credential-provider-imds" "^2.0.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-node@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.425.0.tgz#40f060c039fcf2a9f45c3134b25fa99cf449bbed" + integrity sha512-kw9Iv121AWc+44Lw+zb0NDQ6Pz84D+bonAhJZgY6uAxv4lkZ7ZguZVF3BALPgFIkiHwwaQLNgCEWC1WMk96wWw== + dependencies: + "@aws-sdk/credential-provider-env" "3.425.0" + "@aws-sdk/credential-provider-ini" "3.425.0" + "@aws-sdk/credential-provider-process" "3.425.0" + "@aws-sdk/credential-provider-sso" "3.425.0" + "@aws-sdk/credential-provider-web-identity" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@smithy/credential-provider-imds" "^2.0.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/credential-provider-process@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.306.0.tgz#451d1b93d9c0ac6b5b17a5e4aea355f9eb88e7f5" @@ -628,6 +1052,28 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/credential-provider-process@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.408.0.tgz#fbcf6571bc87e536b847e14c4c9ee1fdd6b81deb" + integrity sha512-qCTf9tr6+I2s3+v5zP4YRQQrGlYw/jyZ7u/k6bGshhlvgwGPfjNuHrM8uK/W1kv4ng1myxaL1/tAY6RVVdXz4Q== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-process@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.425.0.tgz#d5cd231e1732375fc918912f8083c8c45d9dc2ab" + integrity sha512-YY6tkLdvtb1Fgofp3b1UWO+5vwS14LJ/smGmuGpSba0V7gFJRdcrJ9bcb9vVgAGuMdjzRJ+bUKlLLtqXkaykEw== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/credential-provider-sso@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.306.0.tgz#4c3cd6566c38c397c5159a448b286edc90fbc65b" @@ -652,6 +1098,32 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/credential-provider-sso@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.408.0.tgz#aaf772d34871eb4d02a8e8b242b64d02660c64b3" + integrity sha512-iKU91cxrttQyDhdhF7vJZd6XibvwGolFzuJBG4DD4jOdvmTcVq4L26AH8bjR1psnS6pvTa66FaYt6BGtbXgVeA== + dependencies: + "@aws-sdk/client-sso" "3.408.0" + "@aws-sdk/token-providers" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-sso@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.425.0.tgz#9cdc335cd3d0b5bc3f1cfc8f1f6d512860be7cd9" + integrity sha512-oqFwo2UDX4vCrnvdSE9xyFm7sqk/wKkDGLwVV+syqqbMu7F4n9qY9j17Xmr7sGgX3ho9PQh0n2DxyQRN568P7g== + dependencies: + "@aws-sdk/client-sso" "3.425.0" + "@aws-sdk/token-providers" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/credential-provider-web-identity@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.306.0.tgz#9fe7f067315699f2c3566bfdaad8d5a605d2cbd9" @@ -670,6 +1142,26 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/credential-provider-web-identity@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.408.0.tgz#2e38730a309b81527d23c3d435ea5ab1a3f73688" + integrity sha512-5FbDPF/zY/1t6k1zRI/HnrxcH2v7SwsEYu2SThI2qbzaP/K7MTnTanV5vNFcdQOpuQ7x3PrzTlH3AWZueCr3Vw== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-web-identity@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.425.0.tgz#c1587cc39be70db2c828aeab7b68a8245bc86f91" + integrity sha512-/0R65TgRzL01JU3SzloivWNwdkbIhr06uY/F5pBHf/DynQqaspKNfdHn6AiozgSVDfwRHFjKBTUy6wvf3QFkuA== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/eventstream-codec@3.329.0": version "3.329.0" resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-codec/-/eventstream-codec-3.329.0.tgz#6bdfd69ad54352309535f53352017e932b9f643b" @@ -787,6 +1279,19 @@ dependencies: tslib "^2.5.0" +"@aws-sdk/middleware-bucket-endpoint@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.425.0.tgz#21a2658902482a88ea2201046ba324be6bb106b6" + integrity sha512-7UTfA10fmDw9cgHLApxRUNPywZTG4S/1TNZgTxndO/1OM9ZHtIatw1iLbqJD35gHrpEYI8Vo14YvcnD2ITuiMw== + dependencies: + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-arn-parser" "3.310.0" + "@smithy/node-config-provider" "^2.0.13" + "@smithy/protocol-http" "^3.0.6" + "@smithy/types" "^2.3.4" + "@smithy/util-config-provider" "^2.0.0" + tslib "^2.5.0" + "@aws-sdk/middleware-content-length@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-content-length/-/middleware-content-length-3.306.0.tgz#5ab51d76d4e46122fc618d7af505a113f984f0ad" @@ -827,6 +1332,30 @@ "@aws-sdk/util-middleware" "3.329.0" tslib "^2.5.0" +"@aws-sdk/middleware-expect-continue@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.425.0.tgz#65b1c0368582a5658729aa4c918aa1a135f05db2" + integrity sha512-CqAmnDST2o7+sKKw2/ffHKiYKE+jZb/Ce9U0P//ZYzqp9R1Wb016ID+W6DoxufyPJAS9dpRMcUDnAssmMIC/EA== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@aws-sdk/middleware-flexible-checksums@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.425.0.tgz#57b12950b4174f2acdc3c4856b2b764c83c84b70" + integrity sha512-BDwn2vVVsC/AzmHXQlaZhEpKXL7GfKFpH7ZFccZuwEQBcyn8lVCcwtfaRe5P1mEe2wklVzOXd1dw8bt0+BOUPA== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@aws-crypto/crc32c" "3.0.0" + "@aws-sdk/types" "3.425.0" + "@smithy/is-array-buffer" "^2.0.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/types" "^2.3.4" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + "@aws-sdk/middleware-host-header@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.306.0.tgz#69d26fb8a6cdc939bbe1b1956a2fb6831b2b8f70" @@ -845,6 +1374,35 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/middleware-host-header@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.408.0.tgz#7b84ce0336c7acd5bc1e82076ef95bde597d6edf" + integrity sha512-eofCXuSZ+ntbLzeCRdHzraXzgWqAplXU7W2qFFVC4O9lZBhADwNPI8n8x98TH0mftnmvZxh5Bo5U8WvEolIDkw== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/protocol-http" "^2.0.5" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/middleware-host-header@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.425.0.tgz#7bca371e1a5611ec20c06bd7017efa1900c367d0" + integrity sha512-E5Gt41LObQ+cr8QnLthwsH3MtVSNXy1AKJMowDr85h0vzqA/FHUkgHyOGntgozzjXT5M0MaSRYxS0xwTR5D4Ew== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@aws-sdk/middleware-location-constraint@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.425.0.tgz#562cd09d85b8500bfcf94ff59b9ec8489e78f53a" + integrity sha512-3rt0LpGmL1LCRFuEObS1yERd9OEV+AEIAvhY7b53M7u7SyrjWQtpntWkI365L/QljhgMXQBfps2qO4JtrhQnsA== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/middleware-logger@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.306.0.tgz#9a43c7b213c2ffe0b5382cef6e51aacfa64a965e" @@ -861,6 +1419,24 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/middleware-logger@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.408.0.tgz#6c745f352ba95284ee78a397368c7dc79378da43" + integrity sha512-otwXPCubsGRFv8Hb6nKw6Vvnu4dC8CcPk05buStj42nF8QdjWrKGb2rDCvLph5lr576LF5HN+Y2moyOi7z/I7g== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/middleware-logger@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.425.0.tgz#e45f160b84798365e4acf8a283e9664ee9ee131b" + integrity sha512-INE9XWRXx2f4a/r2vOU0tAmgctVp7nEaEasemNtVBYhqbKLZvr9ndLBSgKGgJ8LIcXAoISipaMuFiqIGkFsm7A== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/middleware-recursion-detection@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.306.0.tgz#2a12e46f9dd1acba57f1a1219550e50f94ea9f5d" @@ -879,6 +1455,26 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/middleware-recursion-detection@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.408.0.tgz#036fa1ee8b76d5a0947591590a7a3a867aea8cae" + integrity sha512-QfZwmX5z0IRC2c8pBi9VozSqbJw19V5oxyykSTqdjGe3CG3yNujXObV6xQesK67CWSnPb9wDgVGKUoYuIXwOxw== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/protocol-http" "^2.0.5" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/middleware-recursion-detection@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.425.0.tgz#c348ec16ebb7c357bcb403904c24e8da1914961d" + integrity sha512-77gnzJ5b91bgD75L/ugpOyerx6lR3oyS4080X1YI58EzdyBMkDrHM4FbMcY2RynETi3lwXCFzLRyZjWXY1mRlw== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/middleware-retry@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.306.0.tgz#577502e3b510465c3fc78206462ec934fd64f732" @@ -905,6 +1501,29 @@ tslib "^2.5.0" uuid "^8.3.2" +"@aws-sdk/middleware-sdk-s3@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.425.0.tgz#fb1d250c7ce43436f2191cf3267dfcf48775d9b4" + integrity sha512-kX6uiyaz3xpiFGDsFCtwwORLqDDLr8lEI42iUbHh5XzNb1dG6tqa0Zfw/oNI+lGVFmOzr1otR39p925tYVeEaQ== + dependencies: + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-arn-parser" "3.310.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@aws-sdk/middleware-sdk-sqs@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.425.0.tgz#72ac1c560091798af47a53a73f7876b52811d8bb" + integrity sha512-c+8SQmxs9NMgaCea0o2RSsonYlDXbsYf7SODqiYKmPbHic7oa+rUmIWq7cLjxcMT8W2WKFkpvLHJZ8ex+BOHXQ== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/types" "^2.3.4" + "@smithy/util-hex-encoding" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + "@aws-sdk/middleware-sdk-sts@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.306.0.tgz#6624b9c2ac6280f8c6c8717a34a7740129b3bcd2" @@ -923,6 +1542,26 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/middleware-sdk-sts@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.408.0.tgz#812deff5fa8388cda6d6908452d6223b059232f9" + integrity sha512-dIO9BTX049P2PwaeAK2lxJeA2rZi9/bWzMP1GIE60VrMDHmN5Ljvh1lLActECLAqNQIqN5Ub0bKV2tC/jMn+CA== + dependencies: + "@aws-sdk/middleware-signing" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/middleware-sdk-sts@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.425.0.tgz#a020a04ddb5c6741d43d72afe79c24e6f1bb94b7" + integrity sha512-JFojrg76oKAoBknnr9EL5N2aJ1mRCtBqXoZYST58GSx8uYdFQ89qS65VNQ8JviBXzsrCNAn4vDhZ5Ch5E6TxGQ== + dependencies: + "@aws-sdk/middleware-signing" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/middleware-serde@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.306.0.tgz#97695b07496e1fef68fa50959b3919cf1d0d261e" @@ -963,6 +1602,41 @@ "@aws-sdk/util-middleware" "3.329.0" tslib "^2.5.0" +"@aws-sdk/middleware-signing@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.408.0.tgz#89bb56abf5cbddaa9b04026c74362765918b6ff2" + integrity sha512-flLiLKATJ4NLcLb7lPojyQ6NvLSyQ3axqIClqwMRnhSRxvREB7OgBKwmPecSl0I5JxsNEqo+mjARdMjUHadgWQ== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/protocol-http" "^2.0.5" + "@smithy/signature-v4" "^2.0.0" + "@smithy/types" "^2.2.2" + "@smithy/util-middleware" "^2.0.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-signing@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.425.0.tgz#fa133b8a76216d0b55558634b09cbe769f16b037" + integrity sha512-ZpOfgJHk7ovQ0sSwg3tU4NxFOnz53lJlkJRf7S+wxQALHM0P2MJ6LYBrZaFMVsKiJxNIdZBXD6jclgHg72ZW6Q== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/property-provider" "^2.0.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/signature-v4" "^2.0.0" + "@smithy/types" "^2.3.4" + "@smithy/util-middleware" "^2.0.3" + tslib "^2.5.0" + +"@aws-sdk/middleware-ssec@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.425.0.tgz#5faf5a44af23faf829f60d0ce08b36332f32cb3f" + integrity sha512-9HTuXnHYAZWkwPC8x9tElsQjFPxDT//orbIFauS7VF5HkLCKn9J6O6lW1wKMxrEnDwfN/Vi3nw479MoPj5Ss0Q== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/middleware-stack@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.306.0.tgz#3f145b39a233571785607874a021af10bf54a73a" @@ -997,6 +1671,28 @@ "@aws-sdk/util-endpoints" "3.332.0" tslib "^2.5.0" +"@aws-sdk/middleware-user-agent@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.408.0.tgz#c1909be2ce2c350273747923c4791a2d37bb0af8" + integrity sha512-UvlKri8/Mgf5W+tFU6ZJ65fC6HljcysIqfRFts/8Wurl322IS1I4j+pyjV2P6eK1054bzynfi3Trv+tRYHtVcA== + dependencies: + "@aws-sdk/types" "3.408.0" + "@aws-sdk/util-endpoints" "3.408.0" + "@smithy/protocol-http" "^2.0.5" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/middleware-user-agent@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.425.0.tgz#3361051829d6e711273035651d00802de7a4ff3e" + integrity sha512-FFlXJcCA6/Z3J66UEi3VVsWFaH11buPK5NZ2HgAzbzYwksc8EoM4kIfzl4qEoA5LbrYJGPIQ95eI+/FbbIobwA== + dependencies: + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-endpoints" "3.425.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/node-config-provider@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.306.0.tgz#9fed0bef4e8446350ca2dd3ec7571759d8ce2cd8" @@ -1105,6 +1801,17 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/region-config-resolver@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.425.0.tgz#b69cc305a4211c9f96f04ac3a10ff9a736ec13cb" + integrity sha512-u7uv/iUOapIJdRgRkO3wnpYsUgV6ponsZJQgVg/8L+n+Vo5PQL5gAcIuAOwcYSKQPFaeK+KbmByI4SyOK203Vw== + dependencies: + "@smithy/node-config-provider" "^2.0.13" + "@smithy/types" "^2.3.4" + "@smithy/util-config-provider" "^2.0.0" + "@smithy/util-middleware" "^2.0.3" + tslib "^2.5.0" + "@aws-sdk/service-error-classification@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/service-error-classification/-/service-error-classification-3.306.0.tgz#47889417d26ea99f0f229f5ca5bc42ac95c07976" @@ -1131,6 +1838,17 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/signature-v4-multi-region@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.425.0.tgz#9521058eec054b835070e85a1fd10877de49b154" + integrity sha512-7n2FRPE9rLaVa26xXQJ8TExrt53dWN824axQd1a0r5va0SmMQYG/iV5LBmwUlAntUSq46Lse4Q5YnbOVedGOmw== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/signature-v4" "^2.0.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/signature-v4@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4/-/signature-v4-3.306.0.tgz#a32079435099232cdc88b1bf9ed0918a385ae39e" @@ -1197,6 +1915,88 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/token-providers@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.408.0.tgz#1de7fbbe25b8526ee7f3eebac26f581e3488a5d3" + integrity sha512-D//BjUrVtDzDdCz1mRdZZSAc822fh75Ssq46smeS6S6NKq3vJeHhfrQJMyVU1GclXu1tn9AwykaQW5Jwb5im+g== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/middleware-host-header" "3.408.0" + "@aws-sdk/middleware-logger" "3.408.0" + "@aws-sdk/middleware-recursion-detection" "3.408.0" + "@aws-sdk/middleware-user-agent" "3.408.0" + "@aws-sdk/types" "3.408.0" + "@aws-sdk/util-endpoints" "3.408.0" + "@aws-sdk/util-user-agent-browser" "3.408.0" + "@aws-sdk/util-user-agent-node" "3.408.0" + "@smithy/config-resolver" "^2.0.5" + "@smithy/fetch-http-handler" "^2.0.5" + "@smithy/hash-node" "^2.0.5" + "@smithy/invalid-dependency" "^2.0.5" + "@smithy/middleware-content-length" "^2.0.5" + "@smithy/middleware-endpoint" "^2.0.5" + "@smithy/middleware-retry" "^2.0.5" + "@smithy/middleware-serde" "^2.0.5" + "@smithy/middleware-stack" "^2.0.0" + "@smithy/node-config-provider" "^2.0.6" + "@smithy/node-http-handler" "^2.0.5" + "@smithy/property-provider" "^2.0.0" + "@smithy/protocol-http" "^2.0.5" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/smithy-client" "^2.0.5" + "@smithy/types" "^2.2.2" + "@smithy/url-parser" "^2.0.5" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.6" + "@smithy/util-defaults-mode-node" "^2.0.6" + "@smithy/util-retry" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@aws-sdk/token-providers@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.425.0.tgz#ffc7c0b797a2a0b2e3338045b7804784ca938be7" + integrity sha512-q9skB/aDlqRESOuavs+wbnD9X2Odro0VaM1OOl2CRnJyv5ePOzNVzeoQn3d21zoh8klZkhoAqgbFnACeI3MN4w== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/middleware-host-header" "3.425.0" + "@aws-sdk/middleware-logger" "3.425.0" + "@aws-sdk/middleware-recursion-detection" "3.425.0" + "@aws-sdk/middleware-user-agent" "3.425.0" + "@aws-sdk/types" "3.425.0" + "@aws-sdk/util-endpoints" "3.425.0" + "@aws-sdk/util-user-agent-browser" "3.425.0" + "@aws-sdk/util-user-agent-node" "3.425.0" + "@smithy/config-resolver" "^2.0.11" + "@smithy/fetch-http-handler" "^2.2.1" + "@smithy/hash-node" "^2.0.10" + "@smithy/invalid-dependency" "^2.0.10" + "@smithy/middleware-content-length" "^2.0.12" + "@smithy/middleware-endpoint" "^2.0.10" + "@smithy/middleware-retry" "^2.0.13" + "@smithy/middleware-serde" "^2.0.10" + "@smithy/middleware-stack" "^2.0.4" + "@smithy/node-config-provider" "^2.0.13" + "@smithy/node-http-handler" "^2.1.6" + "@smithy/property-provider" "^2.0.0" + "@smithy/protocol-http" "^3.0.6" + "@smithy/shared-ini-file-loader" "^2.0.6" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + "@smithy/url-parser" "^2.0.10" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-body-length-browser" "^2.0.0" + "@smithy/util-body-length-node" "^2.1.0" + "@smithy/util-defaults-mode-browser" "^2.0.13" + "@smithy/util-defaults-mode-node" "^2.0.15" + "@smithy/util-retry" "^2.0.3" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + "@aws-sdk/types@3.306.0", "@aws-sdk/types@^3.222.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.306.0.tgz#076aa94a1d711311c14bab10b251752506a21487" @@ -1211,6 +2011,22 @@ dependencies: tslib "^2.5.0" +"@aws-sdk/types@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.408.0.tgz#eb10377130f23aef6594eb0e0a14e82dfa2e4d5a" + integrity sha512-sIsR5224xWQTW7O6h4V0S7DMWs4bK4DCunwOo7Avpq7ZVmH2YyLTs0n4NGL186j8xTosycF1ACQgpM48SLIvaA== + dependencies: + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/types@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.425.0.tgz#8d4e94743a69c865a83785a9f3bcfd49945836f7" + integrity sha512-6lqbmorwerN4v+J5dqbHPAsjynI0mkEF+blf+69QTaKKGaxBBVaXgqoqul9RXYcK5MMrrYRbQIMd0zYOoy90kA== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/url-parser@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.306.0.tgz#7d6b51f70874bbeb18208d4d9b6f931a98b81c03" @@ -1229,6 +2045,13 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/util-arn-parser@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz#861ff8810851be52a320ec9e4786f15b5fc74fba" + integrity sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA== + dependencies: + tslib "^2.5.0" + "@aws-sdk/util-base64@3.303.0": version "3.303.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64/-/util-base64-3.303.0.tgz#653281b7c1abfafc3f7a4c6f3b00d0733a4c455a" @@ -1363,6 +2186,22 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/util-endpoints@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.408.0.tgz#397c6d9236434063127301f9c4d2117bdb978621" + integrity sha512-N1D5cKEkCqf5Q7IF/pI9kfcNrT+/5ctZ6cQo4Ex6xaOcnUzdOZcXdPqaMRZVZRn8enjK2SpoLlRpXGISOugPaw== + dependencies: + "@aws-sdk/types" "3.408.0" + tslib "^2.5.0" + +"@aws-sdk/util-endpoints@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.425.0.tgz#00b66f45ca79cc7554e9bb6cd2328abdec186bc2" + integrity sha512-0HkrfWQRo10TWcllDAk9mkkttAXv/AUHpQ+JZjaLmR4IIrn3l/AqTiz/zyXfUawWaoXJzuPIdJ2J3v/gt/IpQA== + dependencies: + "@aws-sdk/types" "3.425.0" + tslib "^2.5.0" + "@aws-sdk/util-hex-encoding@3.295.0": version "3.295.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.295.0.tgz#13acb924f88785d317c9bec37e5ca173ccc4a0ca" @@ -1446,6 +2285,26 @@ bowser "^2.11.0" tslib "^2.5.0" +"@aws-sdk/util-user-agent-browser@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.408.0.tgz#60b9660d4eb8c7ee9b3dc941436f1a025cc62567" + integrity sha512-wOVjDprG5h6kM8aJZk/tRX/RgxNxr73d6kIsUePlAgil13q62M9lcFMcIXduqtDsa1B6FfVB2wx/pyUuOZri5g== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/types" "^2.2.2" + bowser "^2.11.0" + tslib "^2.5.0" + +"@aws-sdk/util-user-agent-browser@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.425.0.tgz#74d200d461ea2d75a8d4916c230ffe3a20fcb009" + integrity sha512-22Y9iMtjGcFjGILR6/xdp1qRezlHVLyXtnpEsbuPTiernRCPk6zfAnK/ATH77r02MUjU057tdxVkd5umUBTn9Q== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/types" "^2.3.4" + bowser "^2.11.0" + tslib "^2.5.0" + "@aws-sdk/util-user-agent-node@3.306.0": version "3.306.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.306.0.tgz#40a981a49cf07681ee3ffefbf479d05fbb257e1b" @@ -1464,6 +2323,26 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/util-user-agent-node@3.408.0": + version "3.408.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.408.0.tgz#2976414ed440d0a338b1ec6373a220ae71c08cab" + integrity sha512-BzMFV+cIXrtfcfJk3GpXnkANFkzZisvAtD306TMgIscn5FF26K1jD5DU+h5Q5WMq7gx+oXh9kJ3Lu3hi7hahKQ== + dependencies: + "@aws-sdk/types" "3.408.0" + "@smithy/node-config-provider" "^2.0.6" + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@aws-sdk/util-user-agent-node@3.425.0": + version "3.425.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.425.0.tgz#847c0d6526a34e174419dcecf0e12cd000158a84" + integrity sha512-SIR4F5uQeeVAi8lv4OgRirtdtNi5zeyogTuQgGi9su8F/WP1N6JqxofcwpUY5f8/oJ2UlXr/tx1f09UHfJJzvA== + dependencies: + "@aws-sdk/types" "3.425.0" + "@smithy/node-config-provider" "^2.0.13" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + "@aws-sdk/util-utf8-browser@^3.0.0": version "3.259.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" @@ -1496,6 +2375,13 @@ "@aws-sdk/types" "3.329.0" tslib "^2.5.0" +"@aws-sdk/xml-builder@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz#f0236f2103b438d16117e0939a6305ad69b7ff76" + integrity sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw== + dependencies: + tslib "^2.5.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4": version "7.21.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" @@ -3280,103 +4166,814 @@ uuid "^8.3.2" yamljs "^0.3.0" -"@serverless/event-mocks@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@serverless/event-mocks/-/event-mocks-1.1.1.tgz#7064b99ccc29d9a8e9b799f413dbcfd64ea3b7ee" - integrity sha512-YAV5V/y+XIOfd+HEVeXfPWZb8C6QLruFk9tBivoX2roQLWVq145s4uxf8D0QioCueuRzkukHUS4JIj+KVoS34A== +"@serverless/event-mocks@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@serverless/event-mocks/-/event-mocks-1.1.1.tgz#7064b99ccc29d9a8e9b799f413dbcfd64ea3b7ee" + integrity sha512-YAV5V/y+XIOfd+HEVeXfPWZb8C6QLruFk9tBivoX2roQLWVq145s4uxf8D0QioCueuRzkukHUS4JIj+KVoS34A== + dependencies: + "@types/lodash" "^4.14.123" + lodash "^4.17.11" + +"@serverless/platform-client@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@serverless/platform-client/-/platform-client-4.3.2.tgz#10cd3ad8cf452a33528cfb14bbb6003d30a74805" + integrity sha512-DAa5Z0JAZc6UfrTZLYwqoZxgAponZpFwaqd7WzzMA+loMCkYWyJNwxrAmV6cr2UUJpkko4toPZuJ3vM9Ie+NDA== + dependencies: + adm-zip "^0.5.5" + archiver "^5.3.0" + axios "^0.21.1" + fast-glob "^3.2.7" + https-proxy-agent "^5.0.0" + ignore "^5.1.8" + isomorphic-ws "^4.0.1" + js-yaml "^3.14.1" + jwt-decode "^2.2.0" + minimatch "^3.0.4" + querystring "^0.2.1" + run-parallel-limit "^1.1.0" + throat "^5.0.0" + traverse "^0.6.6" + ws "^7.5.3" + +"@serverless/utils@^6.10.0", "@serverless/utils@^6.8.2": + version "6.10.0" + resolved "https://registry.yarnpkg.com/@serverless/utils/-/utils-6.10.0.tgz#6e1b8f23c1b13689cd97d7f4dcc2135d2b8a850d" + integrity sha512-1ScVcT8UUzOsOXZpY6Z/VypyZFVX5/2nmAuttD6bYLVEtavl6w+l33LFQbGLuMIRyV/6ZgaeZeyrszOOs4A2+g== + dependencies: + archive-type "^4.0.0" + chalk "^4.1.2" + ci-info "^3.8.0" + cli-progress-footer "^2.3.2" + content-disposition "^0.5.4" + d "^1.0.1" + decompress "^4.2.1" + event-emitter "^0.3.5" + ext "^1.7.0" + ext-name "^5.0.0" + file-type "^16.5.4" + filenamify "^4.3.0" + get-stream "^6.0.1" + got "^11.8.6" + inquirer "^8.2.5" + js-yaml "^4.1.0" + jwt-decode "^3.1.2" + lodash "^4.17.21" + log "^6.3.1" + log-node "^8.0.3" + make-dir "^3.1.0" + memoizee "^0.4.15" + ms "^2.1.3" + ncjsm "^4.3.2" + node-fetch "^2.6.9" + open "^8.4.2" + p-event "^4.2.0" + supports-color "^8.1.1" + timers-ext "^0.1.7" + type "^2.7.2" + uni-global "^1.0.0" + uuid "^8.3.2" + write-file-atomic "^4.0.2" + +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== + +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@sinonjs/commons@^1.7.0": + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@smithy/abort-controller@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.0.10.tgz#a6d0d24973ac35b59cc450c34decd68485fbe2c0" + integrity sha512-xn7PnFD3m4rQIG00h1lPuDVnC2QMtTFhzRLX3y56KkgFaCysS7vpNevNBgmNUtmJ4eVFc+66Zucwo2KDLdicOg== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/abort-controller@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.0.6.tgz#8d17bb447aa33a43e4d57f98f9dc23560158b6b8" + integrity sha512-4I7g0lyGUlW2onf8mD76IzU37oRWSHsQ5zlW5MjDzgg4I4J9bOK4500Gx6qOuoN7+GulAnGLe1YwyrIluzhakg== + dependencies: + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/chunked-blob-reader-native@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-2.0.0.tgz#f6d0eeeb5481026b68b054f45540d924c194d558" + integrity sha512-HM8V2Rp1y8+1343tkZUKZllFhEQPNmpNdgFAncbTsxkZ18/gqjk23XXv3qGyXWp412f3o43ZZ1UZHVcHrpRnCQ== + dependencies: + "@smithy/util-base64" "^2.0.0" + tslib "^2.5.0" + +"@smithy/chunked-blob-reader@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/chunked-blob-reader/-/chunked-blob-reader-2.0.0.tgz#c44fe2c780eaf77f9e5381d982ac99a880cce51b" + integrity sha512-k+J4GHJsMSAIQPChGBrjEmGS+WbPonCXesoqP9fynIqjn7rdOThdH8FAeCmokP9mxTYKQAKoHCLPzNlm6gh7Wg== + dependencies: + tslib "^2.5.0" + +"@smithy/config-resolver@^2.0.11", "@smithy/config-resolver@^2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.0.12.tgz#3d72e3805ad1ba8fc9df82415302d513312b5f98" + integrity sha512-ISGEdQTGV2p5x9UZzb9SX3Y2MySLi5r69+UtDgB4KvJitV+ys1ONKpsLshi22bvQTy1yAgfLjOj33K7mSJakpQ== + dependencies: + "@smithy/node-config-provider" "^2.0.14" + "@smithy/types" "^2.3.4" + "@smithy/util-config-provider" "^2.0.0" + "@smithy/util-middleware" "^2.0.3" + tslib "^2.5.0" + +"@smithy/config-resolver@^2.0.5", "@smithy/config-resolver@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.0.6.tgz#b837cf15ab81a94a1d57b1720ef1b8b458884ef4" + integrity sha512-6yxwwy6mEpfOxwlj45x8pAv47fDskgFmNu/dZhmbc67OMOuyxBQFvxZWuUQZXtMnClxWW4IceYqIIdkJo4Uitw== + dependencies: + "@smithy/types" "^2.3.0" + "@smithy/util-config-provider" "^2.0.0" + "@smithy/util-middleware" "^2.0.0" + tslib "^2.5.0" + +"@smithy/credential-provider-imds@^2.0.0", "@smithy/credential-provider-imds@^2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.8.tgz#e8579b987f5480c2d8fdb4eade2d21984a5e4f6c" + integrity sha512-yOX1a7ZH7yEOiPOrPZ/iGtLTY3PqacEh8d2IimDRrbYQ0lkPJU1g/wL+LIxv3as/MIEexBlcXF+EEbsmKc8PKg== + dependencies: + "@smithy/node-config-provider" "^2.0.8" + "@smithy/property-provider" "^2.0.7" + "@smithy/types" "^2.3.0" + "@smithy/url-parser" "^2.0.6" + tslib "^2.5.0" + +"@smithy/credential-provider-imds@^2.0.14": + version "2.0.14" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.14.tgz#127c6d0c8503e074bbf81eab618c28f31abb1116" + integrity sha512-9dPBDuudRnrRuyKXdS4cn8A8FAOVVIgc+j3qC86c5xYnZ9Ykr7WKIl53OTQsZlEsiHC73d93YCA89KVhvGIlJg== + dependencies: + "@smithy/node-config-provider" "^2.0.14" + "@smithy/property-provider" "^2.0.11" + "@smithy/types" "^2.3.4" + "@smithy/url-parser" "^2.0.10" + tslib "^2.5.0" + +"@smithy/eventstream-codec@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.0.10.tgz#dbd46d0ed13abc61b1f08ab249f3097602752933" + integrity sha512-3SSDgX2nIsFwif6m+I4+ar4KDcZX463Noes8ekBgQHitULiWvaDZX8XqPaRQSQ4bl1vbeVXHklJfv66MnVO+lw== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@smithy/types" "^2.3.4" + "@smithy/util-hex-encoding" "^2.0.0" + tslib "^2.5.0" + +"@smithy/eventstream-codec@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.0.6.tgz#1ea033e977b58a59ff4b00cf7c899d1ca0c7f81a" + integrity sha512-J9xL82mlYRUMXFnB9VaThXkD7z2JLr52FIVZMoQQ1dxZG5ub+NOGmzaTTZC/cMmKXI/nwCoFuwDWCTjwQhYhQA== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@smithy/types" "^2.3.0" + "@smithy/util-hex-encoding" "^2.0.0" + tslib "^2.5.0" + +"@smithy/eventstream-serde-browser@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.10.tgz#93054f85194655d7eba27125f4935d247bdc2a8f" + integrity sha512-/NSUNrWedO9Se80jo/2WcPvqobqCM/0drZ03Kqn1GZpGwVTsdqNj7frVTCUJs/W/JEzOShdMv8ewoKIR7RWPmA== + dependencies: + "@smithy/eventstream-serde-universal" "^2.0.10" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/eventstream-serde-config-resolver@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.10.tgz#ea2f6675a4270fc3eccbb9fda4086f611887b510" + integrity sha512-ag1U0vsC5rhRm7okFzsS6YsvyTRe62jIgJ82+Wr4qoOASx7eCDWdjoqLnrdDY0S4UToF9hZAyo4Du/xrSSSk4g== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/eventstream-serde-node@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.10.tgz#54af54b9719aa8f74fae5885a72e69b33d5661cf" + integrity sha512-3+VeofxoVCa+dvqcuzEpnFve8EQJKaYR7UslDFpj6UTZfa7Hxr8o1/cbFkTftFo71PxzYVsR+bsD56EbAO432A== + dependencies: + "@smithy/eventstream-serde-universal" "^2.0.10" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/eventstream-serde-universal@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.10.tgz#575a6160a12508341c9c345bf3da7422a590aaae" + integrity sha512-JhJJU1ULLsn5kxKfFe8zOF2tibjxlPIvIB71Kn20aa/OFs+lvXBR0hBGswpovyYyckXH3qU8VxuIOEuS+2G+3A== + dependencies: + "@smithy/eventstream-codec" "^2.0.10" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/fetch-http-handler@^2.0.5", "@smithy/fetch-http-handler@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.1.1.tgz#e71588989acb5bcef90aef59fa0069510a907f15" + integrity sha512-jb2gHYAPpZ3Zkpng3oicPLIw+3ZW2Z3u1bo9LWgX8tEghn72olvRKSLsjykbDSKOQWyWNGywkApHPdDXJcO6fQ== + dependencies: + "@smithy/protocol-http" "^3.0.1" + "@smithy/querystring-builder" "^2.0.6" + "@smithy/types" "^2.3.0" + "@smithy/util-base64" "^2.0.0" + tslib "^2.5.0" + +"@smithy/fetch-http-handler@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.1.tgz#a8abbd339c2c3d76456f4d16e65cf934727fc7ad" + integrity sha512-bXyM8PBAIKxVV++2ZSNBEposTDjFQ31XWOdHED+2hWMNvJHUoQqFbECg/uhcVOa6vHie2/UnzIZfXBSTpDBnEw== + dependencies: + "@smithy/protocol-http" "^3.0.6" + "@smithy/querystring-builder" "^2.0.10" + "@smithy/types" "^2.3.4" + "@smithy/util-base64" "^2.0.0" + tslib "^2.5.0" + +"@smithy/hash-blob-browser@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.10.tgz#fa761e02c9a21b9c4bf827139d65376d50356c69" + integrity sha512-U2+wIWWloOZ9DaRuz2sk9f7A6STRTlwdcv+q6abXDvS0TRDk8KGgUmfV5lCZy8yxFxZIA0hvHDNqcd25r4Hrew== + dependencies: + "@smithy/chunked-blob-reader" "^2.0.0" + "@smithy/chunked-blob-reader-native" "^2.0.0" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/hash-node@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.0.10.tgz#af13889a008880bdc30278b148e0e0b2a6e2d243" + integrity sha512-jSTf6uzPk/Vf+8aQ7tVXeHfjxe9wRXSCqIZcBymSDTf7/YrVxniBdpyN74iI8ZUOx/Pyagc81OK5FROLaEjbXQ== + dependencies: + "@smithy/types" "^2.3.4" + "@smithy/util-buffer-from" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@smithy/hash-node@^2.0.5": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.0.6.tgz#d13af02d3adb010e0c321035b610d53af2e652ef" + integrity sha512-xz7fzFxSzxohKGGyKPbLReRrY01JOZgRDHIXSks3PxQxG9c8PJMa5nUw0stH8UOySUgkofmMy0n7vTUsF5Mdqg== + dependencies: + "@smithy/types" "^2.3.0" + "@smithy/util-buffer-from" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@smithy/hash-stream-node@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/hash-stream-node/-/hash-stream-node-2.0.10.tgz#6e693b4362fbb031b8fc60e105220874d044ec8d" + integrity sha512-L58XEGrownZZSpF7Lp0gc0hy+eYKXuPgNz3pQgP5lPFGwBzHdldx2X6o3c6swD6RkcPvTRh0wTUVVGwUotbgnQ== + dependencies: + "@smithy/types" "^2.3.4" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@smithy/invalid-dependency@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.0.10.tgz#b708e7cfc35214ce664db6aa67465567b97ffd36" + integrity sha512-zw9p/zsmJ2cFcW4KMz3CJoznlbRvEA6HG2mvEaX5eAca5dq4VGI2MwPDTfmteC/GsnURS4ogoMQ0p6aHM2SDVQ== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/invalid-dependency@^2.0.5": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.0.6.tgz#9230517c5a9f5bafee3bf89e9c548801a2681a99" + integrity sha512-L5MUyl9mzawIvBxr0Hg3J/Q5qZFXKcBgMk0PacfK3Mthp4WAR6h7iMxdSQ23Q7X/kxOrpZuoYEdh1BWLKbDc8Q== + dependencies: + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/is-array-buffer@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz#8fa9b8040651e7ba0b2f6106e636a91354ff7d34" + integrity sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug== + dependencies: + tslib "^2.5.0" + +"@smithy/md5-js@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/md5-js/-/md5-js-2.0.10.tgz#8480de1b42abc581cf515e2b8e35542e9248f520" + integrity sha512-eA/Ova4/UdQUbMlrbBmnewmukH0zWU6C67HFFR/719vkFNepbnliGjmGksQ9vylz9eD4nfGkZZ5NKZMAcUuzjQ== + dependencies: + "@smithy/types" "^2.3.4" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@smithy/middleware-content-length@^2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.0.12.tgz#e6f874f5eef880561f774a4376b73f04b97efc53" + integrity sha512-QRhJTo5TjG7oF7np6yY4ZO9GDKFVzU/GtcqUqyEa96bLHE3yZHgNmsolOQ97pfxPHmFhH4vDP//PdpAIN3uI1Q== + dependencies: + "@smithy/protocol-http" "^3.0.6" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/middleware-content-length@^2.0.5": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.0.7.tgz#f046da02f6c9bb95edbb9cac28f66e77e240b09e" + integrity sha512-A4TZXhEIROrLL+Um7yHXZnEKU6EnQzhO53DkJfWQbhsL1nMA2s9yk8d1R+JywsnskhAay3BmLDwcIG/dZtAHIw== + dependencies: + "@smithy/protocol-http" "^3.0.1" + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/middleware-endpoint@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.10.tgz#c11d9f75549116453eea0e812e17ec7917ce5bb1" + integrity sha512-O6m4puZc16xfenotZUHL4bRlMrwf4gTp+0I5l954M5KNd3dOK18P+FA/IIUgnXF/dX6hlCUcJkBp7nAzwrePKA== + dependencies: + "@smithy/middleware-serde" "^2.0.10" + "@smithy/types" "^2.3.4" + "@smithy/url-parser" "^2.0.10" + "@smithy/util-middleware" "^2.0.3" + tslib "^2.5.0" + +"@smithy/middleware-endpoint@^2.0.5": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.6.tgz#b2350fcf63cd69a595b0f42e9718e1ac5144220e" + integrity sha512-MuSPPtEHFal/M77tR3ffLsdOfX29IZpA990nGuoPj5zQnAYrA4PYBGoqqrASQKm8Xb3C0NwuYzOATT7WX4f5Pg== + dependencies: + "@smithy/middleware-serde" "^2.0.6" + "@smithy/types" "^2.3.0" + "@smithy/url-parser" "^2.0.6" + "@smithy/util-middleware" "^2.0.0" + tslib "^2.5.0" + +"@smithy/middleware-retry@^2.0.13": + version "2.0.14" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.0.14.tgz#8b7ab9e22d0fdd72bef5ea3781c1ddc0161b7ebb" + integrity sha512-+1zHIfRyRcTpWnI2z4H6qLKiHQR011JVekSCKDMADwDpRpGUFj+JdCLwu2yEPOPd3MwHLylHBKV03Oooe2PkZQ== + dependencies: + "@smithy/node-config-provider" "^2.0.14" + "@smithy/protocol-http" "^3.0.6" + "@smithy/service-error-classification" "^2.0.3" + "@smithy/types" "^2.3.4" + "@smithy/util-middleware" "^2.0.3" + "@smithy/util-retry" "^2.0.3" + tslib "^2.5.0" + uuid "^8.3.2" + +"@smithy/middleware-retry@^2.0.5": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.0.7.tgz#8425afd2ddadf876a08612fe01131f27419a0486" + integrity sha512-v8fkzG6AbgEj3DWrt4N+gbWlhb48DHCZKsz31Nfhc9t9FYZI1+dKRpRI1yszQSYAaId7WLwQ0PqAoOClYCBCCQ== + dependencies: + "@smithy/protocol-http" "^3.0.1" + "@smithy/service-error-classification" "^2.0.0" + "@smithy/types" "^2.3.0" + "@smithy/util-middleware" "^2.0.0" + "@smithy/util-retry" "^2.0.0" + tslib "^2.5.0" + uuid "^8.3.2" + +"@smithy/middleware-serde@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.0.10.tgz#4b0e5f838c7d7621cabf7cfdd6cec4c7f4d52a3f" + integrity sha512-+A0AFqs768256H/BhVEsBF6HijFbVyAwYRVXY/izJFkTalVWJOp4JA0YdY0dpXQd+AlW0tzs+nMQCE1Ew+DcgQ== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/middleware-serde@^2.0.5", "@smithy/middleware-serde@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.0.6.tgz#cd2ed49fc22b998f3bbbd28b53a72a26d3dd08fb" + integrity sha512-8/GODBngYbrS28CMZtaHIL4R9rLNSQ/zgb+N1OAZ02NwBUawlnLDcatve9YRzhJC/IWz0/pt+WimJZaO1sGcig== + dependencies: + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/middleware-stack@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.0.0.tgz#cd9f442c2788b1ef0ea6b32236d80c76b3c342e9" + integrity sha512-31XC1xNF65nlbc16yuh3wwTudmqs6qy4EseQUGF8A/p2m/5wdd/cnXJqpniy/XvXVwkHPz/GwV36HqzHtIKATQ== + dependencies: + tslib "^2.5.0" + +"@smithy/middleware-stack@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.0.4.tgz#cf199dd4d6eb3a3562e6757804faa91165693395" + integrity sha512-MW0KNKfh8ZGLagMZnxcLJWPNXoKqW6XV/st5NnCBmmA2e2JhrUjU0AJ5Ca/yjTyNEKs3xH7AQDwp1YmmpEpmQQ== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/node-config-provider@^2.0.13", "@smithy/node-config-provider@^2.0.14": + version "2.0.14" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.0.14.tgz#3850410c5fba4fb2032688f2536662073e9b6812" + integrity sha512-DXn0NXmprmhcK81AgYoRct11If3Fvyd9U/T0Bu8ZId/XKho0SGTPahWHI1cZBtPZoiZVeXv3PZAzx6v8kw/0pw== + dependencies: + "@smithy/property-provider" "^2.0.11" + "@smithy/shared-ini-file-loader" "^2.0.13" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/node-config-provider@^2.0.6", "@smithy/node-config-provider@^2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.0.8.tgz#284848dd9d7190ac49af6082b0e19897182c6db7" + integrity sha512-+OjSYXT33jIyU+eu/ECH5wMGtGs4h5MZLy9FbXoWhztszxoDrQRrET01XbhihPQH8bpjrMpYEdlxYEUHQNQzzQ== + dependencies: + "@smithy/property-provider" "^2.0.7" + "@smithy/shared-ini-file-loader" "^2.0.7" + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/node-http-handler@^2.0.5", "@smithy/node-http-handler@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.1.1.tgz#19be3788c4120bd766580ab898a9c6121015d056" + integrity sha512-2dtlmwD2awz/JV4vWHTXwTOBkkIs9XXbMKjv0b+lJDc+VuURZUCZsc7xERDJZy1HO0w/+yuLCjeJu2ER3FlM0A== + dependencies: + "@smithy/abort-controller" "^2.0.6" + "@smithy/protocol-http" "^3.0.1" + "@smithy/querystring-builder" "^2.0.6" + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/node-http-handler@^2.1.6": + version "2.1.6" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.1.6.tgz#c2913363bbf28f315461bd54ef9a5394f1686776" + integrity sha512-NspvD3aCwiUNtoSTcVHz0RZz1tQ/SaRIe1KPF+r0mAdCZ9eWuhIeJT8ZNPYa1ITn7/Lgg64IyFjqPynZ8KnYQw== + dependencies: + "@smithy/abort-controller" "^2.0.10" + "@smithy/protocol-http" "^3.0.6" + "@smithy/querystring-builder" "^2.0.10" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/property-provider@^2.0.0", "@smithy/property-provider@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.0.7.tgz#4b7b780477909026d2fdaef29f0ce5c258f89681" + integrity sha512-XT8Tl7YNxM8tCtGqy7v7DSf6PxyXaPE9cdA/Yj4dEw2b05V3RrPqsP+t5XJiZu0yIsQ7pdeYZWv2sSEWVjNeAg== + dependencies: + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/property-provider@^2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.0.11.tgz#c6e03e4f6f886851339c3dfaf8cd8ae3b2878fa3" + integrity sha512-kzuOadu6XvrnlF1iXofpKXYmo4oe19st9/DE8f5gHNaFepb4eTkR8gD8BSdTnNnv7lxfv6uOwZPg4VS6hemX1w== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/protocol-http@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-2.0.5.tgz#ff7779fc8fcd3fe52e71fd07565b518f0937e8ba" + integrity sha512-d2hhHj34mA2V86doiDfrsy2fNTnUOowGaf9hKb0hIPHqvcnShU4/OSc4Uf1FwHkAdYF3cFXTrj5VGUYbEuvMdw== + dependencies: + "@smithy/types" "^2.2.2" + tslib "^2.5.0" + +"@smithy/protocol-http@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-3.0.1.tgz#4f9787104c94f68e1da99cd1dca7ed548a7a697d" + integrity sha512-+5no1i1fzPjrGsxs06gjAjwDoKuKAFt/QNHEF4hePVfV1EKpR1m/h9GqRH0Z4u6kPfcPZkYSzESTU0cjLqsrIw== + dependencies: + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/protocol-http@^3.0.6": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-3.0.6.tgz#c33c128cc0f7096bf4fcdcc6d14d156ba5cd5b7c" + integrity sha512-F0jAZzwznMmHaggiZgc7YoS08eGpmLvhVktY/Taz6+OAOHfyIqWSDNgFqYR+WHW9z5fp2XvY4mEUrQgYMQ71jw== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/querystring-builder@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-2.0.10.tgz#b06aa958b6ec1c56254d8cc41a19882625fd1c05" + integrity sha512-uujJGp8jzrrU1UHme8sUKEbawQTcTmUWsh8rbGXYD/lMwNLQ+9jQ9dMDWbbH9Hpoa9RER1BeL/38WzGrbpob2w== + dependencies: + "@smithy/types" "^2.3.4" + "@smithy/util-uri-escape" "^2.0.0" + tslib "^2.5.0" + +"@smithy/querystring-builder@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-2.0.6.tgz#6fd9f86dbfe27e0e71e5569768a2b5d599f44119" + integrity sha512-HnU00shCGoV8vKJZTiNBkNvR9NogU3NIUaVMAGJPSqNGJj3psWo+TUrC0BVCDcwiCljXwXCFGJqIcsWtClrktQ== + dependencies: + "@smithy/types" "^2.3.0" + "@smithy/util-uri-escape" "^2.0.0" + tslib "^2.5.0" + +"@smithy/querystring-parser@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-2.0.10.tgz#074d770a37feafb0d550094dd8463bdff58515f5" + integrity sha512-WSD4EU60Q8scacT5PIpx4Bahn6nWpt+MiYLcBkFt6fOj7AssrNeaNIU2Z0g40ftVmrwLcEOIKGX92ynbVDb3ZA== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/querystring-parser@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-2.0.6.tgz#0b4fc7ec5fe5371113fcb1116216daf2d7e2c3ff" + integrity sha512-i4LKoXHP7pTFAPjLIJyQXYOhWokbcFha3WWsX74sAKmuluv0XM2cxONZoFxwEzmWhsNyM6buSwJSZXyPiec0AQ== + dependencies: + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/service-error-classification@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.0.0.tgz#bbce07c9c529d9333d40db881fd4a1795dd84892" + integrity sha512-2z5Nafy1O0cTf69wKyNjGW/sNVMiqDnb4jgwfMG8ye8KnFJ5qmJpDccwIbJNhXIfbsxTg9SEec2oe1cexhMJvw== + +"@smithy/service-error-classification@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.0.3.tgz#4c7de61d06db5f72437557d429bd74c74988b19e" + integrity sha512-b+m4QCHXb7oKAkM/jHwHrl5gpqhFoMTHF643L0/vAEkegrcUWyh1UjyoHttuHcP5FnHVVy4EtpPtLkEYD+xMFw== + dependencies: + "@smithy/types" "^2.3.4" + +"@smithy/shared-ini-file-loader@^2.0.13": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.13.tgz#aee4b4db2c6fbaa9630b64cb78bfc9da237c8857" + integrity sha512-r6BlDQdYgqDo5xuOOKbmhJD5jylg2Lm1Q1eXZ2mM1kg64GVQ0bHScELEb4W5jl+LEwrU9yNEly6c6ErtU3TJxw== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/shared-ini-file-loader@^2.0.6", "@smithy/shared-ini-file-loader@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.7.tgz#fb4b8394c6a9d3c6b7fd9e3980bcca5366c40503" + integrity sha512-RCpKuofS43eAmmNdJI1Ce3tLdUXuMk/9wX2aj3qXen+uH0jPkbXcQJyvkKtSpIXP9Ty5MJ3nb7nN2iWHR/BfzQ== + dependencies: + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/signature-v4@^2.0.0": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.0.6.tgz#bd0ec98149dfc97e91e227411091e371248309ae" + integrity sha512-4zNTi8w4sky07YKq7oYucZt4ogY00IEaS1NFDXxmCN5V/ywE0WiK+WMim+8wtYQmB0qy3oExZR4LoCAml6j/rA== + dependencies: + "@smithy/eventstream-codec" "^2.0.6" + "@smithy/is-array-buffer" "^2.0.0" + "@smithy/types" "^2.3.0" + "@smithy/util-hex-encoding" "^2.0.0" + "@smithy/util-middleware" "^2.0.0" + "@smithy/util-uri-escape" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@smithy/smithy-client@^2.0.5": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.1.1.tgz#1f27568b76a2232efc3b68fdf8869826830d3c0a" + integrity sha512-AXe7BR3xRrTFepUjY/nJWrOk2fXdgLRNxrnyl8V7weaf+UIaKdPf9dW5hsbJt8V67/X0ofDkNAt92nNKhuQmXw== + dependencies: + "@smithy/middleware-stack" "^2.0.0" + "@smithy/types" "^2.3.0" + "@smithy/util-stream" "^2.0.7" + tslib "^2.5.0" + +"@smithy/smithy-client@^2.1.9": + version "2.1.9" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.1.9.tgz#5a0a185947ae4e66d12d2a6135628dd2fc36924c" + integrity sha512-HTicQSn/lOcXKJT+DKJ4YMu51S6PzbWsO8Z6Pwueo30mSoFKXg5P0BDkg2VCDqCVR0mtddM/F6hKhjW6YAV/yg== + dependencies: + "@smithy/middleware-stack" "^2.0.4" + "@smithy/types" "^2.3.4" + "@smithy/util-stream" "^2.0.14" + tslib "^2.5.0" + +"@smithy/types@^2.2.2", "@smithy/types@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.3.0.tgz#a5c3869465f384fd4d811b2f1f37779e069ef06e" + integrity sha512-pJce3rd39MElkV57UTPAoSYAApjQLELUxjU5adHNLYk9gnPvyIGbJNJTZVVFu00BrgZH3W/cQe8QuFcknDyodQ== + dependencies: + tslib "^2.5.0" + +"@smithy/types@^2.3.4": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.3.4.tgz#3b9bc15000af0a0b1f4fda741f78c1580ba15e92" + integrity sha512-D7xlM9FOMFyFw7YnMXn9dK2KuN6+JhnrZwVt1fWaIu8hCk5CigysweeIT/H/nCo4YV+s8/oqUdLfexbkPZtvqw== + dependencies: + tslib "^2.5.0" + +"@smithy/url-parser@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.0.10.tgz#3261a463b87901d7686f66a9f26efb9f57d8d555" + integrity sha512-4TXQFGjHcqru8aH5VRB4dSnOFKCYNX6SR1Do6fwxZ+ExT2onLsh2W77cHpks7ma26W5jv6rI1u7d0+KX9F0aOw== + dependencies: + "@smithy/querystring-parser" "^2.0.10" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/url-parser@^2.0.5", "@smithy/url-parser@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.0.6.tgz#e926d1bcbe4bb0e244ed25ea58bc48ac5ae41436" + integrity sha512-9i6j5QW6bapHZ4rtkXOAm0hOUG1+5IVdVJXNSUTcNskwJchZH5IQuDNPCbgUi/u2P8EZazKt4wXT51QxOXCz1A== + dependencies: + "@smithy/querystring-parser" "^2.0.6" + "@smithy/types" "^2.3.0" + tslib "^2.5.0" + +"@smithy/util-base64@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-2.0.0.tgz#1beeabfb155471d1d41c8d0603be1351f883c444" + integrity sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA== + dependencies: + "@smithy/util-buffer-from" "^2.0.0" + tslib "^2.5.0" + +"@smithy/util-body-length-browser@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz#5447853003b4c73da3bc5f3c5e82c21d592d1650" + integrity sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg== + dependencies: + tslib "^2.5.0" + +"@smithy/util-body-length-node@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-2.1.0.tgz#313a5f7c5017947baf5fa018bfc22628904bbcfa" + integrity sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw== + dependencies: + tslib "^2.5.0" + +"@smithy/util-buffer-from@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz#7eb75d72288b6b3001bc5f75b48b711513091deb" + integrity sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw== + dependencies: + "@smithy/is-array-buffer" "^2.0.0" + tslib "^2.5.0" + +"@smithy/util-config-provider@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz#4dd6a793605559d94267312fd06d0f58784b4c38" + integrity sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg== + dependencies: + tslib "^2.5.0" + +"@smithy/util-defaults-mode-browser@^2.0.13": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.13.tgz#8136955f1bef6e66cb8a8702693e7685dcd33e26" + integrity sha512-UmmOdUzaQjqdsl1EjbpEaQxM0VDFqTj6zDuI26/hXN7L/a1k1koTwkYpogHMvunDX3fjrQusg5gv1Td4UsGyog== + dependencies: + "@smithy/property-provider" "^2.0.11" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + bowser "^2.11.0" + tslib "^2.5.0" + +"@smithy/util-defaults-mode-browser@^2.0.6": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.7.tgz#322822e064450ec59e3ae288f3f2eed0a5acbfb1" + integrity sha512-s1caKxC7Y87Q72Goll//clZs2WNBfG9WtFDWVRS+Qgk147YPCOUYtkpuD0XZAh/vbayObFz5tQ1fiX4G19HSCA== + dependencies: + "@smithy/property-provider" "^2.0.7" + "@smithy/types" "^2.3.0" + bowser "^2.11.0" + tslib "^2.5.0" + +"@smithy/util-defaults-mode-node@^2.0.15": + version "2.0.16" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.16.tgz#d7cc038cb166acf3f044a74d9d4c72206b1cb9fa" + integrity sha512-HYNqSVTYNGzJsxuhWwiew3zcJ2cDi3ZHz3M0km8ma01AdMd0pYFIGaN24rkXvEOAZPZGRg+3+Wefc3zv8ApRkw== + dependencies: + "@smithy/config-resolver" "^2.0.12" + "@smithy/credential-provider-imds" "^2.0.14" + "@smithy/node-config-provider" "^2.0.14" + "@smithy/property-provider" "^2.0.11" + "@smithy/smithy-client" "^2.1.9" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" + +"@smithy/util-defaults-mode-node@^2.0.6": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.8.tgz#9ab2c932e24b0996bf70f7654987ec541b7733b8" + integrity sha512-lrESm7unVNNkjgLFqcKxer6BUSzb9fPdni/hHmskfE480ScbjU8vBVt4KtQm6MMS2W8suWDCHv/HNK9cx3+ITg== dependencies: - "@types/lodash" "^4.14.123" - lodash "^4.17.11" + "@smithy/config-resolver" "^2.0.6" + "@smithy/credential-provider-imds" "^2.0.8" + "@smithy/node-config-provider" "^2.0.8" + "@smithy/property-provider" "^2.0.7" + "@smithy/types" "^2.3.0" + tslib "^2.5.0" -"@serverless/platform-client@^4.3.2": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@serverless/platform-client/-/platform-client-4.3.2.tgz#10cd3ad8cf452a33528cfb14bbb6003d30a74805" - integrity sha512-DAa5Z0JAZc6UfrTZLYwqoZxgAponZpFwaqd7WzzMA+loMCkYWyJNwxrAmV6cr2UUJpkko4toPZuJ3vM9Ie+NDA== +"@smithy/util-hex-encoding@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz#0aa3515acd2b005c6d55675e377080a7c513b59e" + integrity sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA== dependencies: - adm-zip "^0.5.5" - archiver "^5.3.0" - axios "^0.21.1" - fast-glob "^3.2.7" - https-proxy-agent "^5.0.0" - ignore "^5.1.8" - isomorphic-ws "^4.0.1" - js-yaml "^3.14.1" - jwt-decode "^2.2.0" - minimatch "^3.0.4" - querystring "^0.2.1" - run-parallel-limit "^1.1.0" - throat "^5.0.0" - traverse "^0.6.6" - ws "^7.5.3" + tslib "^2.5.0" -"@serverless/utils@^6.10.0", "@serverless/utils@^6.8.2": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@serverless/utils/-/utils-6.10.0.tgz#6e1b8f23c1b13689cd97d7f4dcc2135d2b8a850d" - integrity sha512-1ScVcT8UUzOsOXZpY6Z/VypyZFVX5/2nmAuttD6bYLVEtavl6w+l33LFQbGLuMIRyV/6ZgaeZeyrszOOs4A2+g== +"@smithy/util-middleware@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.0.0.tgz#706681d4a1686544a2275f68266304233f372c99" + integrity sha512-eCWX4ECuDHn1wuyyDdGdUWnT4OGyIzV0LN1xRttBFMPI9Ff/4heSHVxneyiMtOB//zpXWCha1/SWHJOZstG7kA== dependencies: - archive-type "^4.0.0" - chalk "^4.1.2" - ci-info "^3.8.0" - cli-progress-footer "^2.3.2" - content-disposition "^0.5.4" - d "^1.0.1" - decompress "^4.2.1" - event-emitter "^0.3.5" - ext "^1.7.0" - ext-name "^5.0.0" - file-type "^16.5.4" - filenamify "^4.3.0" - get-stream "^6.0.1" - got "^11.8.6" - inquirer "^8.2.5" - js-yaml "^4.1.0" - jwt-decode "^3.1.2" - lodash "^4.17.21" - log "^6.3.1" - log-node "^8.0.3" - make-dir "^3.1.0" - memoizee "^0.4.15" - ms "^2.1.3" - ncjsm "^4.3.2" - node-fetch "^2.6.9" - open "^8.4.2" - p-event "^4.2.0" - supports-color "^8.1.1" - timers-ext "^0.1.7" - type "^2.7.2" - uni-global "^1.0.0" - uuid "^8.3.2" - write-file-atomic "^4.0.2" + tslib "^2.5.0" -"@sinclair/typebox@^0.24.1": - version "0.24.51" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" - integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== +"@smithy/util-middleware@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.0.3.tgz#478cbf957eaffa36aed624350be342bbf15d3c42" + integrity sha512-+FOCFYOxd2HO7v/0hkFSETKf7FYQWa08wh/x/4KUeoVBnLR4juw8Qi+TTqZI6E2h5LkzD9uOaxC9lAjrpVzaaA== + dependencies: + "@smithy/types" "^2.3.4" + tslib "^2.5.0" -"@sindresorhus/is@^4.0.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== +"@smithy/util-retry@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.0.0.tgz#7ac5d5f12383a9d9b2a43f9ff25f3866c8727c24" + integrity sha512-/dvJ8afrElasuiiIttRJeoS2sy8YXpksQwiM/TcepqdRVp7u4ejd9C4IQURHNjlfPUT7Y6lCDSa2zQJbdHhVTg== + dependencies: + "@smithy/service-error-classification" "^2.0.0" + tslib "^2.5.0" -"@sinonjs/commons@^1.7.0": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" - integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== +"@smithy/util-retry@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.0.3.tgz#a053855ddb51800bd679da03454cf626bc440918" + integrity sha512-gw+czMnj82i+EaH7NL7XKkfX/ZKrCS2DIWwJFPKs76bMgkhf0y1C94Lybn7f8GkBI9lfIOUdPYtzm19zQOC8sw== dependencies: - type-detect "4.0.8" + "@smithy/service-error-classification" "^2.0.3" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== +"@smithy/util-stream@^2.0.14": + version "2.0.14" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.0.14.tgz#3fdd934e2bced80331dcaff18aefbcfe39ebf3cd" + integrity sha512-XjvlDYe+9DieXhLf7p+EgkXwFtl34kHZcWfHnc5KaILbhyVfDLWuqKTFx6WwCFqb01iFIig8trGwExRIqqkBYg== + dependencies: + "@smithy/fetch-http-handler" "^2.2.1" + "@smithy/node-http-handler" "^2.1.6" + "@smithy/types" "^2.3.4" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-buffer-from" "^2.0.0" + "@smithy/util-hex-encoding" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@smithy/util-stream@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.0.7.tgz#9c9f489e292eac7693fba2b8360d33ec95fda382" + integrity sha512-GFgvPt5+lPx5Fmx0esCwOuDipoIatiTnUPFW5QwkrfxKNYcPwKvhzu9iFzOiHcj2WwRQsA6YBRRdeBttdAG/HA== + dependencies: + "@smithy/fetch-http-handler" "^2.1.1" + "@smithy/node-http-handler" "^2.1.1" + "@smithy/types" "^2.3.0" + "@smithy/util-base64" "^2.0.0" + "@smithy/util-buffer-from" "^2.0.0" + "@smithy/util-hex-encoding" "^2.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.5.0" + +"@smithy/util-uri-escape@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz#19955b1a0f517a87ae77ac729e0e411963dfda95" + integrity sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw== dependencies: - "@sinonjs/commons" "^1.7.0" + tslib "^2.5.0" + +"@smithy/util-utf8@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.0.0.tgz#b4da87566ea7757435e153799df9da717262ad42" + integrity sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ== + dependencies: + "@smithy/util-buffer-from" "^2.0.0" + tslib "^2.5.0" + +"@smithy/util-waiter@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-2.0.10.tgz#6cd28af8340ab54fa9adf10d193c4476a5673363" + integrity sha512-yQjwWVrwYw+/f3hFQccE3zZF7lk6N6xtNcA6jvhWFYhnyKAm6B2mX8Gzftl0TbgoPUpzCvKYlvhaEpVtRpVfVw== + dependencies: + "@smithy/abort-controller" "^2.0.10" + "@smithy/types" "^2.3.4" + tslib "^2.5.0" "@sqltools/formatter@^1.2.5": version "1.2.5" resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12" integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== +"@swc/helpers@^0.3.13": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.3.17.tgz#7c1b91f43c77e2bba99492162a498d465ef253d5" + integrity sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q== + dependencies: + tslib "^2.4.0" + "@szmarczak/http-timer@^4.0.5": version "4.0.6" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" @@ -3850,14 +5447,18 @@ dependencies: "@ucast/core" "^1.4.1" -"@undp/carbon-credit-calculator@../../libs/carbon-credit-calculator": +"@undp/carbon-credit-calculator@^1.0.0": version "1.0.0" + resolved "https://registry.yarnpkg.com/@undp/carbon-credit-calculator/-/carbon-credit-calculator-1.0.0.tgz#fbdfbb606cb7bd402ed74887dfc1f0861cfca892" + integrity sha512-7wbGm7uEYdRBWlKzATKIhFLd9Zip8yxLCi3cfAcufb5kACw8ZKqtbn+08EyZQiJbDoPB3ouM6Dx8Dl+FnqqPVg== dependencies: "@types/node" "^18.11.9" convert-units "^2.3.4" -"@undp/serial-number-gen@../../libs/serial-number-gen": - version "1.0.0" +"@undp/serial-number-gen@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@undp/serial-number-gen/-/serial-number-gen-1.0.1.tgz#0615f9d547334f6837f0588e0df2f6cc89ab61c2" + integrity sha512-skIbmfcR70WmDoWe7REPwpK6EPM83fEtPCMy146eqNQ34FsMX92Yv9HqH/h2jtK/KmcwKotjbMJsmJqR7EwCqQ== "@vendia/serverless-express@^3.4.0": version "3.4.0" @@ -4344,7 +5945,7 @@ aws-lambda@^1.0.7: js-yaml "^3.14.1" watchpack "^2.0.0-beta.10" -aws-sdk@^2.1046.0, aws-sdk@^2.1342.0, aws-sdk@^2.814.0: +aws-sdk@^2.1046.0, aws-sdk@^2.1342.0: version "2.1351.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1351.0.tgz#d691555150791b0957c4b9715cd15a901a86e013" integrity sha512-/Hj9lmxFO2eBipUGY2CL5rNhoZO4PrXOYQ6C+nQ0ffzp+bmYc0nzKwO7xrGreVIefrVbbikQyItiDL3PmBRnGw== @@ -4360,6 +5961,22 @@ aws-sdk@^2.1046.0, aws-sdk@^2.1342.0, aws-sdk@^2.814.0: uuid "8.0.0" xml2js "0.4.19" +aws-sdk@^2.814.0: + version "2.1453.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1453.0.tgz#c6f92e8692a512d3370eb2f40e6d724a1b19fdab" + integrity sha512-pNkz4gAuR2nnOAvq6P2/0wvcyQDY112VYQS4w+vqWcxwEuptcWmTynd8BH3foUHnwPaU+Z/BR6DaTnBSjOzR+Q== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.16.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + util "^0.12.4" + uuid "8.0.0" + xml2js "0.5.0" + aws-serverless-express@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/aws-serverless-express/-/aws-serverless-express-3.4.0.tgz#74153b8cc80dbd2c6a32a51e6d353a325c2710d7" @@ -4678,7 +6295,12 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.0.2, base64-js@^1.3.1: +base64-js@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" + integrity sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw== + +base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -4761,6 +6383,11 @@ body-parser@1.20.2: type-is "~1.6.18" unpipe "1.0.0" +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + bowser@^2.11.0: version "2.11.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" @@ -4807,6 +6434,13 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +brotli@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.3.tgz#7365d8cc00f12cf765d2b2c898716bcf4b604d48" + integrity sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg== + dependencies: + base64-js "^1.1.2" + browser-pack@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.1.0.tgz#c34ba10d0b9ce162b5af227c7131c92c2ecd5774" @@ -5129,6 +6763,54 @@ caniuse-lite@^1.0.30001449: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz#13b6fe301a831fe666cce8ca4ef89352334133d5" integrity sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q== +carbon-services-lib@0.0.237: + version "0.0.237" + resolved "https://registry.yarnpkg.com/carbon-services-lib/-/carbon-services-lib-0.0.237.tgz#f59894e51f561bee5566e5bae8c28a1e403d330f" + integrity sha512-qN4/EBBeDgYTHOV5iWhbxeGF6qBoaGLqLaI6IW+/95lkxzQKazmcnwWi42eEU1hn78QMnohDJBHiIcVpQj36dA== + dependencies: + "@aws-sdk/client-qldb" "^3.408.0" + "@aws-sdk/client-qldb-session" "^3.408.0" + "@aws-sdk/client-s3" "^3.408.0" + "@aws-sdk/client-sqs" "^3.408.0" + "@casl/ability" "^6.3.2" + "@drdgvhbh/postgres-error-codes" "^0.0.6" + "@nestjs/common" "^9.0.0" + "@nestjs/config" "^2.2.0" + "@nestjs/core" "^9.0.0" + "@nestjs/jwt" "^10.0.0" + "@nestjs/passport" "^9.0.0" + "@nestjs/platform-express" "^9.0.0" + "@nestjs/swagger" "^6.1.3" + "@nestjs/typeorm" "^9.0.1" + "@undp/carbon-credit-calculator" "^1.0.0" + "@undp/serial-number-gen" "^1.0.0" + amazon-qldb-driver-nodejs "^3.0.1" + aws-kinesis-agg "^4.2.6" + aws-lambda "^1.0.7" + aws-serverless-express "^3.4.0" + axios "^1.2.4" + cheerio "^1.0.0-rc.12" + class-transformer "^0.5.1" + class-validator "^0.14.0" + dotenv-flow "^3.2.0" + fs "^0.0.1-security" + ion-js "^4.3.0" + jsbi "^4.3.0" + nanoid "3.3.4" + nest-winston "^1.8.0" + nestjs-i18n "^10.2.6" + nodemailer "^6.8.0" + passport "^0.6.0" + passport-headerapikey "^1.2.2" + passport-jwt "^4.0.0" + passport-local "^1.0.0" + pg "^8.8.0" + reflect-metadata "^0.1.13" + rimraf "^3.0.2" + rxjs "^7.2.0" + typeorm "^0.3.10" + winston "^3.8.2" + chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -5161,6 +6843,31 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0-rc.12: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.0.1" + htmlparser2 "^8.0.1" + parse5 "^7.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + child-process-ext@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/child-process-ext/-/child-process-ext-2.1.1.tgz#f7cf4e68fef60c4c8ee911e1b402413191467dc3" @@ -5336,6 +7043,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== +clone@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -5640,6 +7352,27 @@ crypto-browserify@^3.0.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-js@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" + integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" @@ -5742,6 +7475,30 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-equal@^2.0.5: + version "2.2.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.2.tgz#9b2635da569a13ba8e1cc159c2f744071b115daa" + integrity sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.1" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -5780,7 +7537,7 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.1.4: +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== @@ -5853,6 +7610,11 @@ dezalgo@^1.0.4: asap "^2.0.0" wrappy "1" +dfa@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/dfa/-/dfa-1.2.0.tgz#96ac3204e2d29c49ea5b57af8d92c2ae12790657" + integrity sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q== + diff-sequences@^28.1.1: version "28.1.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" @@ -5886,11 +7648,41 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + domain-browser@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dotenv-expand@10.0.0, dotenv-expand@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" @@ -6003,6 +7795,11 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0: graceful-fs "^4.2.4" tapable "^2.2.0" +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -6050,6 +7847,21 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: unbox-primitive "^1.0.2" which-typed-array "^1.1.9" +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + es-module-lexer@^0.9.0: version "0.9.3" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" @@ -6491,6 +8303,13 @@ fast-xml-parser@4.1.2: dependencies: strnum "^1.0.5" +fast-xml-parser@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" + integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== + dependencies: + strnum "^1.0.5" + fastest-levenshtein@^1.0.16: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -6664,6 +8483,21 @@ follow-redirects@^1.14.0, follow-redirects@^1.15.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +fontkit@^1.8.1: + version "1.9.0" + resolved "https://registry.yarnpkg.com/fontkit/-/fontkit-1.9.0.tgz#95729cc9f24995fb068ea53aea2f1f193e323f2b" + integrity sha512-HkW/8Lrk8jl18kzQHvAw9aTHe1cqsyx5sDnxncx652+CIfhawokEPkeM3BoIC+z/Xv7a0yMr0f3pRRwhGH455g== + dependencies: + "@swc/helpers" "^0.3.13" + brotli "^1.3.2" + clone "^2.1.2" + deep-equal "^2.0.5" + dfa "^1.2.0" + restructure "^2.0.1" + tiny-inflate "^1.0.3" + unicode-properties "^1.3.1" + unicode-trie "^2.0.0" + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -6832,7 +8666,7 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functions-have-names@^1.2.2: +functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -6861,6 +8695,16 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@ has "^1.0.3" has-symbols "^1.0.3" +get-intrinsic@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -7129,6 +8973,16 @@ htmlescape@^1.1.0: resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" integrity sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg== +htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + http-cache-semantics@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" @@ -7324,7 +9178,7 @@ insert-module-globals@^7.0.0: undeclared-identifiers "^1.1.2" xtend "^4.0.0" -internal-slot@^1.0.5: +internal-slot@^1.0.4, internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== @@ -7353,7 +9207,7 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-arguments@^1.0.4: +is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -7419,7 +9273,7 @@ is-core-module@^2.11.0: dependencies: has "^1.0.3" -is-date-object@^1.0.1: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -7465,6 +9319,11 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-natural-number@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" @@ -7510,6 +9369,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -7562,6 +9426,11 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -7569,6 +9438,14 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -7581,6 +9458,11 @@ isarray@^1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -8274,6 +10156,14 @@ lie@~3.3.0: dependencies: immediate "~3.0.5" +linebreak@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/linebreak/-/linebreak-1.1.0.tgz#831cf378d98bced381d8ab118f852bd50d81e46b" + integrity sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ== + dependencies: + base64-js "0.0.8" + unicode-trie "^2.0.0" + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -9053,6 +10943,13 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -9068,6 +10965,14 @@ object-inspect@^1.12.3, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -9266,6 +11171,11 @@ packet-reader@1.0.0: resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== +pako@^0.2.5: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== + pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -9313,6 +11223,14 @@ parse5-htmlparser2-tree-adapter@^6.0.0: dependencies: parse5 "^6.0.1" +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + parse5@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" @@ -9323,6 +11241,13 @@ parse5@^6.0.1: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -9457,6 +11382,16 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +pdfkit@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.13.0.tgz#da4c2becd63a129e3aae448fdaed4ee7be790f8f" + integrity sha512-AW79eHU5eLd2vgRDS9z3bSoi0FA+gYm+100LLosrQQMLUzOBGVOhG7ABcMFpJu7Bpg+MT74XYHi4k9EuU/9EZw== + dependencies: + crypto-js "^4.0.0" + fontkit "^1.8.1" + linebreak "^1.0.2" + png-js "^1.0.0" + peek-readable@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" @@ -9567,6 +11502,11 @@ pluralize@8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== +png-js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.0.0.tgz#e5484f1e8156996e383aceebb3789fd75df1874d" + integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g== + postgres-array@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" @@ -9895,6 +11835,15 @@ regexp.prototype.flags@^1.4.3: define-properties "^1.1.3" functions-have-names "^1.2.2" +regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" + regexpu-core@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" @@ -9975,6 +11924,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +restructure@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/restructure/-/restructure-2.0.1.tgz#4199745466cfc9bb9e1647746a4c902b7b0049d1" + integrity sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg== + retry@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" @@ -10485,6 +12439,13 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + stream-browserify@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" @@ -10918,6 +12879,11 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" +tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" + integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -11076,6 +13042,11 @@ tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -11245,11 +13216,27 @@ unicode-match-property-value-ecmascript@^2.1.0: resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== +unicode-properties@^1.3.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unicode-properties/-/unicode-properties-1.4.1.tgz#96a9cffb7e619a0dc7368c28da27e05fc8f9be5f" + integrity sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg== + dependencies: + base64-js "^1.3.0" + unicode-trie "^2.0.0" + unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== +unicode-trie@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-trie/-/unicode-trie-2.0.0.tgz#8fd8845696e2e14a8b67d78fa9e0dd2cad62fec8" + integrity sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ== + dependencies: + pako "^0.2.5" + tiny-inflate "^1.0.0" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -11485,6 +13472,16 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + which-typed-array@^1.1.2, which-typed-array@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" @@ -11605,6 +13602,14 @@ xml2js@0.4.19: sax ">=0.6.0" xmlbuilder "~9.0.1" +xml2js@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7" + integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + xml2js@^0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" diff --git a/docker-compose-image.yml b/docker-compose-image.yml index 608928331..2889720c1 100644 --- a/docker-compose-image.yml +++ b/docker-compose-image.yml @@ -21,7 +21,7 @@ services: - ./init.sql:/docker-entrypoint-initdb.d/init.sql - data:/data/postgres national: - image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-services:latest + image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-services:CARBON-15 # build: # context: . # dockerfile: ./backend/services/Dockerfile @@ -40,15 +40,20 @@ services: logoBase64: "sss" IS_EMAIL_DISABLED: "true" LOCATION_SERVICE: OPENSTREET + ASYNC_OPERATIONS_TYPE: Database HOST: "http://localhost:3030" + DOMAIN_MAP: "true" EXPIRES_IN: "7200" + SYSTEM_TYPE: CARBON_REGISTRY_SYSTEM volumes: - filestore:/app/backend/services/public + - ./users.csv:/app/backend/services/users.csv + - ./organisations.csv:/app/backend/services/organisations.csv stats: # build: # context: . # dockerfile: ./backend/services/Dockerfile - image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-services:latest + image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-services:CARBON-15 ports: - "3100:3100" depends_on: @@ -60,8 +65,9 @@ services: DB_PASSWORD: "" RUN_PORT: 3100 RUN_MODULE: analytics-api + DOMAIN_MAP: "true" replicator: - image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-services:latest + image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-services:CARBON-15 # build: # context: . # dockerfile: ./backend/services/Dockerfile @@ -82,8 +88,12 @@ services: ITMO_API_KEY: "" ITMO_EMAIL: "" ITMO_PASSWORD: "" + SYNC_ENDPOINT: 'http://192.168.123.20:9000' + SYNC_API_TOKEN: '' + SYNC_ENABLE: true + SYSTEM_TYPE: CARBON_REGISTRY_SYSTEM web: - image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-web:latest + image: 302213478610.dkr.ecr.us-east-1.amazonaws.com/carbon-web:CARBON-15 # build: # context: . # dockerfile: ./web/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index e47ac820f..73c704c8b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,6 +43,8 @@ services: HOST: "http://localhost:3030" DOMAIN_MAP: "true" EXPIRES_IN: "7200" + SYSTEM_TYPE: CARBON_REGISTRY_SYSTEM + SYSTEM_NAME: Carbon Registry volumes: - filestore:/app/backend/services/public - ./users.csv:/app/backend/services/users.csv @@ -84,9 +86,10 @@ services: ITMO_API_KEY: "" ITMO_EMAIL: "" ITMO_PASSWORD: "" - MRV_ENDPOINT: 'http://192.168.123.20:9000' - REGISTRY_SYNC_ENABLE: true - MRV_API_TOKEN: '' + SYNC_ENDPOINT: 'http://192.168.123.20:9000' + SYNC_API_TOKEN: '' + SYNC_ENABLE: true + SYSTEM_TYPE: CARBON_REGISTRY_SYSTEM # async-operations-handler: # build: # context: . @@ -114,6 +117,7 @@ services: REACT_APP_COUNTRY_FLAG_URL: "https://carbon-common-dev.s3.amazonaws.com/flag.png" REACT_APP_COUNTRY_CODE: "NG" REACT_APP_MAP_TYPE: "None" + REACT_APP_ENABLE_REGISTRATION: true ports: - "3030:3030" depends_on: diff --git a/libs/carbon-credit-calculator/jest.config.js b/libs/carbon-credit-calculator/jest.config.js deleted file mode 100644 index b413e106d..000000000 --- a/libs/carbon-credit-calculator/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', -}; \ No newline at end of file diff --git a/libs/carbon-credit-calculator/package.json b/libs/carbon-credit-calculator/package.json deleted file mode 100644 index 3ef743ffa..000000000 --- a/libs/carbon-credit-calculator/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@undp/carbon-credit-calculator", - "version": "1.0.0", - "description": "Carbon Credit Calculator", - "main": "./dist/esm/index.js", - "module": "./dist/cjs/index.js", - "license": "MIT", - "scripts": { - "devBuild": "yarn install && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json", - "build": "yarn install --production && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json", - "prepublishOnly": "yarn install --production && yarn run build", - "test": "jest --coverage" - }, - "files": [ - "dist/" - ], - "devDependencies": { - "@types/jest": "^29.2.3", - "jest": "^29.3.1", - "ts-jest": "^29.0.3", - "typescript": "^4.8.4" - }, - "dependencies": { - "@types/node": "^18.11.9", - "convert-units": "^2.3.4" - }, - "types": "./dist/esm/index.d.ts", - "repository": { - "type": "git", - "url": "git+https://github.com/xeptagondev/carbon-registry.git#develop" - }, - "author": "UNDP", - "bugs": { - "url": "https://github.com/xeptagondev/carbon-registry/issues" - }, - "homepage": "https://github.com/xeptagondev/carbon-registry/tree/develop#readme" -} diff --git a/libs/carbon-credit-calculator/src/calculator.test.ts b/libs/carbon-credit-calculator/src/calculator.test.ts deleted file mode 100644 index 6036460bf..000000000 --- a/libs/carbon-credit-calculator/src/calculator.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { calculateCredit } from "./calculator"; -import { AgricultureCreationRequest } from "./requests/agricultureCreationRequest"; -import { SolarCreationRequest } from "./requests/solarCreationRequest"; - -describe("Agriculture calculation", () => { - it("example", () => { - const req = new AgricultureCreationRequest(); - req.duration = 120 - req.durationUnit = 'd' - req.landArea = 16 - req.landAreaUnit = 'ha' - expect(calculateCredit(req)).toBe(88.32); - }); - - it("km2 test", () => { - const req = new AgricultureCreationRequest(); - req.duration = 120 - req.durationUnit = 'd' - req.landArea = 0.16 - req.landAreaUnit = 'km2' - expect(calculateCredit(req)).toBe(88.32); - }); - - it("hours test", () => { - const req = new AgricultureCreationRequest(); - req.duration = 2880 - req.durationUnit = 'h' - req.landArea = 0.16 - req.landAreaUnit = 'km2' - expect(calculateCredit(req)).toBe(88.32); - }); - - it("example 2", () => { - const req = new AgricultureCreationRequest(); - req.duration = 365 - req.durationUnit = 'd' - req.landArea = 50 - req.landAreaUnit = 'ha' - expect(calculateCredit(req)).toBe(839.5); - }); - - it("test error", () => { - const req = new AgricultureCreationRequest(); - req.duration = 365 - req.durationUnit = 'd' - req.landArea = 50 - req.landAreaUnit = 'ha' - req.agricultureConstants.emissionFactorUnit = "km" - expect(() => calculateCredit(req)).toThrow("Invalid emission factor unit km"); - }); -}); - -describe("Solar calculation", () => { - it("example1", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 20 - req.energyGenerationUnit = 'kWh/year/unit' - req.buildingType = 'Household' - expect(calculateCredit(req)).toBe(0.136); - }); - - it("example1 MWh", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 0.020 - req.energyGenerationUnit = 'MWh/year/unit' - req.buildingType = 'Household' - expect(calculateCredit(req)).toBe(0.136); - }); - - it("example2", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 105 - req.energyGenerationUnit = 'kWh/year/unit' - req.buildingType = 'Household' - expect(calculateCredit(req)).toBe(0.439); - }); - - it("example2 MWh", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 0.105 - req.energyGenerationUnit = 'MWh/year/unit' - req.buildingType = 'Household' - expect(calculateCredit(req)).toBe(0.439); - }); - - it("example1 error", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 20 - req.energyGenerationUnit = 'kWh/year/unit' - req.buildingType = 'Household' - req.solarConstants.emissionFactorUnit = "m" - expect(() => calculateCredit(req)).toThrow("Invalid emission factor unit m"); - }); - - it("example1 error 2", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 20 - req.buildingType = 'Household' - req.energyGenerationUnit = 'km' - expect(() => calculateCredit(req)).toThrow("Invalid measured unit km"); - }); - - it("example1 error build type", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 20 - req.buildingType = 'TestType' - req.energyGenerationUnit = 'kWh/year/unit' - expect(() => calculateCredit(req)).toThrow("Invalid building type TestType"); - }); - - it("Rounding issue fix", () => { - const req = new SolarCreationRequest(); - req.energyGeneration = 8520000000 - req.buildingType = 'TestType' - req.solarConstants.buildingTypes = { - 'TestType': 825 - }; - req.energyGenerationUnit = 'Wh/year/unit' - expect(calculateCredit(req)).toBe(11080.538); - }); -}); \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/calculator.ts b/libs/carbon-credit-calculator/src/calculator.ts deleted file mode 100644 index 6d9a27222..000000000 --- a/libs/carbon-credit-calculator/src/calculator.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { AgricultureCal } from "./calculators/agricultureCal"; -import { SolarCal } from "./calculators/solarCal"; -import { AgricultureCreationRequest } from "./requests/agricultureCreationRequest"; -import { CreditCreationRequest } from "./requests/creditCreationRequest"; -import { SolarCreationRequest } from "./requests/solarCreationRequest"; - -export const PRECISION = 2 -export const calculateCredit = (request: CreditCreationRequest): number => { - if (request instanceof AgricultureCreationRequest) { - return AgricultureCal.calculate(request) - } else if (request instanceof SolarCreationRequest) { - return SolarCal.calculate(request) - } else { - throw Error("Not implemented") - } -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/calculators/agricultureCal.ts b/libs/carbon-credit-calculator/src/calculators/agricultureCal.ts deleted file mode 100644 index dd49a2387..000000000 --- a/libs/carbon-credit-calculator/src/calculators/agricultureCal.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { PRECISION } from "../calculator"; -import { AgricultureCreationRequest } from "../requests/agricultureCreationRequest"; -var convert = require('convert-units') - -export class AgricultureCal { - public static calculate(req: AgricultureCreationRequest): number { - const constants = req.agricultureConstants; - const unitParts = constants.emissionFactorUnit.split('/') - if (unitParts.length != 3) { - throw Error("Invalid emission factor unit " + constants.emissionFactorUnit) - } - const landArea = convert(req.landArea).from(req.landAreaUnit).to(unitParts[1]); - const duration = convert(req.duration).from(req.durationUnit).to(unitParts[2]); - return Number((constants.emissionFactor * landArea * duration).toFixed(PRECISION)) - } -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/calculators/solarCal.ts b/libs/carbon-credit-calculator/src/calculators/solarCal.ts deleted file mode 100644 index b50aa461f..000000000 --- a/libs/carbon-credit-calculator/src/calculators/solarCal.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { PRECISION } from "../calculator"; -import { SolarCreationRequest } from "../requests/solarCreationRequest"; - -var convert = require('convert-units') - -export class SolarCal { - public static calculate(req: SolarCreationRequest): number { - const constants = req.solarConstants; - const emissionUnitParts = constants.emissionFactorUnit.split('/') - if (emissionUnitParts.length != 2) { - throw Error("Invalid emission factor unit " + constants.emissionFactorUnit) - } - - const measuredUnitParts = req.energyGenerationUnit.split('/') - if (measuredUnitParts.length != 3) { - throw Error("Invalid measured unit " + req.energyGenerationUnit) - } - - let threshold = constants.buildingTypes[req.buildingType]; - if (!threshold) { - throw Error("Invalid building type " + req.buildingType) - } - - if (req.energyGenerationUnit != constants.thresholdUnit) { - const thresholdUnitParts = constants.thresholdUnit.split('/') - if (thresholdUnitParts.length != 2) { - throw Error("Invalid threshold unit " + constants.thresholdUnit) - } - - let factor = convert(1).from(thresholdUnitParts[0]).to(measuredUnitParts[0]); - factor = factor / convert(1).from(thresholdUnitParts[1]).to(measuredUnitParts[1]); - threshold = Number(threshold * factor) - } - - const unitX = convert(1).from(measuredUnitParts[0]).to(emissionUnitParts[1]); - - const highFactor = Number(constants.highEmissionFactor * unitX); - const lowFactor = Number(constants.lowEmissionFactor * unitX); - - let value; - if (req.energyGeneration < threshold) { - value = req.energyGeneration * highFactor; - } else { - value = threshold * highFactor + (req.energyGeneration - threshold) * lowFactor; - } - return Number(value.toFixed(PRECISION)) - } -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/constants/agricultureConstants.ts b/libs/carbon-credit-calculator/src/constants/agricultureConstants.ts deleted file mode 100644 index 6dac89402..000000000 --- a/libs/carbon-credit-calculator/src/constants/agricultureConstants.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { SubSectorConstants } from "./subSectorConstants"; - -export class AgricultureConstants implements SubSectorConstants { - emissionFactor: number = 0.046; - emissionFactorUnit: string = "tCO2e/ha/d"; -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/constants/building.type.enum.ts b/libs/carbon-credit-calculator/src/constants/building.type.enum.ts deleted file mode 100644 index 22b5cce24..000000000 --- a/libs/carbon-credit-calculator/src/constants/building.type.enum.ts +++ /dev/null @@ -1,11 +0,0 @@ -export enum BuildingType { - Household = "Household", - HealthCenter = "HealthCenter", - Dispensary = "Dispensary", - School = "School", - PrimarySchool = "PrimarySchool", - SecondarySchool = "SecondarySchool", - PublicAdministration = "PublicAdministration", - TradingPlace = "TradingPlace", - BusStop = "BusStop", -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/constants/solarConstants.ts b/libs/carbon-credit-calculator/src/constants/solarConstants.ts deleted file mode 100644 index 956c528de..000000000 --- a/libs/carbon-credit-calculator/src/constants/solarConstants.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { BuildingType } from "./building.type.enum"; -import { SubSectorConstants } from "./subSectorConstants"; - -export class SolarConstants implements SubSectorConstants { - highEmissionFactor: number = 6.8; - lowEmissionFactor: number = 1.3; - emissionFactorUnit: string = "tCO2/MWh"; - thresholdUnit: string = "kWh/year"; - buildingTypes: { [k: string] : number } = { - Household : 55, - HealthCenter: 825, - Dispensary: 825, - School: 275, - PrimarySchool: 275, - SecondarySchool: 275, - PublicAdministration: 55, - TradingPlace: 825, - BusStop: 200, - } -} - diff --git a/libs/carbon-credit-calculator/src/constants/subSectorConstants.ts b/libs/carbon-credit-calculator/src/constants/subSectorConstants.ts deleted file mode 100644 index e31cbb5e0..000000000 --- a/libs/carbon-credit-calculator/src/constants/subSectorConstants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export interface SubSectorConstants { -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/index.ts b/libs/carbon-credit-calculator/src/index.ts deleted file mode 100644 index ca6f9d077..000000000 --- a/libs/carbon-credit-calculator/src/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { calculateCredit } from './calculator' -import { AgricultureConstants } from './constants/agricultureConstants'; -import { BuildingType } from './constants/building.type.enum'; -import { SolarConstants } from './constants/solarConstants'; -import { SubSectorConstants } from './constants/subSectorConstants'; -import { AgricultureCreationRequest } from './requests/agricultureCreationRequest'; -import { CreditCreationRequest } from './requests/creditCreationRequest'; -import { SolarCreationRequest } from './requests/solarCreationRequest'; - -export { - calculateCredit, - CreditCreationRequest, - SubSectorConstants, - SolarCreationRequest, - AgricultureCreationRequest, - AgricultureConstants, - SolarConstants, - BuildingType -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/requests/agricultureCreationRequest.ts b/libs/carbon-credit-calculator/src/requests/agricultureCreationRequest.ts deleted file mode 100644 index afb48fb47..000000000 --- a/libs/carbon-credit-calculator/src/requests/agricultureCreationRequest.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { AgricultureConstants } from "../constants/agricultureConstants"; -import { CreditCreationRequest } from "./creditCreationRequest"; - -export class AgricultureCreationRequest implements CreditCreationRequest { - landArea!: number; - landAreaUnit!: string; - duration!: number; - durationUnit!: string; - agricultureConstants: AgricultureConstants = new AgricultureConstants(); - - -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/requests/creditCreationRequest.ts b/libs/carbon-credit-calculator/src/requests/creditCreationRequest.ts deleted file mode 100644 index e88484890..000000000 --- a/libs/carbon-credit-calculator/src/requests/creditCreationRequest.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface CreditCreationRequest { - -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/src/requests/solarCreationRequest.ts b/libs/carbon-credit-calculator/src/requests/solarCreationRequest.ts deleted file mode 100644 index ae2e439cd..000000000 --- a/libs/carbon-credit-calculator/src/requests/solarCreationRequest.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { SolarConstants } from "../constants/solarConstants"; -import { CreditCreationRequest } from "./creditCreationRequest"; - -export class SolarCreationRequest implements CreditCreationRequest { - energyGeneration!: number; - energyGenerationUnit!: string; - buildingType!: string; - solarConstants: SolarConstants = new SolarConstants() -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/tsconfig-cjs.json b/libs/carbon-credit-calculator/tsconfig-cjs.json deleted file mode 100644 index 45e278a2c..000000000 --- a/libs/carbon-credit-calculator/tsconfig-cjs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "CommonJS", - "outDir": "./dist/cjs" - }, -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/tsconfig.json b/libs/carbon-credit-calculator/tsconfig.json deleted file mode 100644 index 8d4453624..000000000 --- a/libs/carbon-credit-calculator/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "target": "es2017", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "outDir": "./dist/esm", - "declaration": true - }, - "include": [ - "./src" - ], - "exclude": [ - "**/*.test.ts", - ] -} \ No newline at end of file diff --git a/libs/carbon-credit-calculator/yarn.lock b/libs/carbon-credit-calculator/yarn.lock deleted file mode 100644 index 804dedc34..000000000 --- a/libs/carbon-credit-calculator/yarn.lock +++ /dev/null @@ -1,2312 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== - dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/compat-data@^7.20.0": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" - integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== - -"@babel/core@^7.11.6", "@babel/core@^7.12.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.2.tgz#8dc9b1620a673f92d3624bd926dc49a52cf25b92" - integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.2" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-module-transforms" "^7.20.2" - "@babel/helpers" "^7.20.1" - "@babel/parser" "^7.20.2" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" - -"@babel/generator@^7.20.1", "@babel/generator@^7.20.2", "@babel/generator@^7.7.2": - version "7.20.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.4.tgz#4d9f8f0c30be75fd90a0562099a26e5839602ab8" - integrity sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA== - dependencies: - "@babel/types" "^7.20.2" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" - -"@babel/helper-compilation-targets@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" - integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== - dependencies: - "@babel/compat-data" "^7.20.0" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - semver "^6.3.0" - -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-transforms@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" - integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.2" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== - -"@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== - dependencies: - "@babel/types" "^7.20.2" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helpers@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.1.tgz#2ab7a0fcb0a03b5bf76629196ed63c2d7311f4c9" - integrity sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg== - dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.1" - "@babel/types" "^7.20.0" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2" - integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg== - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.7.2": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" - integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - -"@babel/template@^7.18.10", "@babel/template@^7.3.3": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" - -"@babel/traverse@^7.20.1", "@babel/traverse@^7.7.2": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.1.tgz#9b15ccbf882f6d107eeeecf263fbcdd208777ec8" - integrity sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.1" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.1" - "@babel/types" "^7.20.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842" - integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog== - dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.3.1.tgz#3e3f876e4e47616ea3b1464b9fbda981872e9583" - integrity sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg== - dependencies: - "@jest/types" "^29.3.1" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^29.3.1" - jest-util "^29.3.1" - slash "^3.0.0" - -"@jest/core@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.3.1.tgz#bff00f413ff0128f4debec1099ba7dcd649774a1" - integrity sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw== - dependencies: - "@jest/console" "^29.3.1" - "@jest/reporters" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^29.2.0" - jest-config "^29.3.1" - jest-haste-map "^29.3.1" - jest-message-util "^29.3.1" - jest-regex-util "^29.2.0" - jest-resolve "^29.3.1" - jest-resolve-dependencies "^29.3.1" - jest-runner "^29.3.1" - jest-runtime "^29.3.1" - jest-snapshot "^29.3.1" - jest-util "^29.3.1" - jest-validate "^29.3.1" - jest-watcher "^29.3.1" - micromatch "^4.0.4" - pretty-format "^29.3.1" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.3.1.tgz#eb039f726d5fcd14698acd072ac6576d41cfcaa6" - integrity sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag== - dependencies: - "@jest/fake-timers" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/node" "*" - jest-mock "^29.3.1" - -"@jest/expect-utils@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.3.1.tgz#531f737039e9b9e27c42449798acb5bba01935b6" - integrity sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g== - dependencies: - jest-get-type "^29.2.0" - -"@jest/expect@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.3.1.tgz#456385b62894349c1d196f2d183e3716d4c6a6cd" - integrity sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg== - dependencies: - expect "^29.3.1" - jest-snapshot "^29.3.1" - -"@jest/fake-timers@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.3.1.tgz#b140625095b60a44de820876d4c14da1aa963f67" - integrity sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A== - dependencies: - "@jest/types" "^29.3.1" - "@sinonjs/fake-timers" "^9.1.2" - "@types/node" "*" - jest-message-util "^29.3.1" - jest-mock "^29.3.1" - jest-util "^29.3.1" - -"@jest/globals@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.3.1.tgz#92be078228e82d629df40c3656d45328f134a0c6" - integrity sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q== - dependencies: - "@jest/environment" "^29.3.1" - "@jest/expect" "^29.3.1" - "@jest/types" "^29.3.1" - jest-mock "^29.3.1" - -"@jest/reporters@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.3.1.tgz#9a6d78c109608e677c25ddb34f907b90e07b4310" - integrity sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" - "@jridgewell/trace-mapping" "^0.3.15" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^29.3.1" - jest-util "^29.3.1" - jest-worker "^29.3.1" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^29.0.0": - version "29.0.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" - integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== - dependencies: - "@sinclair/typebox" "^0.24.1" - -"@jest/source-map@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" - integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== - dependencies: - "@jridgewell/trace-mapping" "^0.3.15" - callsites "^3.0.0" - graceful-fs "^4.2.9" - -"@jest/test-result@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.3.1.tgz#92cd5099aa94be947560a24610aa76606de78f50" - integrity sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw== - dependencies: - "@jest/console" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz#fa24b3b050f7a59d48f7ef9e0b782ab65123090d" - integrity sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA== - dependencies: - "@jest/test-result" "^29.3.1" - graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" - slash "^3.0.0" - -"@jest/transform@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.3.1.tgz#1e6bd3da4af50b5c82a539b7b1f3770568d6e36d" - integrity sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^29.3.1" - "@jridgewell/trace-mapping" "^0.3.15" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" - jest-regex-util "^29.2.0" - jest-util "^29.3.1" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.1" - -"@jest/types@^29.3.1": - version "29.3.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.3.1.tgz#7c5a80777cb13e703aeec6788d044150341147e3" - integrity sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA== - dependencies: - "@jest/schemas" "^29.0.0" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@sinclair/typebox@^0.24.1": - version "0.24.51" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" - integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== - -"@sinonjs/commons@^1.7.0": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.5.tgz#e280c94c95f206dcfd5aca00a43f2156b758c764" - integrity sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@types/babel__core@^7.1.14": - version "7.1.20" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359" - integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" - integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== - dependencies: - "@babel/types" "^7.3.0" - -"@types/graceful-fs@^4.1.3": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@^29.2.3": - version "29.2.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.3.tgz#f5fd88e43e5a9e4221ca361e23790d48fcf0a211" - integrity sha512-6XwoEbmatfyoCjWRX7z0fKMmgYKe9+/HrviJ5k0X/tjJWHGAezZOfYaxqQKuzG/TvQyr+ktjm4jgbk0s4/oF2w== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - -"@types/node@*", "@types/node@^18.11.9": - version "18.11.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" - integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== - -"@types/prettier@^2.1.5": - version "2.7.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.1.tgz#dfd20e2dc35f027cdd6c1908e80a5ddc7499670e" - integrity sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow== - -"@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== - -"@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== - -"@types/yargs@^17.0.8": - version "17.0.13" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" - integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== - dependencies: - "@types/yargs-parser" "*" - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -anymatch@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -babel-jest@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.3.1.tgz#05c83e0d128cd48c453eea851482a38782249f44" - integrity sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA== - dependencies: - "@jest/transform" "^29.3.1" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.2.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094" - integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-jest@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc" - integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA== - dependencies: - babel-plugin-jest-hoist "^29.2.0" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.21.3: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== - dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" - -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001400: - version "1.0.30001434" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz#ec1ec1cfb0a93a34a0600d37903853030520a4e5" - integrity sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA== - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -ci-info@^3.2.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.6.1.tgz#7594f1c95cb7fdfddee7af95a13af7dbc67afdcf" - integrity sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w== - -cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -convert-units@^2.3.4: - version "2.3.4" - resolved "https://registry.yarnpkg.com/convert-units/-/convert-units-2.3.4.tgz#a279f4b3cb9b5d5094beba61abc742dcb46a180d" - integrity sha512-ERHfdA0UhHJp1IpwE6PnFJx8LqG7B1ZjJ20UvVCmopEnVCfER68Tbe3kvN63dLbYXDA2xFWRE6zd4Wsf0w7POg== - dependencies: - lodash.foreach "2.3.x" - lodash.keys "2.3.x" - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@^4.1.0, debug@^4.1.1: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -diff-sequences@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" - integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== - -electron-to-chromium@^1.4.251: - version "1.4.284" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== - -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expect@^29.0.0, expect@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.3.1.tgz#92877aad3f7deefc2e3f6430dd195b92295554a6" - integrity sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA== - dependencies: - "@jest/expect-utils" "^29.3.1" - jest-get-type "^29.2.0" - jest-matcher-utils "^29.3.1" - jest-message-util "^29.3.1" - jest-util "^29.3.1" - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jest-changed-files@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289" - integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA== - dependencies: - execa "^5.0.0" - p-limit "^3.1.0" - -jest-circus@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.3.1.tgz#177d07c5c0beae8ef2937a67de68f1e17bbf1b4a" - integrity sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg== - dependencies: - "@jest/environment" "^29.3.1" - "@jest/expect" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - is-generator-fn "^2.0.0" - jest-each "^29.3.1" - jest-matcher-utils "^29.3.1" - jest-message-util "^29.3.1" - jest-runtime "^29.3.1" - jest-snapshot "^29.3.1" - jest-util "^29.3.1" - p-limit "^3.1.0" - pretty-format "^29.3.1" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-cli@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.3.1.tgz#e89dff427db3b1df50cea9a393ebd8640790416d" - integrity sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ== - dependencies: - "@jest/core" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/types" "^29.3.1" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^29.3.1" - jest-util "^29.3.1" - jest-validate "^29.3.1" - prompts "^2.0.1" - yargs "^17.3.1" - -jest-config@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.3.1.tgz#0bc3dcb0959ff8662957f1259947aedaefb7f3c6" - integrity sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.3.1" - "@jest/types" "^29.3.1" - babel-jest "^29.3.1" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^29.3.1" - jest-environment-node "^29.3.1" - jest-get-type "^29.2.0" - jest-regex-util "^29.2.0" - jest-resolve "^29.3.1" - jest-runner "^29.3.1" - jest-util "^29.3.1" - jest-validate "^29.3.1" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^29.3.1" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.3.1.tgz#d8215b72fed8f1e647aed2cae6c752a89e757527" - integrity sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.3.1" - jest-get-type "^29.2.0" - pretty-format "^29.3.1" - -jest-docblock@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" - integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== - dependencies: - detect-newline "^3.0.0" - -jest-each@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.3.1.tgz#bc375c8734f1bb96625d83d1ca03ef508379e132" - integrity sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA== - dependencies: - "@jest/types" "^29.3.1" - chalk "^4.0.0" - jest-get-type "^29.2.0" - jest-util "^29.3.1" - pretty-format "^29.3.1" - -jest-environment-node@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.3.1.tgz#5023b32472b3fba91db5c799a0d5624ad4803e74" - integrity sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag== - dependencies: - "@jest/environment" "^29.3.1" - "@jest/fake-timers" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/node" "*" - jest-mock "^29.3.1" - jest-util "^29.3.1" - -jest-get-type@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" - integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== - -jest-haste-map@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.3.1.tgz#af83b4347f1dae5ee8c2fb57368dc0bb3e5af843" - integrity sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A== - dependencies: - "@jest/types" "^29.3.1" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^29.2.0" - jest-util "^29.3.1" - jest-worker "^29.3.1" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - -jest-leak-detector@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz#95336d020170671db0ee166b75cd8ef647265518" - integrity sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA== - dependencies: - jest-get-type "^29.2.0" - pretty-format "^29.3.1" - -jest-matcher-utils@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz#6e7f53512f80e817dfa148672bd2d5d04914a572" - integrity sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ== - dependencies: - chalk "^4.0.0" - jest-diff "^29.3.1" - jest-get-type "^29.2.0" - pretty-format "^29.3.1" - -jest-message-util@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.3.1.tgz#37bc5c468dfe5120712053dd03faf0f053bd6adb" - integrity sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.3.1" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.3.1" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.3.1.tgz#60287d92e5010979d01f218c6b215b688e0f313e" - integrity sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA== - dependencies: - "@jest/types" "^29.3.1" - "@types/node" "*" - jest-util "^29.3.1" - -jest-pnp-resolver@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" - integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== - -jest-resolve-dependencies@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz#a6a329708a128e68d67c49f38678a4a4a914c3bf" - integrity sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA== - dependencies: - jest-regex-util "^29.2.0" - jest-snapshot "^29.3.1" - -jest-resolve@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.3.1.tgz#9a4b6b65387a3141e4a40815535c7f196f1a68a7" - integrity sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" - jest-pnp-resolver "^1.2.2" - jest-util "^29.3.1" - jest-validate "^29.3.1" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - -jest-runner@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.3.1.tgz#a92a879a47dd096fea46bb1517b0a99418ee9e2d" - integrity sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA== - dependencies: - "@jest/console" "^29.3.1" - "@jest/environment" "^29.3.1" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.13.1" - graceful-fs "^4.2.9" - jest-docblock "^29.2.0" - jest-environment-node "^29.3.1" - jest-haste-map "^29.3.1" - jest-leak-detector "^29.3.1" - jest-message-util "^29.3.1" - jest-resolve "^29.3.1" - jest-runtime "^29.3.1" - jest-util "^29.3.1" - jest-watcher "^29.3.1" - jest-worker "^29.3.1" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.3.1.tgz#21efccb1a66911d6d8591276a6182f520b86737a" - integrity sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A== - dependencies: - "@jest/environment" "^29.3.1" - "@jest/fake-timers" "^29.3.1" - "@jest/globals" "^29.3.1" - "@jest/source-map" "^29.2.0" - "@jest/test-result" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/node" "*" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^29.3.1" - jest-message-util "^29.3.1" - jest-mock "^29.3.1" - jest-regex-util "^29.2.0" - jest-resolve "^29.3.1" - jest-snapshot "^29.3.1" - jest-util "^29.3.1" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-snapshot@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.3.1.tgz#17bcef71a453adc059a18a32ccbd594b8cc4e45e" - integrity sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.3.1" - "@jest/transform" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/babel__traverse" "^7.0.6" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^29.3.1" - graceful-fs "^4.2.9" - jest-diff "^29.3.1" - jest-get-type "^29.2.0" - jest-haste-map "^29.3.1" - jest-matcher-utils "^29.3.1" - jest-message-util "^29.3.1" - jest-util "^29.3.1" - natural-compare "^1.4.0" - pretty-format "^29.3.1" - semver "^7.3.5" - -jest-util@^29.0.0, jest-util@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.3.1.tgz#1dda51e378bbcb7e3bc9d8ab651445591ed373e1" - integrity sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ== - dependencies: - "@jest/types" "^29.3.1" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.3.1.tgz#d56fefaa2e7d1fde3ecdc973c7f7f8f25eea704a" - integrity sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g== - dependencies: - "@jest/types" "^29.3.1" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^29.2.0" - leven "^3.1.0" - pretty-format "^29.3.1" - -jest-watcher@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.3.1.tgz#3341547e14fe3c0f79f9c3a4c62dbc3fc977fd4a" - integrity sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg== - dependencies: - "@jest/test-result" "^29.3.1" - "@jest/types" "^29.3.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.13.1" - jest-util "^29.3.1" - string-length "^4.0.1" - -jest-worker@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.3.1.tgz#e9462161017a9bb176380d721cab022661da3d6b" - integrity sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw== - dependencies: - "@types/node" "*" - jest-util "^29.3.1" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.3.1.tgz#c130c0d551ae6b5459b8963747fed392ddbde122" - integrity sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA== - dependencies: - "@jest/core" "^29.3.1" - "@jest/types" "^29.3.1" - import-local "^3.0.2" - jest-cli "^29.3.1" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json5@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.2.tgz#64471c5bdcc564c18f7c1d4df2e2297f2457c5ab" - integrity sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash._basebind@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._basebind/-/lodash._basebind-2.3.0.tgz#2b5bc452a0e106143b21869f233bdb587417d248" - integrity sha512-SHqM7YCuJ+BeGTs7lqpWnmdHEeF4MWxS3dksJctHFNxR81FXPOzA4bS5Vs5CpcGTkBpM8FCl+YEbQEblRw8ABg== - dependencies: - lodash._basecreate "~2.3.0" - lodash._setbinddata "~2.3.0" - lodash.isobject "~2.3.0" - -lodash._basecreate@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-2.3.0.tgz#9b88a86a4dcff7b7f3c61d83a2fcfc0671ec9de0" - integrity sha512-vwZaWldZwS2y9b99D8i9+WtgiZXbHKsBsMrpxJEqTsNW20NhJo5W8PBQkeQO9CmxuqEYn8UkMnfEM2MMT4cVrw== - dependencies: - lodash._renative "~2.3.0" - lodash.isobject "~2.3.0" - lodash.noop "~2.3.0" - -lodash._basecreatecallback@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._basecreatecallback/-/lodash._basecreatecallback-2.3.0.tgz#37b2ab17591a339e988db3259fcd46019d7ac362" - integrity sha512-Ev+pDzzfVfgbiucpXijconLGRBar7/+KNCf05kSnk4CmdDVhAy1RdbU9efCJ/o9GXI08JdUGwZ+5QJ3QX3kj0g== - dependencies: - lodash._setbinddata "~2.3.0" - lodash.bind "~2.3.0" - lodash.identity "~2.3.0" - lodash.support "~2.3.0" - -lodash._basecreatewrapper@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.3.0.tgz#aa0c61ad96044c3933376131483a9759c3651247" - integrity sha512-YLycQ7k8AB9Wc1EOvLNxuRWcqipDkMXq2GCgnLWQR6qtgTb3gY3LELzEpnFshrEO4LOLs+R2EpcY+uCOZaLQ8Q== - dependencies: - lodash._basecreate "~2.3.0" - lodash._setbinddata "~2.3.0" - lodash._slice "~2.3.0" - lodash.isobject "~2.3.0" - -lodash._createwrapper@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._createwrapper/-/lodash._createwrapper-2.3.0.tgz#d1aae1102dadf440e8e06fc133a6edd7fe146075" - integrity sha512-XjaI/rzg9W+WO4WJDQ+PRlHD5sAMJ1RhJLuT65cBxLCb1kIYs4U20jqvTDGAWyVT3c34GYiLd9AreHYuB/8yJA== - dependencies: - lodash._basebind "~2.3.0" - lodash._basecreatewrapper "~2.3.0" - lodash.isfunction "~2.3.0" - -lodash._objecttypes@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.3.0.tgz#6a3ea3987dd6eeb8021b2d5c9c303549cc2bae1e" - integrity sha512-jbA6QyHt9cw3BzvbWzIcnU3Z12jSneT6xBgz3Y782CJsN1tV5aTBKrFo2B4AkeHBNaxSrbPYZZpi1Lwj3xjdtg== - -lodash._renative@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._renative/-/lodash._renative-2.3.0.tgz#77d8edd4ced26dd5971f9e15a5f772e4e317fbd3" - integrity sha512-v44MRirqYqZGK/h5UKoVqXWF2L+LUiLTU+Ogu5rHRVWJUA1uWIlHaMpG8f/OA8j++BzPMQij9+erXHtgFcbuwg== - -lodash._setbinddata@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._setbinddata/-/lodash._setbinddata-2.3.0.tgz#e5610490acd13277d59858d95b5f2727f1508f04" - integrity sha512-xMFfbF7dL+sFtrdE49uHFmfpBAEwlFtfgMp86nQRlAF6aizYL+3MTbnYMKJSkP1W501PhsgiBED5kBbZd8kR2g== - dependencies: - lodash._renative "~2.3.0" - lodash.noop "~2.3.0" - -lodash._shimkeys@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.3.0.tgz#611f93149e3e6c721096b48769ef29537ada8ba9" - integrity sha512-9Iuyi7TiWMGa/9+2rqEE+Zwye4b/U2w7Saw6UX1h6Xs88mEER+uz9FZcEBPKMVKsad9Pw5GNAcIBRnW2jNpneQ== - dependencies: - lodash._objecttypes "~2.3.0" - -lodash._slice@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash._slice/-/lodash._slice-2.3.0.tgz#147198132859972e4680ca29a5992c855669aa5c" - integrity sha512-7C61GhzRUv36gTafr+RIb+AomCAYsSATEoK4OP0VkNBcwvsM022Z22AVgqjjzikeNO1U29LzsJZDvLbiNPUYvA== - -lodash.bind@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-2.3.0.tgz#c2a8e18b68e5ecc152e2b168266116fea5b016cc" - integrity sha512-goakyOo+FMN8lttMPnZ0UNlr5RlzX4IrUXyTJPT2A0tGCMXySupond9wzvDqTvVmYTcQjIKGrj8naJDS2xWAlQ== - dependencies: - lodash._createwrapper "~2.3.0" - lodash._renative "~2.3.0" - lodash._slice "~2.3.0" - -lodash.foreach@2.3.x: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-2.3.0.tgz#083404c91e846ee77245fdf9d76519c68b2af168" - integrity sha512-yLnyptVRJd0//AbGp480grgQG9iaDIV5uOgSbpurRy1dYybPbjNTLQ3FyLEQ84buVLPG7jyaiyvpzgfOutRB3Q== - dependencies: - lodash._basecreatecallback "~2.3.0" - lodash.forown "~2.3.0" - -lodash.forown@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.forown/-/lodash.forown-2.3.0.tgz#24fb4aaf800d45fc2dc60bfec3ce04c836a3ad7f" - integrity sha512-dUnCsuQTtq3Y7bxPNoEEqjJjPL2ftLtcz2PTeRKvhbpdM514AvnqCjewHGsm/W+dwspIwa14KoWEZeizJ7smxA== - dependencies: - lodash._basecreatecallback "~2.3.0" - lodash._objecttypes "~2.3.0" - lodash.keys "~2.3.0" - -lodash.identity@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.identity/-/lodash.identity-2.3.0.tgz#6b01a210c9485355c2a913b48b6711219a173ded" - integrity sha512-NYJ2r2cwy3tkx/saqbIZEX6oQUzjWTnGRu7d/zmBjMCZos3eHBxCpbvWFWSetv8jFVrptsp6EbWjzNgBKhUoOA== - -lodash.isfunction@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-2.3.0.tgz#6b2973e47a647cf12e70d676aea13643706e5267" - integrity sha512-X5lteBYlCrVO7Qc00fxP8W90fzRp6Ax9XcHANmU3OsZHdSyIVZ9ZlX5QTTpRq8aGY+9I5Rmd0UTzTIIyWPugEQ== - -lodash.isobject@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.3.0.tgz#2e16d3fc583da9831968953f2d8e6d73434f6799" - integrity sha512-jo1pfV61C4TE8BfEzqaHj6EIKiSkFANJrB6yscwuCJMSRw5tbqjk4Gv7nJzk4Z6nFKobZjGZ8Qd41vmnwgeQqQ== - dependencies: - lodash._objecttypes "~2.3.0" - -lodash.keys@2.3.x, lodash.keys@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.3.0.tgz#b350f4f92caa9f45a4a2ecf018454cf2f28ae253" - integrity sha512-c0UW0ffqMxSCtoVbmVt2lERJLkEqgoOn2ejPsWXzr0ZrqRbl3uruGgwHzhtqXxi6K/ei3Ey7zimOqSwXgzazPg== - dependencies: - lodash._renative "~2.3.0" - lodash._shimkeys "~2.3.0" - lodash.isobject "~2.3.0" - -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - -lodash.noop@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-2.3.0.tgz#3059d628d51bbf937cd2a0b6fc3a7f212a669c2c" - integrity sha512-NpSm8HRm1WkBBWHUveDukLF4Kfb5P5E3fjHc9Qre9A11nNubozLWD2wH3UBTZbu+KSuX8aSUvy9b+PUyEceJ8g== - -lodash.support@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/lodash.support/-/lodash.support-2.3.0.tgz#7eaf038af4f0d6aab776b44aa6dcfc80334c9bfd" - integrity sha512-etc7VWbB0U3Iya8ixj2xy4sDBN3jvPX7ODi8iXtn4KkkjNpdngrdc7Vlt5jub/Vgqx6/dWtp7Ml9awhCQPYKGQ== - dependencies: - lodash._renative "~2.3.0" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@1.x: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.4, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pirates@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pretty-format@^29.0.0, pretty-format@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.3.1.tgz#1841cac822b02b4da8971dacb03e8a871b4722da" - integrity sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg== - dependencies: - "@jest/schemas" "^29.0.0" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== - -resolve@^1.20.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -semver@7.x, semver@^7.3.5: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.3.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -stack-utils@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -ts-jest@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.3.tgz#63ea93c5401ab73595440733cefdba31fcf9cb77" - integrity sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^29.0.0" - json5 "^2.2.1" - lodash.memoize "4.x" - make-error "1.x" - semver "7.x" - yargs-parser "^21.0.1" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -typescript@^4.8.4: - version "4.8.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== - -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -v8-to-istanbul@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" - integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^21.0.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs@^17.3.1: - version "17.6.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" - integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/libs/serial-number-gen/docs/imgs/format.png b/libs/serial-number-gen/docs/imgs/format.png deleted file mode 100644 index e4262f5d8..000000000 Binary files a/libs/serial-number-gen/docs/imgs/format.png and /dev/null differ diff --git a/libs/serial-number-gen/package.json b/libs/serial-number-gen/package.json deleted file mode 100644 index 2f0809d66..000000000 --- a/libs/serial-number-gen/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@undp/serial-number-gen", - "version": "1.0.0", - "description": "Serial Number Generator", - "main": "./dist/esm/index.js", - "module": "./dist/cjs/index.js", - "license": "MIT", - "scripts": { - "build": "tsc -p tsconfig.json && tsc -p tsconfig-cjs.json", - "prepublishOnly": "yarn run build" - }, - "files": [ - "dist/" - ], - "devDependencies": { - "typescript": "^4.8.4" - }, - "types": "./dist/esm/index.d.ts", - "directories": { - "doc": "docs" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/undp/carbon-registry.git#main" - }, - "author": "UNDP", - "bugs": { - "url": "https://github.com/undp/carbon-registry/issues" - }, - "homepage": "https://github.com/undp/carbon-registry/tree/main#readme" -} diff --git a/libs/serial-number-gen/src/constants/sectoralScope.ts b/libs/serial-number-gen/src/constants/sectoralScope.ts deleted file mode 100644 index 5ea8e2318..000000000 --- a/libs/serial-number-gen/src/constants/sectoralScope.ts +++ /dev/null @@ -1,17 +0,0 @@ -export enum SectoralScope { - EnergyIndustry = '1', - EnergyDistribution = '2', - EnergyDemand = '3', - ManufacturingIndustries = '4', - ChemicalIndustries = '5', - Construction = '6', - Transport = '7', - MiningAndMineral = '8', - MetalProduction = '9', - FugitiveEmissionsFromFuels = '10', - FugitiveEmissionsFromProductionConsumption = '11', - SolventUse = '12', - WasteHandlingDisposal = '13', - AfforestationAndReforestation = '14', - Agriculture = '15' -} \ No newline at end of file diff --git a/libs/serial-number-gen/src/generator.ts b/libs/serial-number-gen/src/generator.ts deleted file mode 100644 index f4be22e07..000000000 --- a/libs/serial-number-gen/src/generator.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { SectoralScope } from "./constants/sectoralScope" - -export const generateSerialNumber = ( - countryISO2Code: string, - sectoralScope: SectoralScope, - programmeId: string, - year: number, - blockStartCredit: number, - blockEndCredit: number, - creditUnit: string - ): string => { - return `${countryISO2Code}-${creditUnit}-${sectoralScope}-${programmeId}-${year}-0-${blockStartCredit}-${blockEndCredit}` -} \ No newline at end of file diff --git a/libs/serial-number-gen/src/index.ts b/libs/serial-number-gen/src/index.ts deleted file mode 100644 index f2731fd3e..000000000 --- a/libs/serial-number-gen/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { SectoralScope } from './constants/sectoralScope' -import { generateSerialNumber } from './generator' -export { - generateSerialNumber, - SectoralScope -} \ No newline at end of file diff --git a/libs/serial-number-gen/tsconfig-cjs.json b/libs/serial-number-gen/tsconfig-cjs.json deleted file mode 100644 index 45e278a2c..000000000 --- a/libs/serial-number-gen/tsconfig-cjs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "CommonJS", - "outDir": "./dist/cjs" - }, -} \ No newline at end of file diff --git a/libs/serial-number-gen/tsconfig.json b/libs/serial-number-gen/tsconfig.json deleted file mode 100644 index 48127c29c..000000000 --- a/libs/serial-number-gen/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "target": "es2017", - "module": "commonjs", - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "outDir": "./dist/esm", - "declaration": true - }, - "include": [ - "./src" - ] -} diff --git a/libs/serial-number-gen/yarn.lock b/libs/serial-number-gen/yarn.lock deleted file mode 100644 index a5d100bbf..000000000 --- a/libs/serial-number-gen/yarn.lock +++ /dev/null @@ -1,8 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -typescript@^4.8.4: - version "4.8.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== diff --git a/web/Dockerfile b/web/Dockerfile index 962c75869..5639afad2 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -31,13 +31,17 @@ ENV REACT_APP_MAPBOXGL_ACCESS_TOKEN $REACT_APP_MAPBOXGL_ACCESS_TOKEN ARG REACT_APP_MAP_TYPE ENV REACT_APP_MAP_TYPE $REACT_APP_MAP_TYPE +ARG REACT_APP_ENABLE_REGISTRATION +ENV REACT_APP_ENABLE_REGISTRATION $REACT_APP_ENABLE_REGISTRATION + # Build the app RUN CI=false yarn build # production environment FROM nginx:stable-alpine COPY --from=build /app/build /usr/share/nginx/html -COPY ./web/nginx.conf /etc/nginx/conf.d/default.conf +ARG NGINX_CONFIG=nginx.conf +COPY ./web/$NGINX_CONFIG /etc/nginx/conf.d/default.conf EXPOSE $PORT CMD ["nginx", "-g", "daemon off;"] diff --git a/web/nginx_prod.conf b/web/nginx_prod.conf new file mode 100644 index 000000000..0eff1a6ce --- /dev/null +++ b/web/nginx_prod.conf @@ -0,0 +1,21 @@ +server { + listen 3030; + ssl on; + server_name test.carbreg.org; + server_name www.test.carbreg.org; + ssl_certificate /ssl_cert/fullchain.pem; + ssl_certificate_key /ssl_cert/privkey.pem; + root /usr/share/nginx/html/; + + location / { + root /usr/share/nginx/html/; + include /etc/nginx/mime.types; + try_files $uri $uri/ /index.html; + } +} + +server { + listen 80 default_server; + server_name _; + return 301 https://$host$request_uri; +} \ No newline at end of file diff --git a/web/package.json b/web/package.json index ebdff47be..8000be475 100644 --- a/web/package.json +++ b/web/package.json @@ -14,7 +14,7 @@ "@types/react-dom": "^18.0.8", "@types/styled-components": "^5.1.26", "@types/validator": "^13.7.13", - "@undp/carbon-library": "^1.0.61", + "@undp/carbon-library": "^1.0.127", "antd": "^4.24.1", "apexcharts": "^3.36.3", "axios": "^1.1.3", @@ -46,7 +46,7 @@ "web-vitals": "^2.1.4" }, "scripts": { - "start:dev": "PORT=3030 env-cmd -e development craco start", + "start:dev": "set PORT=3030 env-cmd -e development && craco start", "start:prod": "set PORT=3030 env-cmd -e production && craco start", "clean": "npx rimraf build", "build": "yarn run clean && craco build", diff --git a/web/public/Assets/i18n/addCompany/en.json b/web/public/Assets/i18n/addCompany/en.json index 418380ffe..d33145a84 100644 --- a/web/public/Assets/i18n/addCompany/en.json +++ b/web/public/Assets/i18n/addCompany/en.json @@ -30,6 +30,7 @@ "cancel": "CANCEL", "companyAddedSuccess": "The organisation has been created successfully", "companyUpdatedSuccess": "The organisation has been updated successfully ", + "companyRegisteredSuccess": "User registration request has been sent", "errorInAddUser": "Error in adding user!", "errorInUpdatingCompany": "Error in updating company!" } \ No newline at end of file diff --git a/web/public/Assets/i18n/common/en.json b/web/public/Assets/i18n/common/en.json index 4f8e6108b..bc102e888 100644 --- a/web/public/Assets/i18n/common/en.json +++ b/web/public/Assets/i18n/common/en.json @@ -15,5 +15,7 @@ "signIn": "Sign In", "loginFailed": "Login failed", "networkError": "Network error. Please check your internet connection and try again.", - "systemError": "Something went wrong. Please try again." + "systemError": "Something went wrong. Please try again.", + "approve": "APPROVE", + "reject": "REJECT" } \ No newline at end of file diff --git a/web/public/Assets/i18n/company/en.json b/web/public/Assets/i18n/company/en.json index f4d43fb84..13d136d2f 100644 --- a/web/public/Assets/i18n/company/en.json +++ b/web/public/Assets/i18n/company/en.json @@ -4,6 +4,7 @@ "taxId": "TAX ID", "filterByOrgType": "Filter by Organisation Type", "companyRole": "ORGANISATION TYPE", + "companyState": "STATUS", "viewCompanies": "View Organisations", "viewDesc": "View all the visible organisations in the system based on your permissions", "addCompany": "Add organisation", @@ -17,5 +18,6 @@ "all": "All", "searchMail": "Search by email", "searchName": "Search by name", - "min": "Ministry" + "min": "Ministry", + "nationalSopValue": "National Share of Proceeds" } diff --git a/web/public/Assets/i18n/companyProfile/en.json b/web/public/Assets/i18n/companyProfile/en.json index 33c1591b5..629a2a942 100644 --- a/web/public/Assets/i18n/companyProfile/en.json +++ b/web/public/Assets/i18n/companyProfile/en.json @@ -3,9 +3,12 @@ "subTitle": "View the details of the selected organisation", "deauthorise": "DEACTIVATE", "reActivate": "REACTIVATE", + "approve": "APPROVE", + "reject": "REJECT", "organisationDetailsHeading": "Organisation Details", "name" : "Name", "taxId" : "Tax ID", + "paymentId" : "Registration Payment ID", "companyRole": "Role", "email" : "Email", "phoneNo" : "Phone", @@ -17,11 +20,23 @@ "deauthoriseConfirmText":"Organisation will still be visible but no further action will be able to take place.\n Note: all users associated with the organisation will also be deactivated.", "activeStatus": "Active", "deauthorisedStatus": "Deactivated", + "pendingStatus": "Pending", + "rejectedStatus": "Rejected", "remarks": "Remarks", "deauthorisationSuccess": "Company deactivated successfully!", "reActivateConfirmHeaderText": "Are you sure you want to reactivate this organisation?", "reActivateConfirmText": "Note: all users associated with the organisation will also be reactivated.", "reactivationSuccess": "Company reactivated successfully!", "ministerName": "Name of the Minister", - "sectoralScope": "Sectoral Scope" + "sectoralScope": "Sectoral Scope", + "approveConfirmHeaderText": "Are you sure you want to authorise this organisation?", + "approveConfirmText": "You can't undo this action", + "approvedSuccessfully": "The Organisation was approved successfully", + "rejectConfirmHeaderText": "Are you sure you want to reject this organisation?", + "rejectConfirmText": "You can't undo this action", + "rejectedSuccessfully": "The Organisation was rejected successfully", + "adminDetailsHeading": "Organisation Admin Details", + "adminName": "Name", + "adminEmail": "Email", + "adminPhone": "Phone" } \ No newline at end of file diff --git a/web/public/Assets/i18n/login/en.json b/web/public/Assets/i18n/login/en.json index 2589968a8..6a4a116d3 100644 --- a/web/public/Assets/i18n/login/en.json +++ b/web/public/Assets/i18n/login/en.json @@ -4,6 +4,7 @@ "management": "DEMO", "welcome": "Welcome", "welcome-back": "Welcome Back", - "register-acc": "Don't have an account yet", - "forgot-pwd": "Forgot Password" + "register-acc": "Need an account?", + "forgot-pwd": "Forgot Password", + "register-here": "Register here" } diff --git a/web/public/Assets/i18n/programme/en.json b/web/public/Assets/i18n/programme/en.json index 357666b7a..eecf0c6f6 100644 --- a/web/public/Assets/i18n/programme/en.json +++ b/web/public/Assets/i18n/programme/en.json @@ -12,5 +12,6 @@ "title": "Programme Name", "gettingProgrammeError": "Error in getting programme", "all": "All", - "searchByName": "Search by programme name" + "searchByName": "Search by programme name", + "environmentalImpactAssessment": "Environmental Impact Assessment" } \ No newline at end of file diff --git a/web/public/Assets/i18n/userProfile/en.json b/web/public/Assets/i18n/userProfile/en.json index ed36fdebd..c6bcb2ec1 100644 --- a/web/public/Assets/i18n/userProfile/en.json +++ b/web/public/Assets/i18n/userProfile/en.json @@ -8,6 +8,7 @@ "role": "Role", "phoneNo": "Phone", "taxId": "Tax ID", + "paymentId" : "Registration Payment ID", "website": "Website", "address": "Address", "id": "id", diff --git a/web/public/Assets/i18n/view/en.json b/web/public/Assets/i18n/view/en.json index f78c6349b..4d543675e 100644 --- a/web/public/Assets/i18n/view/en.json +++ b/web/public/Assets/i18n/view/en.json @@ -115,9 +115,14 @@ "tlTxLowCreditCancelSystemDesc": "The request to transfer {} {} credits from {} to {} was cancelled by the system due to insufficient credit balance", "tlOwnership": "New Ownership", "tlOwnershipDesc": "{} invested in this programme obtaining {} ownership of the programme.", + "tlPending": "Pending", + "tlAuthorisation": "Authorisation", "typeOfMitigation": "Type Of Mitigation", "userEstimatedCredits": "User Estimated Credits", "systemEstimatedCredits": "System Estimated Credits", "actionId": "NDC ID", - "ministryLevel": "Minitry Level" + "ministryLevel": "Ministry Level", + "creditEst": "Estimated Credits", + "carbonPriceUSDPerTon": "Minimum Carbon Price: USD per ton (assuming no other revenue)", + "environmentalAssessmentRegistrationNo": "Environmental Assessment Registration Number" } diff --git a/web/src/App.tsx b/web/src/App.tsx index f4c19d7de..e9a5be664 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -30,6 +30,8 @@ import { AbilityContext } from './Casl/Can'; import { defineAbility, updateUserAbility } from './Casl/ability'; import { message } from 'antd'; import { SettingsContextProvider } from './Context/SettingsContext/settingsContext'; +import RegisterNewCompany from './Pages/Company/registerNewCompany'; +import { Loading } from '@undp/carbon-library'; // message.config({ // duration: 60, @@ -37,6 +39,8 @@ import { SettingsContextProvider } from './Context/SettingsContext/settingsConte const App = () => { const ability = defineAbility(); + const enableRegistration = process.env.REACT_APP_ENABLE_REGISTRATION || 'true'; + useEffect(() => { console.log(process.env.REACT_APP_BACKEND); console.log(process.env.REACT_APP_STAT_URL); @@ -133,6 +137,16 @@ const App = () => { } /> */} + {enableRegistration === 'true' && ( + }> + + + } + /> + )} } /> diff --git a/web/src/Casl/ability.ts b/web/src/Casl/ability.ts index 246b30626..55b6420f6 100644 --- a/web/src/Casl/ability.ts +++ b/web/src/Casl/ability.ts @@ -6,13 +6,18 @@ import { InferSubjects, MongoAbility, } from '@casl/ability'; -import { Company, BaseEntity, ProgrammeTransfer, User } from '@undp/carbon-library'; -import { Programme } from './entities/Programme'; -import { ProgrammeCertify } from './entities/ProgrammeCertify'; -import { Action } from './enums/action.enum'; -import { CompanyRole } from './enums/company.role.enum'; -import { ProgrammeStage } from './enums/programme-status.enum'; -import { Role } from './enums/role.enum'; +import { + Company, + BaseEntity, + ProgrammeTransfer, + User, + Action, + Role, + CompanyRole, + ProgrammeCertify, + ProgrammeEntity, + ProgrammeStageR, +} from '@undp/carbon-library'; type Subjects = InferSubjects | 'all'; @@ -60,8 +65,6 @@ export const updateUserAbility = (ability: AppAbility, user: User) => { cannot([Action.Update, Action.Delete], User, { companyId: { $ne: user.companyId }, }); - cannot(Action.Delete, Company, { companyRole: { $eq: user.companyRole } }); - cannot(Action.Delete, Company, { companyId: { $eq: user.companyId } }); } } else if (user.role === Role.Admin && user.companyRole !== CompanyRole.GOVERNMENT) { if (user.companyRole === CompanyRole.MINISTRY) { @@ -98,13 +101,18 @@ export const updateUserAbility = (ability: AppAbility, user: User) => { can([Action.Delete], Company); } + if (user.role === Role.Admin && user.companyRole === CompanyRole.GOVERNMENT) { + can(Action.Approve, Company); + can(Action.Reject, Company); + } + if (user.role !== Role.ViewOnly && user.companyRole === CompanyRole.PROGRAMME_DEVELOPER) { can(Action.Manage, ProgrammeTransfer); } if (user.role !== Role.ViewOnly && user.companyRole === CompanyRole.GOVERNMENT) { can(Action.Manage, ProgrammeTransfer); - can(Action.Manage, Programme); + can(Action.Manage, ProgrammeEntity); } if (user.role !== Role.ViewOnly && user.companyRole === CompanyRole.CERTIFIER) { @@ -112,19 +120,20 @@ export const updateUserAbility = (ability: AppAbility, user: User) => { } if (user.role === Role.Admin && user.companyRole === CompanyRole.MRV) { - can([Action.Create, Action.Read], Programme); + can([Action.Create, Action.Read], ProgrammeEntity); } else if (user.companyRole === CompanyRole.CERTIFIER) { - can(Action.Read, Programme, { currentStage: { $in: [ProgrammeStage.AUTHORISED] } }); - can(Action.Read, Programme, { certifierId: { $elemMatch: { $eq: user.companyId } } }); + can(Action.Read, ProgrammeEntity, { currentStage: { $in: [ProgrammeStageR.Authorised] } }); + can(Action.Read, ProgrammeEntity, { certifierId: { $elemMatch: { $eq: user.companyId } } }); } else if (user.companyRole === CompanyRole.PROGRAMME_DEVELOPER) { - can(Action.Read, Programme, { currentStage: { $eq: ProgrammeStage.AUTHORISED } }); - can(Action.Read, Programme, { companyId: { $elemMatch: { $eq: user.companyId } } }); + can(Action.Read, ProgrammeEntity, { currentStage: { $eq: ProgrammeStageR.Authorised } }); + can(Action.Read, ProgrammeEntity, { companyId: { $elemMatch: { $eq: user.companyId } } }); } // cannot(Action.Delete, User, { id: { $eq: user.id } }) cannot(Action.Update, User, ['companyRole']); cannot([Action.Delete], Company, { companyRole: { $eq: CompanyRole.GOVERNMENT } }); + cannot([Action.Delete], Company, { companyRole: { $eq: CompanyRole.MINISTRY } }); if (user.role === Role.Admin || user.role === Role.Root) { can(Action.Create, User); diff --git a/web/src/Casl/entities/Programme.ts b/web/src/Casl/entities/Programme.ts deleted file mode 100644 index 93a1f49c4..000000000 --- a/web/src/Casl/entities/Programme.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { BaseEntity } from '@undp/carbon-library'; - -export class Programme implements BaseEntity { - programmeId?: string; - - serialNo?: string; - - title?: string; - - externalId?: string; - - currentStage?: string; - - typeOfMitigation?: string; - - certifierId?: number[]; - - companyId?: number[]; -} diff --git a/web/src/Casl/entities/ProgrammeCertify.ts b/web/src/Casl/entities/ProgrammeCertify.ts deleted file mode 100644 index b62f96118..000000000 --- a/web/src/Casl/entities/ProgrammeCertify.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { BaseEntity } from '@undp/carbon-library'; - -export class ProgrammeCertify implements BaseEntity { - programmeId?: string; - - comment?: string; -} diff --git a/web/src/Casl/enums/action.enum.ts b/web/src/Casl/enums/action.enum.ts deleted file mode 100644 index b398b2188..000000000 --- a/web/src/Casl/enums/action.enum.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum Action { - Manage = 'manage', - Create = 'create', - Read = 'read', - Update = 'update', - Delete = 'delete', -} diff --git a/web/src/Casl/enums/company.role.enum.ts b/web/src/Casl/enums/company.role.enum.ts deleted file mode 100644 index e600b260d..000000000 --- a/web/src/Casl/enums/company.role.enum.ts +++ /dev/null @@ -1,18 +0,0 @@ -export enum CompanyRole { - ACADEMICS = 'Academics', - SERVICE_PROVIDER = 'ServiceProvider', - MITIGATION_ACTIVITY_PARTNER = 'MitigationActivityParticipant', - CARBON_CREDIT_BROKER = 'CarbonCreditBroker', - VALIDATION_VERIFICATION_ENTITY = 'ValidationVerificationEntities', - COMMERCIAL_BANKS = 'CommercialBanks', - INVESTORS = 'InvestorsFinanciers', - GOV_REGULATOR = 'GovernmentRegulators', - OBSERVERS = 'Observers', - CIVIL_SOCIETY_ORG = 'CivilSocietyOrganization', - CERTIFIER = 'Certifier', - INTERNAL_ORGANIZATION = 'InternationalOrganization', - PROGRAMME_DEVELOPER = 'ProgrammeDeveloper', - MRV = 'MRV', - GOVERNMENT = 'Government', - MINISTRY = 'Ministry', -} diff --git a/web/src/Casl/enums/programme-status.enum.ts b/web/src/Casl/enums/programme-status.enum.ts deleted file mode 100644 index 07263e16a..000000000 --- a/web/src/Casl/enums/programme-status.enum.ts +++ /dev/null @@ -1,16 +0,0 @@ -export enum ProgrammeStage { - AWAITING_DESIGN = 'AwaitingDesign', - AWAITING_VALIDATION = 'AwaitingValidation', - AWAITING_VERIFICATION = 'AwaitingVerification', // Up to this not used - AWAITING_AUTHORIZATION = 'AwaitingAuthorization', - AUTHORISED = 'Authorised', - REJECTED = 'Rejected', - RETIRED = 'Retired', - TRANSFERRED = 'Transferred', -} - -export enum ProgrammeStageLegend { // Up to this not used - AUTHORISED = 'Authorised', - REJECTED = 'Rejected', - AWAITING_AUTHORIZATION = 'AwaitingAuthorization', -} diff --git a/web/src/Casl/enums/role.enum.ts b/web/src/Casl/enums/role.enum.ts deleted file mode 100644 index 010994cb1..000000000 --- a/web/src/Casl/enums/role.enum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum Role { - Root = 'Root', - Admin = 'Admin', - Manager = 'Manager', - ViewOnly = 'ViewOnly', -} diff --git a/web/src/Casl/enums/sector.enum.ts b/web/src/Casl/enums/sector.enum.ts deleted file mode 100644 index 67f4bd8f0..000000000 --- a/web/src/Casl/enums/sector.enum.ts +++ /dev/null @@ -1,12 +0,0 @@ -export enum Sector { - Energy = 'Energy', - Health = 'Health', - Education = 'Education', - Transport = 'Transport', - Manufacturing = 'Manufacturing', - Hospitality = 'Hospitality', - Forestry = 'Forestry', - Waste = 'Waste', - Agriculture = 'Agriculture', - Other = 'Other', -} diff --git a/web/src/Casl/enums/statsCards.type.enum.ts b/web/src/Casl/enums/statsCards.type.enum.ts deleted file mode 100644 index c0570c0a0..000000000 --- a/web/src/Casl/enums/statsCards.type.enum.ts +++ /dev/null @@ -1,19 +0,0 @@ -export enum StatsCardsTypes { - PROGRAMMES_PENDING = 'Programmes Pending', - TRANSFER_REQUEST_RECEIVED = 'Pending Transfers Received', - PROGRAMMES_UNCERTIFIED = 'Programmes Certifiable', - TRANSFER_REQUEST_SENT = 'Pending Transfers Sent', - PROGRAMMES_CERTIFIED = 'Programmes Certified', - CREDIT_BALANCE = 'Credit Balance', - CREDIT_CERTIFIED = 'Credits Certified', - - PROGRAMMES = 'Programmes', - CREDITS = 'Credits', - CERTIFIED_CREDITS = 'Certified Credits', - TOTAL_PROGRAMMES = 'Total Programmes', - TOTAL_PROGRAMMES_SECTOR = 'Total Programmes: Sector', - TOTAL_CREDITS = 'Total Credits', - TOTAL_CREDITS_CERTIFIED = 'Total Credits Certified', - PROGRAMME_LOCATIONS = 'Programme Locations', - TRANSFER_LOCATIONS_INTERNATIONAL = 'Transfer Locations International', -} diff --git a/web/src/Components/CompanyRoleIcon/CompanyRoleIcon.tsx b/web/src/Components/CompanyRoleIcon/CompanyRoleIcon.tsx deleted file mode 100644 index 31efdbc9e..000000000 --- a/web/src/Components/CompanyRoleIcon/CompanyRoleIcon.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { BankOutlined, ExperimentOutlined, SafetyOutlined } from '@ant-design/icons'; -import { FC } from 'react'; -import { - CertBGColor, - CertColor, - DevBGColor, - DevColor, - GovBGColor, - GovColor, -} from '../../Pages/Common/role.color.constants'; -import RoleIcon from '../RoleIcon/role.icon'; - -export interface CompanyRoleIconProps { - role: string; -} - -const CompanyRoleIcon: FC = (props: CompanyRoleIconProps) => { - const { role } = props; - return ( -
- {role === 'Government' ? ( - } bg={GovBGColor} color={GovColor} /> - ) : role === 'Certifier' ? ( - } bg={CertBGColor} color={CertColor} /> - ) : ( - } bg={DevBGColor} color={DevColor} /> - )} - {role === 'ProgrammeDeveloper' ?
{'Developer'}
:
{role}
} -
- ); -}; - -export default CompanyRoleIcon; diff --git a/web/src/Components/Header/layout.header.tsx b/web/src/Components/Header/layout.header.tsx index 7b5abf2fd..9ac29dbd7 100644 --- a/web/src/Components/Header/layout.header.tsx +++ b/web/src/Components/Header/layout.header.tsx @@ -2,11 +2,11 @@ import { MenuProps } from 'antd'; import { useState } from 'react'; import './layout.header.scss'; import { useTranslation } from 'react-i18next'; -import { HeaderProps } from '../../Definitions/InterfacesAndType/layout.header'; import { useConnection } from '../../Context/ConnectionContext/connectionContext'; import { useUserContext } from '../../Context/UserInformationContext/userInformationContext'; import { useNavigate } from 'react-router-dom'; import thumbnail from '../../Assets/Images/thumbnail.png'; +import { HeaderProps } from '@undp/carbon-library'; const LayoutHeader = (props: HeaderProps) => { const navigate = useNavigate(); diff --git a/web/src/Components/ImgwithFallback/ImgWithFallback.tsx b/web/src/Components/ImgwithFallback/ImgWithFallback.tsx deleted file mode 100644 index 6735fe5cb..000000000 --- a/web/src/Components/ImgwithFallback/ImgWithFallback.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -const ImgWithFallback = ({ - src, - alt, - fallbackSrc, - mediaType, - className, - ...delegated -}: { - src: string; - alt: string; - fallbackSrc: string; - mediaType: string; - className: string; -}) => { - return ( - - - {alt} - - ); -}; - -export default ImgWithFallback; diff --git a/web/src/Components/InfoView/info.view.scss b/web/src/Components/InfoView/info.view.scss deleted file mode 100644 index 85b011f63..000000000 --- a/web/src/Components/InfoView/info.view.scss +++ /dev/null @@ -1,34 +0,0 @@ -@import '../../Styles/variables.scss'; - -.info-view { - .title-icon { - padding-right: 10px; - } - - .title-text { - color: $title-text-color; - font-weight: 600; - } - - .title { - margin-bottom: 5px; - } - - .field-key { - color: $body-text-color; - font-weight: 500; - text-overflow: ellipsis; - overflow: hidden; - } - - .field-value { - color: $body-text-color; - text-overflow: ellipsis; - overflow: hidden; - } - - .field { - margin: 15px 25px; - font-size: 0.8rem; - } -} diff --git a/web/src/Components/InfoView/info.view.tsx b/web/src/Components/InfoView/info.view.tsx deleted file mode 100644 index ba3470787..000000000 --- a/web/src/Components/InfoView/info.view.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Col, Row } from 'antd'; -import { DateTime } from 'luxon'; -import React, { FC } from 'react'; -import { useTranslation } from 'react-i18next'; -import { dateFormat } from '../../Pages/Common/configs'; -import './info.view.scss'; - -export interface InfoViewProps { - data: any; - title: any; - icon: any; - hiddenColumns?: any; -} - -const InfoView: FC = (props: InfoViewProps) => { - const { title, data, icon, hiddenColumns } = props; - return ( -
-
- {icon} - {title} -
-
- {Object.keys(data).map((k: any) => { - if (hiddenColumns.indexOf(k) < 0) { - return ( - - - {k} - - - {data[k] instanceof DateTime - ? data[k].toFormat(dateFormat) - : data[k] === '' || !data[k] || data[k] === 'NaN' - ? '-' - : data[k]} - - - ); - } else { - return null; - } - })} -
-
- ); -}; - -InfoView.defaultProps = { - hiddenColumns: [], -}; - -export default InfoView; diff --git a/web/src/Components/Layout/layout.tsx b/web/src/Components/Layout/layout.tsx index 40746764a..26d63b4ab 100644 --- a/web/src/Components/Layout/layout.tsx +++ b/web/src/Components/Layout/layout.tsx @@ -5,12 +5,11 @@ const { Header, Sider, Content } = Layout; import { Outlet } from 'react-router-dom'; import { useConnection } from '../../Context/ConnectionContext/connectionContext'; import { useSettingsContext } from '../../Context/SettingsContext/settingsContext'; -import { ConfigurationSettingsType } from '../../Definitions/InterfacesAndType/settings.definitions'; import LayoutHeader from '../Header/layout.header'; -import Loading from '../Loading/Loading'; import LayoutSider from '../Sider/layout.sider'; import './layout.scss'; import { PauseCircleFill } from 'react-bootstrap-icons'; +import { ConfigurationSettingsType, Loading } from '@undp/carbon-library'; const CustomLayout = (props: any) => { const { selectedKey } = props; diff --git a/web/src/Components/LegendItem/legendItem.scss b/web/src/Components/LegendItem/legendItem.scss deleted file mode 100644 index da5380489..000000000 --- a/web/src/Components/LegendItem/legendItem.scss +++ /dev/null @@ -1,13 +0,0 @@ -.legend-item-container { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - font-size: 14px; - font-weight: 400; - margin-left: 0.75rem; - - .text { - margin-left: 0.2rem; - } -} diff --git a/web/src/Components/LegendItem/legendItem.tsx b/web/src/Components/LegendItem/legendItem.tsx deleted file mode 100644 index 926c4669f..000000000 --- a/web/src/Components/LegendItem/legendItem.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React, { FC } from 'react'; -import { CircleFill } from 'react-bootstrap-icons'; -import './legendItem.scss'; - -export interface LegendItemItemProps { - text: string; - color: string; -} - -const LegendItem: FC = (props: LegendItemItemProps) => { - const { text, color } = props; - - return ( -
- -
{text}
-
- ); -}; - -export default LegendItem; diff --git a/web/src/Components/Loading/Loading.tsx b/web/src/Components/Loading/Loading.tsx deleted file mode 100644 index f3066dd6d..000000000 --- a/web/src/Components/Loading/Loading.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { Spin } from 'antd'; - -const Loading = () => { - return ; -}; - -export default Loading; diff --git a/web/src/Components/MapCards.tsx/MapCard.tsx b/web/src/Components/MapCards.tsx/MapCard.tsx deleted file mode 100644 index 45e109d36..000000000 --- a/web/src/Components/MapCards.tsx/MapCard.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React, { FC } from 'react'; -import moment from 'moment'; -import './mapCard.scss'; - -export interface MapCardProps { - title: string; - children: any; -} - -const MapCard: FC = (props: MapCardProps) => { - const { title, children } = props; - - return ( -
-
{title}
-
{children}
-
- ); -}; -export default MapCard; diff --git a/web/src/Components/MapCards.tsx/mapCard.scss b/web/src/Components/MapCards.tsx/mapCard.scss deleted file mode 100644 index 01a17d74f..000000000 --- a/web/src/Components/MapCards.tsx/mapCard.scss +++ /dev/null @@ -1,26 +0,0 @@ -.map-card { - display: flex; - flex-direction: column; - width: 100%; - height: 400px; - background: #f6f6f6; - box-shadow: rgba(106, 106, 106, 0.2) 0px 8px 24px; - border-radius: 10px; - padding: 10px 10px 10px 10px; - - .map-container { - display: flex; - flex-direction: row; - width: 100%; - } -} - -.map-card:hover { - display: flex; - flex-direction: column; - width: 100%; - background: #f1f1f1; - box-shadow: rgba(124, 124, 124, 0.2) 0px 8px 24px; - border-radius: 10px; - padding: 10px 10px 10px 10px; -} diff --git a/web/src/Components/Maps/MapComponent.tsx b/web/src/Components/Maps/MapComponent.tsx deleted file mode 100644 index 4b4825c6f..000000000 --- a/web/src/Components/Maps/MapComponent.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { - MapComponentProps, - MapTypes, -} from '../../Definitions/InterfacesAndType/mapComponent.definitions'; -import MapboxComponent from './MapboxComponent'; - -const MapComponent = (props: MapComponentProps) => { - const { mapType } = props; - - return
{mapType === MapTypes.Mapbox ? MapboxComponent(props) : ''}
; -}; - -export default MapComponent; diff --git a/web/src/Components/Maps/MapboxComponent.scss b/web/src/Components/Maps/MapboxComponent.scss deleted file mode 100644 index f8fe77480..000000000 --- a/web/src/Components/Maps/MapboxComponent.scss +++ /dev/null @@ -1,17 +0,0 @@ -@import '../../Pages/Common/colors.dashboard.scss'; - -.map-box-container { - .mapboxgl-popup-content { - background-color: $white !important; - color: $card-title !important; - } - - .mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip { - border-top-color: $white !important; - } - - .mapboxgl-popup-close-button, - .mapboxgl-popup-close-button:hover { - display: none; - } -} diff --git a/web/src/Components/Maps/MapboxComponent.tsx b/web/src/Components/Maps/MapboxComponent.tsx deleted file mode 100644 index cd36605b9..000000000 --- a/web/src/Components/Maps/MapboxComponent.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { useEffect, useRef } from 'react'; -import mapboxgl from 'mapbox-gl'; -import 'mapbox-gl/dist/mapbox-gl.css'; -import { - MapComponentProps, - MarkerData, -} from '../../Definitions/InterfacesAndType/mapComponent.definitions'; -import './MapboxComponent.scss'; - -mapboxgl.accessToken = process.env.REACT_APP_MAPBOXGL_ACCESS_TOKEN - ? process.env.REACT_APP_MAPBOXGL_ACCESS_TOKEN - : ''; - -const MapboxComponent = (props: MapComponentProps) => { - const mapContainerRef = useRef(null); - const { - center, - markers, - mapSource, - onClick, - showPopupOnClick, - onMouseMove, - layer, - height, - style, - zoom, - onRender, - } = props; - - useEffect(() => { - if (!mapContainerRef || !mapContainerRef.current || center.length !== 2) { - return; - } - - const map = new mapboxgl.Map({ - container: mapContainerRef.current || '', - style: style, - center: - !Number.isNaN(center[0]) && !Number.isNaN(center[1]) - ? [center[0], center[1]] - : [9.082, 8.6753], - zoom: zoom, - maxZoom: 17, - }); - - map.on('load', () => { - const currentMarkes: any = {}; - - if (mapSource) { - map.addSource(mapSource.key, mapSource.data); - } - - if (onClick) { - map.on('click', function (e) { - const popupContent = onClick(map, e); - if (showPopupOnClick && popupContent) { - const popup = new mapboxgl.Popup() - .setLngLat(map.unproject(e.point)) - .setHTML(popupContent) - .addTo(map); - } - }); - } - - if (onMouseMove) { - map.on('mousemove', function (e) { - onMouseMove(map, e); - }); - } - - if (layer) { - map.addLayer(layer); - } - - if (onRender) { - map.on('render', () => { - const markersList: MarkerData[] = onRender(map); - if (markersList) { - markersList.forEach((marker: MarkerData) => { - if (!currentMarkes[marker.id as number]) { - const createdMarker = new mapboxgl.Marker({ - color: marker.color, - element: marker.element ? marker.element : undefined, - }) - .setLngLat([marker.location[0], marker.location[1]]) - .addTo(map); - currentMarkes[marker.id as number] = createdMarker; - } - }); - - for (const id in currentMarkes) { - if (!markersList?.some((marker: MarkerData) => marker.id?.toString() === id)) { - currentMarkes[id].remove(); - delete currentMarkes[id]; - } - } - } - }); - } - }); - - if (markers) { - markers.forEach((marker: MarkerData) => { - new mapboxgl.Marker({ - color: marker.color, - element: marker.element ? marker.element : undefined, - }) - .setLngLat([marker.location[0], marker.location[1]]) - .addTo(map); - }); - } - }); - - return ( -
- ); -}; - -export default MapboxComponent; diff --git a/web/src/Components/Models/ChangePasswordModel.tsx b/web/src/Components/Models/ChangePasswordModel.tsx deleted file mode 100644 index ef78b4318..000000000 --- a/web/src/Components/Models/ChangePasswordModel.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { ExclamationCircleOutlined, LockOutlined } from '@ant-design/icons'; -import { Alert, Button, Form, Input, Modal } from 'antd'; -import { FC } from 'react'; -import { useTranslation } from 'react-i18next'; -import lockIcon from '../../Assets/Images/lock.svg'; - -export interface ChangePasswordProps { - onPasswordChanged: any; - onFieldsChanged: any; - onCanceled: any; - openModal: any; - errorMsg: any; - loadingBtn: boolean; -} - -const ChangePasswordModel: FC = (props: ChangePasswordProps) => { - const { onPasswordChanged, onFieldsChanged, onCanceled, openModal, errorMsg, loadingBtn } = props; - const { i18n, t } = useTranslation(['passwordReset']); - - return ( - -
- icon -
-
{t('passwordReset:changePassword')}
-
- } - open={openModal} - className={'popup-success password-reset-model'} - centered={true} - destroyOnClose={true} - footer={null} - onCancel={onCanceled} - > -
- - - - - - - - - ({ - validator(_, value) { - if (!value || getFieldValue('newPassword') === value) { - return Promise.resolve(); - } - return Promise.reject( - new Error(t('passwordReset:passwordsNotMatchedErr').toString()) - ); - }, - }), - ]} - > - - - - {errorMsg && } - -
- - -
- - - ); -}; - -export default ChangePasswordModel; diff --git a/web/src/Components/Models/ProgrammeIssueForm.tsx b/web/src/Components/Models/ProgrammeIssueForm.tsx deleted file mode 100644 index b49db1f12..000000000 --- a/web/src/Components/Models/ProgrammeIssueForm.tsx +++ /dev/null @@ -1,155 +0,0 @@ -import { LockOutlined } from '@ant-design/icons'; -import { Alert, Button, Col, Form, Input, InputNumber, Modal, Row } from 'antd'; -import { FC, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { addCommSep, Programme } from '../../Definitions/InterfacesAndType/programme.definitions'; -import { creditUnit } from '../../Pages/Common/configs'; - -export interface ProgrammeIssueFormProps { - programme: Programme; - onCancel: any; - actionBtnText: string; - onFinish: any; - subText: string; - enableIssue: boolean; -} - -const ProgrammeIssueForm: FC = (props: ProgrammeIssueFormProps) => { - const { programme, onFinish, onCancel, actionBtnText, subText, enableIssue } = props; - const { i18n, t } = useTranslation(['view']); - const [popupError, setPopupError] = useState(undefined); - const [loading, setLoading] = useState(false); - - return ( -
- - - {subText} - - -
setPopupError(undefined)} - onFinish={async (d) => { - if (d.issueAmount === 0) { - setPopupError('Issue amount should be greater than 0'); - setLoading(false); - return; - } - setLoading(true); - const res = await onFinish(d); - setPopupError(res); - setLoading(false); - }} - > - {enableIssue ? ( - - -
{`${t('view:issueCreditText')} (${creditUnit})`}
- - - - ({ - validator(rule, value) { - if ( - getFieldValue('issueAmount') && - parseFloat(getFieldValue('issueAmount')) > - programme.creditEst - programme.creditIssued - ) { - // eslint-disable-next-line prefer-promise-reject-errors - return Promise.reject('Amount > Authorised'); - } - return Promise.resolve(); - }, - }), - ]} - > - { - if (!/[0-9\.]/.test(event.key)) { - event.preventDefault(); - } - }} - /> - - - - {'/'} - - - - - - -
- ) : ( - - -
{`${t('view:authCreditText')} (${creditUnit})`}
- - - - - - -
- )} - - - - - - - - - - {popupError ? : ''} - - - - - - -
- ); -}; - -export default ProgrammeIssueForm; diff --git a/web/src/Components/Models/ProgrammeRetireForm.tsx b/web/src/Components/Models/ProgrammeRetireForm.tsx deleted file mode 100644 index faf0531c3..000000000 --- a/web/src/Components/Models/ProgrammeRetireForm.tsx +++ /dev/null @@ -1,461 +0,0 @@ -import { LockOutlined } from '@ant-design/icons'; -import { - Alert, - Button, - Checkbox, - Col, - Form, - Input, - InputNumber, - Modal, - Radio, - Row, - Select, - SelectProps, - Space, -} from 'antd'; -import { FC, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useConnection } from '../../Context/ConnectionContext/connectionContext'; -import { CompanyState } from '../../Definitions/InterfacesAndType/companyManagement.definitions'; -import { addCommSep, Programme } from '../../Definitions/InterfacesAndType/programme.definitions'; -import { creditUnit } from '../../Pages/Common/configs'; - -export interface ProgrammeRetireFormProps { - programme: Programme; - onCancel: any; - actionBtnText: string; - onFinish: any; - subText?: string; - hideType: boolean; - myCompanyId?: number; -} - -const ProgrammeRetireForm: FC = (props: ProgrammeRetireFormProps) => { - const { programme, onFinish, onCancel, actionBtnText, subText, hideType, myCompanyId } = props; - const { i18n, t } = useTranslation(['view']); - const [popupError, setPopupError] = useState(undefined); - const [loading, setLoading] = useState(false); - const [type, setType] = useState(''); - const [form] = Form.useForm(); - - const [currentSum, setCurrentSum] = useState(0); - const [countryList, setCountryList] = useState([]); - const [value, setValue] = useState(); - const [checked, setChecked] = useState(false); - - const { get, delete: del, post } = useConnection(); - - const handleSearch = async (newValue: string) => { - if (newValue !== undefined) { - const resp = await post('national/organisation/countries', { - page: 1, - size: 250, - filterAnd: [ - { - key: 'name', - operation: 'like', - value: newValue.charAt(0).toUpperCase() + newValue.slice(1) + '%', - }, - ], - sort: { - key: 'name', - order: 'ASC', - }, - }); - setCountryList(resp.data.map((d: any) => ({ label: d.name, value: d.alpha2 }))); - } - }; - - const handleChange = (newValue: string) => { - setValue(newValue); - }; - - // if (!toCompanyDefault) { - // const myIndex = programme.companyId.map(e => Number(e)).indexOf(userCompanyId!); - // if (myIndex >= 0) { - // programme.companyId.splice(myIndex, 1); - // programme.creditOwnerPercentage.splice(myIndex, 1); - // } - // } - - if (!programme.creditOwnerPercentage && programme.companyId.length === 1) { - programme.creditOwnerPercentage = [100]; - } - - const companies: any = {}; - for (const c of programme.company) { - companies[c.companyId] = c; - } - const validCompanies: { percentage: number; name: any; available: number; companyId: any }[] = []; - const companyCredit = []; - let totalCredits = 0; - let companyName = undefined; - for (const index in programme.creditOwnerPercentage) { - if ( - (hideType && Number(programme.companyId[index]) !== myCompanyId) || - parseInt(companies[Number(programme.companyId[index])].state) === - CompanyState.SUSPENDED.valueOf() - ) { - continue; - } else { - companyName = companies[Number(programme.companyId[index])].name; - } - const companyAvailableTotal = - ((programme.creditBalance - (programme.creditFrozen ? programme.creditFrozen[index] : 0)) * - programme.creditOwnerPercentage[index]) / - 100; - validCompanies.push({ - percentage: programme.creditOwnerPercentage[index], - name: companies[Number(programme.companyId[index])].name, - available: companyAvailableTotal, - companyId: Number(programme.companyId[index]), - }); - companyCredit.push(0); - - totalCredits += companyAvailableTotal; - } - - useEffect(() => { - handleSearch(''); - if (hideType) { - setType('0'); - } - }, []); - - return ( -
- {subText && ( - - - {subText} - - - )} - -
setPopupError(undefined)} - onValuesChange={(v, allVal) => { - if (allVal.companyCredit) { - setCurrentSum( - allVal.companyCredit.reduce((a: any, b: any) => (a ? a : 0) + (b ? b : 0), 0) - ); - } - }} - onFinish={async (d) => { - setLoading(true); - if (d.comment) { - d.comment = d.comment.trim(); - } - if (hideType) { - d.type = '0'; - } - if (d.type === '0') { - if (currentSum === 0) { - setPopupError('Total Amount should be greater than 0'); - setLoading(false); - return; - } - d.fromCompanyIds = validCompanies.map((e) => Number(e.companyId)); - // programme.companyId.map((n) => Number(n)); - // d.companyCredit = d.companyCredit.map((n: any) => (n === undefined ? 0 : n)); - d.toCompanyMeta = { - name: d.company, - country: d.country, - }; - } - const res = await onFinish(d); - setPopupError(res); - setLoading(false); - }} - > - {hideType && ( - <> - - - - - - - - - - - - - - - - )} - {!hideType && ( - - - - { - setType(v.target.value); - form.setFieldsValue({ type: v.target.value }); - }} - > - - Cross-border transfer - Legal Action - Other - - - - - - )} - {type === '0' && ( -
- - - - - (option?.label ?? '').toLowerCase().includes(input.toLowerCase()) - } - options={companyList} - /> */} - - - - - - - - - - - {validCompanies.map((pert, index) => { - return ( - - - {hideType ? ( -
{`${t( - 'view:totalRetireCredit' - )} (${creditUnit})`}
- ) : ( -
{pert.name}
- )} - - - ({ - validator(rule, v) { - if ( - getFieldValue(['companyCredit', index]) && - parseFloat(getFieldValue(['companyCredit', index])) > pert.available - ) { - // eslint-disable-next-line prefer-promise-reject-errors - return Promise.reject('Retire Amount > Credit Balance'); - } - return Promise.resolve(); - }, - }), - ]} - > - { - if (!/[0-9\.]/.test(event.key)) { - event.preventDefault(); - } - }} - /> - - - - {'/'} - - - - - - -
- ); - })} - {!hideType && validCompanies.length > 1 && ( - - -
{`${t('view:totalTransferCredit')} (${creditUnit})`}
- - - - - - - - {'/'} - - - - - - -
- )} - {/* {hideType && ( - - -
{`${t('view:totalRetireCredit')} (${creditUnit})`}
- - - - { - if (!/[0-9\.]/.test(event.key)) { - event.preventDefault(); - } - }} - /> - - - - {'/'} - - - - - - -
- )} */} -
- )} - - - - ({ - validator(rule, v) { - if (v !== undefined && v !== '' && v.trim() === '') { - // eslint-disable-next-line prefer-promise-reject-errors - return Promise.reject('Required field'); - } - return Promise.resolve(); - }, - }), - ]} - > - - - - - - - ({ - // validator(rule, v) { - // if (v === false) { - // // eslint-disable-next-line prefer-promise-reject-errors - // return Promise.reject('Required field'); - // } - // return Promise.resolve(); - // }, - // }), - // ]} - > - setChecked(v.target.checked)}> - {hideType ? t('view:confirmRetire') : t('view:confirmClosure')} - - - - - - {popupError ? : ''} - - - - - - -
- ); -}; - -export default ProgrammeRetireForm; diff --git a/web/src/Components/Models/ProgrammeRevokeForm.tsx b/web/src/Components/Models/ProgrammeRevokeForm.tsx deleted file mode 100644 index 4dbcf91b4..000000000 --- a/web/src/Components/Models/ProgrammeRevokeForm.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { LockOutlined } from '@ant-design/icons'; -import { Alert, Button, Col, Form, Input, InputNumber, Modal, Row, Select } from 'antd'; -import { FC, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { Programme } from '../../Definitions/InterfacesAndType/programme.definitions'; - -export interface ProgrammeRevokeFormProps { - programme: Programme; - onCancel: any; - actionBtnText: string; - onFinish: any; - subText: string; - showCertifiers: boolean; -} - -const ProgrammeRevokeForm: FC = (props: ProgrammeRevokeFormProps) => { - const { programme, onFinish, onCancel, actionBtnText, subText, showCertifiers } = props; - const { i18n, t } = useTranslation(['view']); - const [popupError, setPopupError] = useState(undefined); - const [loading, setLoading] = useState(false); - - return ( -
- - - {subText} - - -
setPopupError(undefined)} - onFinish={async (d) => { - setLoading(true); - const res = await onFinish(d); - setPopupError(res); - setLoading(false); - }} - > - {showCertifiers && ( - - - - - {/* - - - - {validCompanies.map((pert, index) => { - return ( - - -
{pert.name}
- - - ({ - validator(rule, v) { - if ( - getFieldValue(['companyCredit', index]) && - parseFloat(getFieldValue(['companyCredit', index])) > pert.available - ) { - // eslint-disable-next-line prefer-promise-reject-errors - return Promise.reject('Amount > Available'); - } - return Promise.resolve(); - }, - }), - ]} - > - { - if (!/[0-9\.]/.test(event.key)) { - event.preventDefault(); - } - }} - /> - - - - {'/'} - - - - - - -
- ); - })} - {validCompanies.length > 1 && ( - - -
{`${t('view:totalTransferCredit')} (${creditUnit})`}
- - - - - - - - {'/'} - - - - - - -
- )} - - - - - - - - - {popupError ? : ''} - - - - - - -
- ); -}; - -export default ProgrammeTransferForm; diff --git a/web/src/Components/Models/TransferActionModel.tsx b/web/src/Components/Models/TransferActionModel.tsx deleted file mode 100644 index dff131959..000000000 --- a/web/src/Components/Models/TransferActionModel.tsx +++ /dev/null @@ -1,252 +0,0 @@ -import { Alert, Button, Checkbox, Col, Form, Input, InputNumber, Modal, Row, Select } from 'antd'; -import { FC, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { ProgrammeTransfer } from '@undp/carbon-library'; -import { addCommSep } from '../../Definitions/InterfacesAndType/programme.definitions'; -import { creditUnit } from '../../Pages/Common/configs'; - -export interface TransferActionModelProps { - icon: any; - title: string; - transfer: ProgrammeTransfer; - onCancel: any; - actionBtnText: string; - onFinish: any; - subText: string; - disableToCompany?: boolean; - toCompanyDefault?: any; - openModal: boolean; - type: string; - remarkRequired: boolean; -} - -const TransferActionModel: FC = (props: TransferActionModelProps) => { - const { - transfer, - onFinish, - onCancel, - actionBtnText, - subText, - openModal, - title, - icon, - type, - remarkRequired, - } = props; - const { i18n, t } = useTranslation(['view', 'creditTransfer']); - const [popupError, setPopupError] = useState(undefined); - const [loading, setLoading] = useState(false); - const [checked, setChecked] = useState(false); - - const companyList = !transfer.isRetirement - ? [ - { - value: transfer.toCompanyId, - label: transfer.receiver[0].name, - }, - ] - : [ - { - value: transfer.fromCompanyId, - label: transfer.sender[0].name, - }, - ]; - return ( - -
{icon}
-
{title}
- - } - className={'popup-' + type} - open={openModal} - width={Math.min(430, window.innerWidth)} - centered={true} - footer={null} - onCancel={onCancel} - destroyOnClose={true} - > -
-
setPopupError(undefined)} - onFinish={async (d) => { - setLoading(true); - if (d.comment) { - d.comment = d.comment.trim(); - } - const res = await onFinish(transfer.requestId, d.comment); - setPopupError(res); - setLoading(false); - }} - > - - - - - (option?.label ?? '').toLowerCase().includes(input.toLowerCase()) - } - options={companyList} - /> */} - - - - - - - - - - - {!transfer.isRetirement && ( - - - - - - - - )} - {transfer.toCompanyMeta && transfer.toCompanyMeta.country && ( - - - - - - - - )} - {transfer.toCompanyMeta && transfer.toCompanyMeta.name && ( - - - - - - - - )} - - -
{`${t('view:transferApproveTotal')} (${creditUnit})`}
- - - - - - -
- - - ({ - validator(rule, v) { - if (remarkRequired && v !== undefined && v !== '' && v.trim() === '') { - // eslint-disable-next-line prefer-promise-reject-errors - return Promise.reject('Required field'); - } - return Promise.resolve(); - }, - }), - ]} - > - - - - - - - ({ - // validator(rule, v) { - // if (v === false) { - // // eslint-disable-next-line prefer-promise-reject-errors - // return Promise.reject('Required field'); - // } - // return Promise.resolve(); - // }, - // }), - // ]} - > - setChecked(v.target.checked)}> - {t('view:confirmClosure')} - - - - - - {popupError ? : ''} - - - - - - -
-
- ); -}; - -export default TransferActionModel; diff --git a/web/src/Components/Models/UserActionConfirmationModel.tsx b/web/src/Components/Models/UserActionConfirmationModel.tsx deleted file mode 100644 index 094feb568..000000000 --- a/web/src/Components/Models/UserActionConfirmationModel.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Alert, Form, Modal, Button } from 'antd'; -import { FC, useEffect, useState } from 'react'; -import TextArea from 'antd/lib/input/TextArea'; -import { useTranslation } from 'react-i18next'; - -export interface UserActionProps { - actionInfo: any; - onActionConfirmed: any; - onActionCanceled: any; - openModal: any; - errorMsg: any; - loading: any; -} - -const UserActionConfirmationModel: FC = (props: UserActionProps) => { - const { actionInfo, onActionConfirmed, onActionCanceled, openModal, errorMsg, loading } = props; - const [comment, setComment] = useState(''); - const { i18n, t } = useTranslation(['userProfile']); - - useEffect(() => { - setComment(''); - }, [openModal]); - - return ( - -
{actionInfo.icon}
-
{actionInfo.headerText}
- - } - className={'popup-' + actionInfo.type} - open={openModal} - width={Math.min(400, window.innerWidth)} - centered={true} - onCancel={onActionCanceled} - destroyOnClose={true} - footer={null} - > -

{actionInfo.text}

-
{ - onActionConfirmed(comment); - }} - > - -