diff --git a/.circleci/config.yml b/.circleci/config.yml
index 378589967..3f2da6420 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,1059 +1,11 @@
-# CircleCI v2 Config
version: 2.1
-
-##
-# orbs
-#
-# Orbs used in this pipeline
-##
+setup: true
orbs:
- anchore: anchore/anchore-engine@1.9.0
- slack: circleci/slack@4.12.5 # Ref: https://github.com/mojaloop/ci-config/tree/main/slack-templates
- pr-tools: mojaloop/pr-tools@0.1.10 # Ref: https://github.com/mojaloop/ci-config/
- gh: circleci/github-cli@2.2.0
-
-##
-# defaults
-#
-# YAML defaults templates, in alphabetical order
-##
-defaults_docker_Dependencies: &defaults_docker_Dependencies |
- apk --no-cache add bash
- apk --no-cache add git
- apk --no-cache add ca-certificates
- apk --no-cache add curl
- apk --no-cache add openssh-client
- apk --no-cache add -t build-dependencies make gcc g++ python3 libtool autoconf automake jq
- apk --no-cache add -t openssl ncurses coreutils libgcc linux-headers grep util-linux binutils findutils
- apk --no-cache add librdkafka-dev
-
-## Default 'default-machine' executor dependencies
-defaults_machine_Dependencies: &defaults_machine_Dependencies |
- ## Add Package Repos
- ## Ref: https://docs.confluent.io/platform/current/installation/installing_cp/deb-ubuntu.html#get-the-software
- wget -qO - https://packages.confluent.io/deb/7.4/archive.key | sudo apt-key add -
- sudo add-apt-repository -y "deb https://packages.confluent.io/clients/deb $(lsb_release -cs) main"
-
- ## Install deps
- sudo apt install -y librdkafka-dev curl bash musl-dev libsasl2-dev
- sudo ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1
-
-defaults_awsCliDependencies: &defaults_awsCliDependencies |
- apk --no-cache add aws-cli
-
-defaults_license_scanner: &defaults_license_scanner
- name: Install and set up license-scanner
- command: |
- git clone https://github.com/mojaloop/license-scanner /tmp/license-scanner
- cd /tmp/license-scanner && make build default-files set-up
-
-defaults_npm_auth: &defaults_npm_auth
- name: Update NPM registry auth token
- command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
-
-defaults_npm_publish_release: &defaults_npm_publish_release
- name: Publish NPM $RELEASE_TAG artifact
- command: |
- source $BASH_ENV
- echo "Publishing tag $RELEASE_TAG"
- npm publish --tag $RELEASE_TAG --access public
-
-defaults_export_version_from_package: &defaults_export_version_from_package
- name: Format the changelog into the github release body and get release tag
- command: |
- git diff --no-indent-heuristic main~1 HEAD CHANGELOG.md | sed -n '/^+[^+]/ s/^+//p' > /tmp/changes
- echo 'export RELEASE_CHANGES=`cat /tmp/changes`' >> $BASH_ENV
- echo 'export RELEASE_TAG=`cat package-lock.json | jq -r .version`' >> $BASH_ENV
-
-defaults_configure_git: &defaults_configure_git
- name: Configure git
- command: |
- git config user.email ${GIT_CI_EMAIL}
- git config user.name ${GIT_CI_USER}
-
-defaults_configure_nvmrc: &defaults_configure_nvmrc
- name: Configure NVMRC
- command: |
- if [ -z "$NVMRC_VERSION" ]; then
- echo "==> Configuring NVMRC_VERSION!"
-
- export ENV_DOT_PROFILE=$HOME/.profile
- touch $ENV_DOT_PROFILE
-
- export NVMRC_VERSION=$(cat $CIRCLE_WORKING_DIRECTORY/.nvmrc)
- echo "export NVMRC_VERSION=$NVMRC_VERSION" >> $ENV_DOT_PROFILE
- fi
- echo "NVMRC_VERSION=$NVMRC_VERSION"
-
-defaults_configure_nvm: &defaults_configure_nvm
- name: Configure NVM
- command: |
- cd $HOME
- export ENV_DOT_PROFILE=$HOME/.profile
- touch $ENV_DOT_PROFILE
- echo "1. Check/Set NVM_DIR env variable"
- if [ -z "$NVM_DIR" ]; then
- export NVM_DIR="$HOME/.nvm"
- echo "==> NVM_DIR has been exported - $NVM_DIR"
- else
- echo "==> NVM_DIR already exists - $NVM_DIR"
- fi
- echo "2. Check/Set NVMRC_VERSION env variable"
- if [ -z "$NVMRC_VERSION" ]; then
- echo "==> Configuring NVMRC_VERSION!"
- export NVMRC_VERSION=$(cat $CIRCLE_WORKING_DIRECTORY/.nvmrc)
- echo "export NVMRC_VERSION=$NVMRC_VERSION" >> $ENV_DOT_PROFILE
- fi
- echo "3. Configure NVM"
- ## Lets check if an existing NVM_DIR exists, if it does lets skil
- if [ -e "$NVM_DIR" ]; then
- echo "==> $NVM_DIR exists. Skipping steps 3!"
- # echo "5. Executing $NVM_DIR/nvm.sh"
- # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
- else
- echo "==> $NVM_DIR does not exists. Executing steps 4-5!"
- echo "4. Installing NVM"
- curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
- echo "5. Executing $NVM_DIR/nvm.sh"
- [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
- fi
- ## Ref: https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252
- if [ ! -z "$NVM_ARCH_UNOFFICIAL_OVERRIDE" ]; then
- echo "==> Handle NVM_ARCH_UNOFFICIAL_OVERRIDE=$NVM_ARCH_UNOFFICIAL_OVERRIDE!"
- echo "nvm_get_arch() { nvm_echo \"${NVM_ARCH_UNOFFICIAL_OVERRIDE}\"; }" >> $ENV_DOT_PROFILE
- echo "export NVM_NODEJS_ORG_MIRROR=https://unofficial-builds.nodejs.org/download/release" >> $ENV_DOT_PROFILE
- source $ENV_DOT_PROFILE
- fi
- echo "6. Setup Node version"
- if [ -n "$NVMRC_VERSION" ]; then
- echo "==> Installing Node version: $NVMRC_VERSION"
- nvm install $NVMRC_VERSION
- nvm alias default $NVMRC_VERSION
- nvm use $NVMRC_VERSION
- cd $CIRCLE_WORKING_DIRECTORY
- else
- echo "==> ERROR - NVMRC_VERSION has not been set! - NVMRC_VERSION: $NVMRC_VERSION"
- exit 1
- fi
-
-defaults_display_versions: &defaults_display_versions
- name: Display Versions
- command: |
- echo "What is the active version of Nodejs?"
- echo "node: $(node --version)"
- echo "yarn: $(yarn --version)"
- echo "npm: $(npm --version)"
- echo "nvm: $(nvm --version)"
-
-defaults_environment: &defaults_environment
- ## env var for nx to set main branch
- MAIN_BRANCH_NAME: main
- ## Disable LIBRDKAFKA build since we install it via general dependencies
- # BUILD_LIBRDKAFKA: 0
-
-##
-# Executors
-#
-# CircleCI Executors
-##
-executors:
- default-docker:
- working_directory: &WORKING_DIR /home/circleci/project
- shell: "/bin/sh -leo pipefail" ## Ref: https://circleci.com/docs/env-vars/#alpine-linux
- environment:
- BASH_ENV: /etc/profile ## Ref: https://circleci.com/docs/env-vars/#alpine-linux
- NVM_ARCH_UNOFFICIAL_OVERRIDE: x64-musl ## Ref: https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252
- docker:
- - image: node:18-alpine3.19 # Ref: https://hub.docker.com/_/node?tab=tags&page=1&name=alpine
-
- default-machine:
- working_directory: *WORKING_DIR
- shell: "/bin/bash -leo pipefail"
- machine:
- image: ubuntu-2204:2023.04.2 # Ref: https://circleci.com/developer/machine/image/ubuntu-2204
-
-##
-# Jobs
-#
-# A map of CircleCI jobs
-##
-jobs:
- setup:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - run:
- name: Update NPM install
- command: npm ci
- - save_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- paths:
- - node_modules
-
- test-dependencies:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- name: Execute dependency tests
- command: npm run dep:check
-
- test-lint:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- name: Execute lint tests
- command: npm run lint
-
- test-unit:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- # This is needed for legacy core tests. Remove this once 'tape' is fully deprecated.
- name: Install tape, tapes and tap-xunit
- command: npm install tape tapes tap-xunit
- - run:
- name: Create dir for test results
- command: mkdir -p ./test/results
- - run:
- name: Execute unit tests
- command: npm -s run test:xunit
- - store_artifacts:
- path: ./test/results
- destination: test
- - store_test_results:
- path: ./test/results
-
- test-coverage:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - run:
- name: Install AWS CLI dependencies
- command: *defaults_awsCliDependencies
- - checkout
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- name: Execute code coverage check
- command: npm -s run test:coverage-check
- - store_artifacts:
- path: coverage
- destination: test
- - store_test_results:
- path: coverage
-
- build-local:
- executor: default-machine
- environment:
- <<: *defaults_environment
- steps:
- - checkout
- - run:
- <<: *defaults_configure_nvmrc
- - run:
- <<: *defaults_display_versions
- - run:
- name: Build Docker local image
- command: |
- source ~/.profile
- export DOCKER_NODE_VERSION="$NVMRC_VERSION-alpine"
- echo "export DOCKER_NODE_VERSION=$NVMRC_VERSION-alpine" >> $BASH_ENV
- echo "Building Docker image: ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local --build-arg NODE_VERSION=$DOCKER_NODE_VERSION"
- docker build -t ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local --build-arg NODE_VERSION=$DOCKER_NODE_VERSION .
- - run:
- name: Save docker image to workspace
- command: docker save -o /tmp/docker-image.tar ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local
- - persist_to_workspace:
- root: /tmp
- paths:
- - ./docker-image.tar
-
- test-integration:
- executor: default-machine
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_machine_Dependencies
- - checkout
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - attach_workspace:
- at: /tmp
- - run:
- name: Create dir for test results
- command: mkdir -p ./test/results
- - run:
- name: Execute integration tests
- command: |
- # Set Node version to default (Note: this is needed on Ubuntu)
- nvm use default
- npm ci
-
- echo "Running integration tests...."
- bash ./test/scripts/test-integration.sh
- environment:
- ENDPOINT_URL: http://localhost:4545/notification
- UV_THREADPOOL_SIZE: 12
- WAIT_FOR_REBALANCE: 20
- TEST_INT_RETRY_COUNT: 30
- TEST_INT_RETRY_DELAY: 2
- TEST_INT_REBALANCE_DELAY: 20000
- - store_artifacts:
- path: ./test/results
- destination: test
- - store_test_results:
- path: ./test/results
-
- test-functional:
- executor: default-machine
- environment:
- ML_CORE_TEST_HARNESS_DIR: /tmp/ml-core-test-harness
- steps:
- - checkout
- - attach_workspace:
- at: /tmp
- - run:
- name: Load the pre-built docker image from workspace
- command: docker load -i /tmp/docker-image.tar
- - run:
- name: Execute TTK functional tests
- command: bash ./test/scripts/test-functional.sh
- - store_artifacts:
- path: /tmp/ml-core-test-harness/reports
- destination: test
-
- vulnerability-check:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- name: Create dir for test results
- command: mkdir -p ./audit/results
- - run:
- name: Check for new npm vulnerabilities
- command: npm run audit:check -- -o json > ./audit/results/auditResults.json
- - store_artifacts:
- path: ./audit/results
- destination: audit
-
- audit-licenses:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - run:
- <<: *defaults_license_scanner
- - checkout
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- name: Run the license-scanner
- command: cd /tmp/license-scanner && pathToRepo=$CIRCLE_WORKING_DIRECTORY make run
- - store_artifacts:
- path: /tmp/license-scanner/results
- destination: licenses
-
- license-scan:
- executor: default-machine
- environment:
- <<: *defaults_environment
- steps:
- - attach_workspace:
- at: /tmp
- - run:
- name: Load the pre-built docker image from workspace
- command: docker load -i /tmp/docker-image.tar
- - run:
- <<: *defaults_license_scanner
- - run:
- name: Run the license-scanner
- command: cd /tmp/license-scanner && mode=docker dockerImages=${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local make run
- - store_artifacts:
- path: /tmp/license-scanner/results
- destination: licenses
-
- image-scan:
- executor: anchore/anchore_engine
- shell: /bin/sh -leo pipefail ## Ref: https://circleci.com/docs/env-vars/#alpine-linux
- environment:
- <<: *defaults_environment
- BASH_ENV: /etc/profile ## Ref: https://circleci.com/docs/env-vars/#alpine-linux
- ENV: ~/.profile
- NVM_ARCH_UNOFFICIAL_OVERRIDE: x64-musl ## Ref: https://github.com/nvm-sh/nvm/issues/1102#issuecomment-550572252
- working_directory: *WORKING_DIR
- steps:
- - setup_remote_docker
- - attach_workspace:
- at: /tmp
- - run:
- name: Install docker dependencies for anchore
- command: |
- apk add --update py-pip docker python3-dev libffi-dev openssl-dev gcc libc-dev make jq curl bash
- - run:
- name: Install AWS CLI dependencies
- command: *defaults_awsCliDependencies
- - checkout
- - run:
- name: Setup Slack config
- command: |
- echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV
- echo "export SLACK_RELEASE_TYPE='GitHub Release'" >> $BASH_ENV
- echo "export SLACK_RELEASE_TAG='${RELEASE_TAG} on ${CIRCLE_BRANCH} branch'" >> $BASH_ENV
- echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV
- echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV
- echo "export SLACK_CUSTOM_MSG='Anchore Image Scan failed for: \`${DOCKER_ORG}/${CIRCLE_PROJECT_REPONAME}:${CIRCLE_TAG}\`'" >> $BASH_ENV
- - run:
- <<: *defaults_configure_nvm
- - run:
- <<: *defaults_display_versions
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - run:
- name: Load the pre-built docker image from workspace
- command: docker load -i /tmp/docker-image.tar
- - run:
- name: Download the mojaloop/ci-config repo
- command: |
- git clone https://github.com/mojaloop/ci-config /tmp/ci-config
- # Generate the mojaloop anchore-policy
- cd /tmp/ci-config/container-scanning && ./mojaloop-policy-generator.js /tmp/mojaloop-policy.json
- - run:
- name: Pull base image locally
- command: |
- echo "Pulling docker image: node:$NVMRC_VERSION-alpine"
- docker pull node:$NVMRC_VERSION-alpine
- ## Analyze the base and derived image
- ## Note: It seems images are scanned in parallel, so preloading the base image result doesn't give us any real performance gain
- - anchore/analyze_local_image:
- # Force the older version, version 0.7.0 was just published, and is broken
- anchore_version: v0.6.1
- image_name: "docker.io/node:$NVMRC_VERSION-alpine ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local"
- policy_failure: false
- timeout: '500'
- # Note: if the generated policy is invalid, this will fallback to the default policy, which we don't want!
- policy_bundle_file_path: /tmp/mojaloop-policy.json
- - run:
- name: Upload Anchore reports to s3
- command: |
- aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive
- aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*"
- aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive
- - run:
- name: Evaluate failures
- command: /tmp/ci-config/container-scanning/anchore-result-diff.js anchore-reports/node_${NVMRC_VERSION}-alpine-policy.json anchore-reports/${CIRCLE_PROJECT_REPONAME}*-policy.json
- - store_artifacts:
- path: anchore-reports
- - slack/notify:
- event: fail
- template: SLACK_TEMP_RELEASE_FAILURE
-
- release:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - restore_cache:
- keys:
- - dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- <<: *defaults_configure_git
- - run:
- name: Setup Slack config
- command: |
- echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV
- echo "export SLACK_RELEASE_TYPE='GitHub Release'" >> $BASH_ENV
- echo "export SLACK_RELEASE_TAG='${RELEASE_TAG} on ${CIRCLE_BRANCH} branch'" >> $BASH_ENV
- echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV
- echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV
- - run:
- name: Generate changelog and bump package version
- command: npm run release -- --no-verify
- - run:
- name: Push the release
- command: git push --follow-tags origin ${CIRCLE_BRANCH}
- - slack/notify:
- event: fail
- template: SLACK_TEMP_RELEASE_FAILURE
-
- github-release:
- executor: default-machine
- shell: "/bin/bash -eo pipefail"
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install git
- command: |
- sudo apt-get update && sudo apt-get install -y git
- - gh/install
- - checkout
- - run:
- <<: *defaults_configure_git
- - run:
- name: Fetch updated release branch
- command: |
- git fetch origin
- git checkout origin/${CIRCLE_BRANCH}
- - run:
- <<: *defaults_export_version_from_package
- - run:
- name: Check the release changes
- command: |
- echo "Changes are: ${RELEASE_CHANGES}"
- - run:
- name: Setup Slack config
- command: |
- echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV
- echo "export SLACK_RELEASE_TYPE='Github Release'" >> $BASH_ENV
- echo "export SLACK_RELEASE_TAG=v${RELEASE_TAG}" >> $BASH_ENV
- echo "export SLACK_RELEASE_URL=https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/v${RELEASE_TAG}" >> $BASH_ENV
- echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV
- echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV
- - run:
- name: Create Release
- command: |
- gh release create "v${RELEASE_TAG}" --title "v${RELEASE_TAG} Release" --draft=false --notes "${RELEASE_CHANGES}" ./CHANGELOG.md
- - slack/notify:
- event: pass
- template: SLACK_TEMP_RELEASE_SUCCESS
- - slack/notify:
- event: fail
- template: SLACK_TEMP_RELEASE_FAILURE
-
- publish-docker:
- executor: default-machine
- shell: "/bin/bash -eo pipefail"
- environment:
- <<: *defaults_environment
- steps:
- - checkout
- - run:
- name: Setup for LATEST release
- command: |
- echo "export RELEASE_TAG=$RELEASE_TAG_PROD" >> $BASH_ENV
- echo "RELEASE_TAG=$RELEASE_TAG_PROD"
-
- PACKAGE_VERSION=$(cat package-lock.json | jq -r .version)
- echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV
- echo "PACKAGE_VERSION=${PACKAGE_VERSION}"
- - run:
- name: Setup Slack config
- command: |
- echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV
- echo "export SLACK_RELEASE_TYPE='Docker Release'" >> $BASH_ENV
- echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV
- echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV
- echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV
- - attach_workspace:
- at: /tmp
- - run:
- name: Load the pre-built docker image from workspace
- command: |
- docker load -i /tmp/docker-image.tar
- - run:
- name: Login to Docker Hub
- command: docker login -u $DOCKER_USER -p $DOCKER_PASS
- - run:
- name: Re-tag pre built image
- command: |
- docker tag ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG
- docker tag ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG
- - run:
- name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub
- command: |
- echo "Publishing ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG"
- docker push ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG
- echo "Publishing ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG"
- docker push ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG
- - run:
- name: Set Image Digest
- command: |
- IMAGE_DIGEST=$(docker inspect ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:v${CIRCLE_TAG:1} | jq '.[0].RepoDigests | .[]')
- echo "IMAGE_DIGEST=${IMAGE_DIGEST}"
- echo "export IMAGE_DIGEST=${IMAGE_DIGEST}" >> $BASH_ENV
- - run:
- name: Update Slack config
- command: |
- echo "export SLACK_RELEASE_URL='https://hub.docker.com/layers/${CIRCLE_PROJECT_REPONAME}/${DOCKER_ORG}/${CIRCLE_PROJECT_REPONAME}/v${CIRCLE_TAG:1}/images/${IMAGE_DIGEST}?context=explore'" | sed -r "s/${DOCKER_ORG}\/${CIRCLE_PROJECT_REPONAME}@sha256:/sha256-/g" >> $BASH_ENV
- - slack/notify:
- event: pass
- template: SLACK_TEMP_RELEASE_SUCCESS
- - slack/notify:
- event: fail
- template: SLACK_TEMP_RELEASE_FAILURE
-
- publish-docker-snapshot:
- executor: default-machine
- shell: "/bin/bash -eo pipefail"
- environment:
- <<: *defaults_environment
- steps:
- - checkout
- - run:
- name: Setup for SNAPSHOT release
- command: |
- echo "export RELEASE_TAG=$RELEASE_TAG_SNAPSHOT" >> $BASH_ENV
- echo "RELEASE_TAG=$RELEASE_TAG_SNAPSHOT"
-
- PACKAGE_VERSION=$(cat package-lock.json | jq -r .version)
- echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV
- echo "PACKAGE_VERSION=${PACKAGE_VERSION}"
- - run:
- name: Setup Slack config
- command: |
- echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV
- echo "export SLACK_RELEASE_TYPE='Docker Release'" >> $BASH_ENV
- echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV
- echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV
- echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV
- - attach_workspace:
- at: /tmp
- - run:
- name: Load the pre-built docker image from workspace
- command: |
- docker load -i /tmp/docker-image.tar
- - run:
- name: Login to Docker Hub
- command: docker login -u $DOCKER_USER -p $DOCKER_PASS
- - run:
- name: Re-tag pre built image
- command: |
- docker tag ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG
- docker tag ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:local ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG
- - run:
- name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub
- command: |
- echo "Publishing ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG"
- docker push ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG
- echo "Publishing ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG"
- docker push ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG
- - run:
- name: Set Image Digest
- command: |
- IMAGE_DIGEST=$(docker inspect ${DOCKER_ORG:-mojaloop}/$CIRCLE_PROJECT_REPONAME:v${CIRCLE_TAG:1} | jq '.[0].RepoDigests | .[]')
- echo "IMAGE_DIGEST=${IMAGE_DIGEST}"
- echo "export IMAGE_DIGEST=${IMAGE_DIGEST}" >> $BASH_ENV
- - run:
- name: Update Slack config
- command: |
- echo "export SLACK_RELEASE_URL='https://hub.docker.com/layers/${CIRCLE_PROJECT_REPONAME}/${DOCKER_ORG}/${CIRCLE_PROJECT_REPONAME}/v${CIRCLE_TAG:1}/images/${IMAGE_DIGEST}?context=explore'" | sed -r "s/${DOCKER_ORG}\/${CIRCLE_PROJECT_REPONAME}@sha256:/sha256-/g" >> $BASH_ENV
- - slack/notify:
- event: pass
- template: SLACK_TEMP_RELEASE_SUCCESS
- - slack/notify:
- event: fail
- template: SLACK_TEMP_RELEASE_FAILURE
-
- publish-npm:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- name: Setup for LATEST release
- command: |
- echo "export RELEASE_TAG=$RELEASE_TAG_PROD" >> $BASH_ENV
- echo "RELEASE_TAG=$RELEASE_TAG_PROD"
- PACKAGE_VERSION=$(cat package-lock.json | jq -r .version)
- echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV
- echo "PACKAGE_VERSION=${PACKAGE_VERSION}"
- - run:
- name: Setup Slack config
- command: |
- echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV
- echo "export SLACK_RELEASE_TYPE='NPM Release'" >> $BASH_ENV
- echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV
- echo "export SLACK_RELEASE_URL=https://www.npmjs.com/package/@mojaloop/${CIRCLE_PROJECT_REPONAME}/v/${CIRCLE_TAG:1}" >> $BASH_ENV
- echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV
- echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV
- - run:
- <<: *defaults_npm_auth
- - run:
- <<: *defaults_npm_publish_release
- - slack/notify:
- event: pass
- template: SLACK_TEMP_RELEASE_SUCCESS
- - slack/notify:
- event: fail
- template: SLACK_TEMP_RELEASE_FAILURE
-
- publish-npm-snapshot:
- executor: default-docker
- environment:
- <<: *defaults_environment
- steps:
- - run:
- name: Install general dependencies
- command: *defaults_docker_Dependencies
- - checkout
- - restore_cache:
- key: dependency-cache-{{ .Environment.CIRCLE_SHA1 }}
- - run:
- name: Setup for SNAPSHOT release
- command: |
- echo "export RELEASE_TAG=${RELEASE_TAG_SNAPSHOT}" >> $BASH_ENV
- echo "RELEASE_TAG=${RELEASE_TAG_SNAPSHOT}"
- echo "Override package version: ${CIRCLE_TAG:1}"
- npx standard-version --skip.tag --skip.commit --skip.changelog --release-as ${CIRCLE_TAG:1}
- PACKAGE_VERSION=$(cat package-lock.json | jq -r .version)
- echo "export PACKAGE_VERSION=${PACKAGE_VERSION}" >> $BASH_ENV
- echo "PACKAGE_VERSION=${PACKAGE_VERSION}"
- - run:
- name: Setup Slack config
- command: |
- echo "export SLACK_PROJECT_NAME=${CIRCLE_PROJECT_REPONAME}" >> $BASH_ENV
- echo "export SLACK_RELEASE_TYPE='NPM Snapshot'" >> $BASH_ENV
- echo "export SLACK_RELEASE_TAG=v${CIRCLE_TAG:1}" >> $BASH_ENV
- echo "export SLACK_RELEASE_URL=https://www.npmjs.com/package/@mojaloop/${CIRCLE_PROJECT_REPONAME}/v/${CIRCLE_TAG:1}" >> $BASH_ENV
- echo "export SLACK_BUILD_ID=${CIRCLE_BUILD_NUM}" >> $BASH_ENV
- echo "export SLACK_CI_URL=${CIRCLE_BUILD_URL}" >> $BASH_ENV
- - run:
- <<: *defaults_npm_auth
- - run:
- <<: *defaults_npm_publish_release
- - slack/notify:
- event: pass
- template: SLACK_TEMP_RELEASE_SUCCESS
- - slack/notify:
- event: fail
- template: SLACK_TEMP_RELEASE_FAILURE
-
-##
-# Workflows
-#
-# CircleCI Workflow config
-##
+ build: mojaloop/build@1.0.22
workflows:
- build_and_test:
+ setup:
jobs:
- - pr-tools/pr-title-check:
- context: org-global
- - setup:
- context: org-global
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - test-dependencies:
- context: org-global
- requires:
- - setup
- filters:
- tags:
- ignore: /.*/
- branches:
- ignore:
- - main
- - test-lint:
- context: org-global
- requires:
- - setup
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - test-unit:
- context: org-global
- requires:
- - setup
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - test-coverage:
- context: org-global
- requires:
- - setup
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - test-integration:
- context: org-global
- requires:
- - setup
- - build-local
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - test-functional:
- context: org-global
- requires:
- - setup
- - build-local
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - vulnerability-check:
- context: org-global
- requires:
- - setup
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - audit-licenses:
- context: org-global
- requires:
- - setup
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - build-local:
- context: org-global
- requires:
- - setup
- filters:
- tags:
- only: /.*/
- branches:
- ignore:
- - /feature*/
- - /bugfix*/
- - license-scan:
- context: org-global
- requires:
- - build-local
- filters:
- tags:
- only: /v[0-9]+(\.[0-9]+)*(\-snapshot(\.[0-9]+)?)?(\-hotfix(\.[0-9]+)?)?(\-perf(\.[0-9]+)?)?/
- branches:
- ignore:
- - /.*/
- - image-scan:
- context: org-global
- requires:
- - build-local
- filters:
- tags:
- only: /v[0-9]+(\.[0-9]+)*(\-snapshot(\.[0-9]+)?)?(\-hotfix(\.[0-9]+)?)?(\-perf(\.[0-9]+)?)?/
- branches:
- ignore:
- - /.*/
- # New commits to main release automatically
- - release:
- context: org-global
- requires:
- - pr-tools/pr-title-check
- ## Only do this check on PRs
- # - test-dependencies
- - test-lint
- - test-unit
- - test-coverage
- - test-integration
- - test-functional
- - vulnerability-check
- - audit-licenses
- - license-scan
- - image-scan
- filters:
- branches:
- only:
- - main
- - /release\/v.*/
- - github-release:
- context: org-global
- requires:
- - release
- filters:
- branches:
- only:
- - main
- - /release\/v.*/
- - publish-docker:
- context: org-global
- requires:
- - build-local
- - pr-tools/pr-title-check
- ## Only do this check on PRs
- # - test-dependencies
- - test-lint
- - test-unit
- - test-coverage
- - test-integration
- - test-functional
- - vulnerability-check
- - audit-licenses
- - license-scan
- - image-scan
- filters:
- tags:
- only: /v[0-9]+(\.[0-9]+)*/
- branches:
- ignore:
- - /.*/
- - publish-docker-snapshot:
- context: org-global
- requires:
- - build-local
- - pr-tools/pr-title-check
- ## Only do this check on PRs
- # - test-dependencies
- - test-lint
- - test-unit
- - test-coverage
- - test-integration
- - test-functional
- - vulnerability-check
- - audit-licenses
- - license-scan
- - image-scan
- filters:
- tags:
- only: /v[0-9]+(\.[0-9]+)*\-snapshot+((\.[0-9]+)?)/
- branches:
- ignore:
- - /.*/
- - publish-npm:
- context: org-global
- requires:
- - pr-tools/pr-title-check
- ## Only do this check on PRs
- # - test-dependencies
- - test-lint
- - test-unit
- - test-coverage
- - test-integration
- - test-functional
- - vulnerability-check
- - audit-licenses
- - license-scan
- - image-scan
- filters:
- tags:
- only: /v[0-9]+(\.[0-9]+)*/
- branches:
- ignore:
- - /.*/
- - publish-npm-snapshot:
- context: org-global
- requires:
- - pr-tools/pr-title-check
- ## Only do this check on PRs
- # - test-dependencies
- - test-lint
- - test-unit
- - test-coverage
- - test-integration
- - test-functional
- - vulnerability-check
- - audit-licenses
- - license-scan
- - image-scan
+ - build/workflow:
filters:
tags:
- only: /v[0-9]+(\.[0-9]+)*\-snapshot+((\.[0-9]+)?)/
- branches:
- ignore:
- - /.*/
+ only: /v\d+(\.\d+){2}(-[a-zA-Z-][0-9a-zA-Z-]*\.\d+)?/
diff --git a/.ncurc.yaml b/.ncurc.yaml
index 79ef9049b..c3fd0c385 100644
--- a/.ncurc.yaml
+++ b/.ncurc.yaml
@@ -9,5 +9,7 @@ reject: [
"get-port",
# sinon v17.0.1 causes 58 tests to fail. This will need to be resolved in a future story.
# Issue is tracked here: https://github.com/mojaloop/project/issues/3616
- "sinon"
+ "sinon",
+ # glob >= 11 requires node >= 20
+ "glob"
]
diff --git a/.nvmrc b/.nvmrc
index 4a1f488b6..561a1e9a8 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-18.17.1
+18.20.3
diff --git a/.nycrc.yml b/.nycrc.yml
index 0b43be976..7add54979 100644
--- a/.nycrc.yml
+++ b/.nycrc.yml
@@ -17,5 +17,20 @@ exclude: [
"**/node_modules/**",
'**/migrations/**',
'**/ddl/**',
- '**/bulk*/**'
+ '**/bulk*/**',
+ 'src/shared/logger/**',
+ 'src/shared/loggingPlugin.js',
+ 'src/shared/constants.js',
+ 'src/domain/position/index.js',
+ 'src/domain/position/binProcessor.js',
+ 'src/handlers/positions/handler.js',
+ 'src/handlers/transfers/createRemittanceEntity.js',
+ 'src/handlers/transfers/FxFulfilService.js',
+ 'src/models/position/batch.js',
+ 'src/models/fxTransfer/**',
+ 'src/models/participant/externalParticipantCached.js', # todo: figure out why it shows only 50% coverage in Branch
+ 'src/models/transfer/facade.js', ## add more test coverage
+ 'src/shared/fspiopErrorFactory.js',
+ 'src/lib/proxyCache.js' # todo: remove this line after adding test coverage
]
+## todo: increase test coverage before merging feat/fx-impl to main branch
diff --git a/Dockerfile b/Dockerfile
index d1207c0cd..b7cbc27aa 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,26 +3,27 @@ ARG NODE_VERSION=lts-alpine
# NOTE: Ensure you set NODE_VERSION Build Argument as follows...
#
-# export NODE_VERSION="$(cat .nvmrc)-alpine" \
-# docker build \
-# --build-arg NODE_VERSION=$NODE_VERSION \
-# -t mojaloop/central-ledger:local \
-# . \
+# export NODE_VERSION="$(cat .nvmrc)-alpine"
+# docker build \
+# --build-arg NODE_VERSION=$NODE_VERSION \
+# -t mojaloop/central-ledger:local \
+# .
#
# Build Image
-FROM node:${NODE_VERSION} as builder
+FROM node:${NODE_VERSION} AS builder
WORKDIR /opt/app
RUN apk --no-cache add git
-RUN apk add --no-cache -t build-dependencies make gcc g++ python3 libtool openssl-dev autoconf automake bash \
+RUN apk add --no-cache -t build-dependencies make gcc g++ python3 py3-setuptools libtool openssl-dev autoconf automake bash \
&& cd $(npm root -g)/npm \
&& npm install -g node-gyp
COPY package.json package-lock.json* /opt/app/
RUN npm ci
+RUN npm prune --omit=dev
FROM node:${NODE_VERSION}
WORKDIR /opt/app
@@ -32,7 +33,7 @@ RUN mkdir ./logs && touch ./logs/combined.log
RUN ln -sf /dev/stdout ./logs/combined.log
# Create a non-root user: ml-user
-RUN adduser -D ml-user
+RUN adduser -D ml-user
USER ml-user
COPY --chown=ml-user --from=builder /opt/app .
@@ -43,7 +44,5 @@ COPY migrations /opt/app/migrations
COPY seeds /opt/app/seeds
COPY test /opt/app/test
-RUN npm prune --production
-
EXPOSE 3001
CMD ["npm", "run", "start"]
diff --git a/README.md b/README.md
index b38144ab2..3523eff6f 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ Or via docker build directly:
```bash
docker build \
- --build-arg NODE_VERSION="$(cat .nvmrc)-alpine" \
+ --build-arg NODE_VERSION="$(cat .nvmrc)-alpine3.19" \
-t mojaloop/ml-api-adapter:local \
.
```
@@ -113,12 +113,14 @@ NOTE: Only POSITION.PREPARE and POSITION.COMMIT is supported at this time, with
Batch processing can be enabled in the transfer execution flow. Follow the steps below to enable batch processing for a more efficient transfer execution:
+Note: The position messages with action 'FX_PREPARE', 'FX_COMMIT' and 'FX_TIMEOUT_RESERVED' are only supported in batch processing.
+
- **Step 1:** **Create a New Kafka Topic**
Create a new Kafka topic named `topic-transfer-position-batch` to handle batch processing events.
- **Step 2:** **Configure Action Type Mapping**
- Point the prepare handler to the newly created topic for the action type `prepare` using the `KAFKA.EVENT_TYPE_ACTION_TOPIC_MAP` configuration as shown below:
+ Point the prepare handler to the newly created topic for the action types those are supported in batch processing using the `KAFKA.EVENT_TYPE_ACTION_TOPIC_MAP` configuration as shown below:
```
"KAFKA": {
"EVENT_TYPE_ACTION_TOPIC_MAP" : {
@@ -126,8 +128,12 @@ Batch processing can be enabled in the transfer execution flow. Follow the steps
"PREPARE": "topic-transfer-position-batch",
"BULK_PREPARE": "topic-transfer-position",
"COMMIT": "topic-transfer-position-batch",
+ "FX_COMMIT": "topic-transfer-position-batch",
"BULK_COMMIT": "topic-transfer-position",
"RESERVE": "topic-transfer-position",
+ "FX_PREPARE": "topic-transfer-position-batch",
+ "TIMEOUT_RESERVED": "topic-transfer-position-batch",
+ "FX_TIMEOUT_RESERVED": "topic-transfer-position-batch"
}
}
}
@@ -185,7 +191,8 @@ If you want to run integration tests in a repetitive manner, you can startup the
Start containers required for Integration Tests
```bash
- docker-compose -f docker-compose.yml up -d mysql kafka init-kafka kafka-debug-console
+ source ./docker/env.sh
+ docker compose up -d mysql kafka init-kafka redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
```
Run wait script which will report once all required containers are up and running
@@ -220,7 +227,8 @@ If you want to run integration tests in a repetitive manner, you can startup the
Start containers required for Integration Tests, including a `central-ledger` container which will be used as a proxy shell.
```bash
- docker-compose -f docker-compose.yml -f docker-compose.integration.yml up -d kafka mysql central-ledger
+ source ./docker/env.sh
+ docker-compose -f docker-compose.yml -f docker-compose.integration.yml up -d kafka mysql central-ledger init-kafka redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
```
Run the Integration Tests from the `central-ledger` container
@@ -235,24 +243,42 @@ If you want to run override position topic tests you can repeat the above and us
#### For running integration tests for batch processing interactively
- Run dependecies
-```
-docker-compose up -d mysql kafka init-kafka kafka-debug-console
+```bash
+source ./docker/env.sh
+docker compose up -d mysql kafka init-kafka redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
npm run wait-4-docker
```
- Run central-ledger services
```
nvm use
npm run migrate
-env "CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__PREPARE=topic-transfer-position-batch" npm start
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__PREPARE=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__COMMIT=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__RESERVE=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__TIMEOUT_RESERVED=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__FX_TIMEOUT_RESERVED=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__ABORT=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__FX_ABORT=topic-transfer-position-batch
+npm start
```
- Additionally, run position batch handler in a new terminal
```
+nvm use
export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__PREPARE=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__FX_PREPARE=topic-transfer-position-batch
export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__COMMIT=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__TIMEOUT_RESERVED=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__FX_TIMEOUT_RESERVED=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__ABORT=topic-transfer-position-batch
+export CLEDG_KAFKA__EVENT_TYPE_ACTION_TOPIC_MAP__POSITION__FX_ABORT=topic-transfer-position-batch
export CLEDG_HANDLERS__API__DISABLED=true
node src/handlers/index.js handler --positionbatch
```
-- Run tests using `npx tape 'test/integration-override/**/handlerBatch.test.js'`
+- Run tests using the following commands in a new terminal
+```
+nvm use
+npm run test:int-override
+```
If you want to just run all of the integration suite non-interactively then use npm run `test:integration`.
@@ -263,7 +289,11 @@ It will handle docker start up, migration, service starting and testing. Be sure
If you want to run functional tests locally utilizing the [ml-core-test-harness](https://github.com/mojaloop/ml-core-test-harness), you can run the following commands:
```bash
-docker build -t mojaloop/central-ledger:local .
+export NODE_VERSION="$(cat .nvmrc)-alpine"
+docker build \
+ --build-arg NODE_VERSION=$NODE_VERSION \
+ -t mojaloop/central-ledger:local \
+ .
```
```bash
diff --git a/audit-ci.jsonc b/audit-ci.jsonc
index a6d37cc53..c75bb449a 100644
--- a/audit-ci.jsonc
+++ b/audit-ci.jsonc
@@ -4,6 +4,20 @@
// Only use one of ["low": true, "moderate": true, "high": true, "critical": true]
"moderate": true,
"allowlist": [ // NOTE: Please add as much information as possible to any items added to the allowList
- "GHSA-w5p7-h5w8-2hfq" // tap-spec>tap-out>trim; This has been analyzed and this is acceptable as it is used to run tests.
+ "GHSA-w5p7-h5w8-2hfq", // tap-spec>tap-out>trim; This has been analyzed and this is acceptable as it is used to run tests.
+ "GHSA-2mvq-xp48-4c77", // https://github.com/advisories/GHSA-2mvq-xp48-4c77
+ "GHSA-5854-jvxx-2cg9", // https://github.com/advisories/GHSA-5854-jvxx-2cg9
+ "GHSA-7hx8-2rxv-66xv", // https://github.com/advisories/GHSA-7hx8-2rxv-66xv
+ "GHSA-c429-5p7v-vgjp", // https://github.com/advisories/GHSA-c429-5p7v-vgjp
+ "GHSA-g64q-3vg8-8f93", // https://github.com/advisories/GHSA-g64q-3vg8-8f93
+ "GHSA-mg85-8mv5-ffjr", // https://github.com/advisories/GHSA-mg85-8mv5-ffjr
+ "GHSA-8hc4-vh64-cxmj", // https://github.com/advisories/GHSA-8hc4-vh64-cxmj
+ "GHSA-952p-6rrq-rcjv", // https://github.com/advisories/GHSA-952p-6rrq-rcjv
+ "GHSA-9wv6-86v2-598j", // https://github.com/advisories/GHSA-9wv6-86v2-598j
+ "GHSA-qwcr-r2fm-qrc7", // https://github.com/advisories/GHSA-qwcr-r2fm-qrc7
+ "GHSA-cm22-4g7w-348p", // https://github.com/advisories/GHSA-cm22-4g7w-348p
+ "GHSA-m6fv-jmcg-4jfg", // https://github.com/advisories/GHSA-m6fv-jmcg-4jfg
+ "GHSA-qw6h-vgh9-j6wx", // https://github.com/advisories/GHSA-qw6h-vgh9-j6wx
+ "GHSA-3xgq-45jj-v275" // High vulnerability https://github.com/advisories/GHSA-3xgq-45jj-v275 ignoring for now since devDependency
]
-}
\ No newline at end of file
+}
diff --git a/config/default.json b/config/default.json
index a244a7b1f..fae0711ea 100644
--- a/config/default.json
+++ b/config/default.json
@@ -78,20 +78,36 @@
},
"INTERNAL_TRANSFER_VALIDITY_SECONDS": "432000",
"ENABLE_ON_US_TRANSFERS": false,
+ "PAYEE_PARTICIPANT_CURRENCY_VALIDATION_ENABLED": false,
"CACHE": {
"CACHE_ENABLED": false,
"MAX_BYTE_SIZE": 10000000,
"EXPIRES_IN_MS": 1000
},
+ "PROXY_CACHE": {
+ "enabled": true,
+ "type": "redis-cluster",
+ "proxyConfig": {
+ "cluster": [
+ { "host": "localhost", "port": 6379 }
+ ]
+ }
+ },
"API_DOC_ENDPOINTS_ENABLED": true,
"KAFKA": {
"EVENT_TYPE_ACTION_TOPIC_MAP" : {
"POSITION":{
"PREPARE": null,
+ "FX_PREPARE": "topic-transfer-position-batch",
"BULK_PREPARE": null,
"COMMIT": null,
"BULK_COMMIT": null,
- "RESERVE": null
+ "RESERVE": null,
+ "FX_RESERVE": "topic-transfer-position-batch",
+ "TIMEOUT_RESERVED": null,
+ "FX_TIMEOUT_RESERVED": "topic-transfer-position-batch",
+ "ABORT": null,
+ "FX_ABORT": "topic-transfer-position-batch"
}
},
"TOPIC_TEMPLATES": {
diff --git a/docker-compose.yml b/docker-compose.yml
index 89c1c33ae..1ed34ac16 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,9 +1,22 @@
-version: "3.7"
-
networks:
cl-mojaloop-net:
name: cl-mojaloop-net
+
+# @see https://uninterrupted.tech/blog/hassle-free-redis-cluster-deployment-using-docker/
+x-redis-node: &REDIS_NODE
+ image: docker.io/bitnami/redis-cluster:6.2.14
+ environment: &REDIS_ENVS
+ ALLOW_EMPTY_PASSWORD: yes
+ REDIS_CLUSTER_DYNAMIC_IPS: no
+ REDIS_CLUSTER_ANNOUNCE_IP: ${REDIS_CLUSTER_ANNOUNCE_IP}
+ REDIS_NODES: redis-node-0:6379 redis-node-1:9301 redis-node-2:9302 redis-node-3:9303 redis-node-4:9304 redis-node-5:9305
+ healthcheck:
+ test: [ "CMD", "redis-cli", "ping" ]
+ timeout: 2s
+ networks:
+ - cl-mojaloop-net
+
services:
central-ledger:
image: mojaloop/central-ledger:local
@@ -31,10 +44,14 @@ services:
- CLEDG_MONGODB__DISABLED=false
networks:
- cl-mojaloop-net
+ extra_hosts:
+ - "redis-node-0:host-gateway"
depends_on:
- mysql
- kafka
- objstore
+ - redis-node-0
+ # - redis
healthcheck:
test: ["CMD", "sh", "-c" ,"apk --no-cache add curl", "&&", "curl", "http://localhost:3001/health"]
timeout: 20s
@@ -94,6 +111,77 @@ services:
retries: 10
start_period: 40s
interval: 30s
+
+ redis-node-0:
+ <<: *REDIS_NODE
+ environment:
+ <<: *REDIS_ENVS
+ REDIS_CLUSTER_CREATOR: yes
+ REDIS_PORT_NUMBER: 6379
+ depends_on:
+ - redis-node-1
+ - redis-node-2
+ ports:
+ - "6379:6379"
+ - "16379:16379"
+ redis-node-1:
+ <<: *REDIS_NODE
+ environment:
+ <<: *REDIS_ENVS
+ REDIS_PORT_NUMBER: 9301
+ ports:
+ - "9301:9301"
+ - "19301:19301"
+ redis-node-2:
+ <<: *REDIS_NODE
+ environment:
+ <<: *REDIS_ENVS
+ REDIS_PORT_NUMBER: 9302
+ ports:
+ - "9302:9302"
+ - "19302:19302"
+ redis-node-3:
+ <<: *REDIS_NODE
+ environment:
+ <<: *REDIS_ENVS
+ REDIS_PORT_NUMBER: 9303
+ ports:
+ - "9303:9303"
+ - "19303:19303"
+ redis-node-4:
+ <<: *REDIS_NODE
+ environment:
+ <<: *REDIS_ENVS
+ REDIS_PORT_NUMBER: 9304
+ ports:
+ - "9304:9304"
+ - "19304:19304"
+ redis-node-5:
+ <<: *REDIS_NODE
+ environment:
+ <<: *REDIS_ENVS
+ REDIS_PORT_NUMBER: 9305
+ ports:
+ - "9305:9305"
+ - "19305:19305"
+
+## To be used with proxyCache.type === 'redis'
+# redis:
+# image: redis:6.2.4-alpine
+# restart: "unless-stopped"
+# environment:
+# <<: *REDIS_ENVS
+# REDIS_CLUSTER_CREATOR: yes
+# depends_on:
+# - redis-node-1
+# - redis-node-2
+# - redis-node-3
+# - redis-node-4
+# - redis-node-5
+# ports:
+# - "6379:6379"
+# networks:
+# - cl-mojaloop-net
mockserver:
image: jamesdbloom/mockserver
diff --git a/docker/central-ledger/default.json b/docker/central-ledger/default.json
index 5571f464a..a8b233332 100644
--- a/docker/central-ledger/default.json
+++ b/docker/central-ledger/default.json
@@ -82,6 +82,15 @@
"MAX_BYTE_SIZE": 10000000,
"EXPIRES_IN_MS": 1000
},
+ "PROXY_CACHE": {
+ "enabled": true,
+ "type": "redis-cluster",
+ "proxyConfig": {
+ "cluster": [
+ { "host": "redis-node-0", "port": 6379 }
+ ]
+ }
+ },
"KAFKA": {
"TOPIC_TEMPLATES": {
"PARTICIPANT_TOPIC_TEMPLATE": {
diff --git a/docker/config-modifier/configs/central-ledger.js b/docker/config-modifier/configs/central-ledger.js
index 904c98ba8..902498719 100644
--- a/docker/config-modifier/configs/central-ledger.js
+++ b/docker/config-modifier/configs/central-ledger.js
@@ -12,7 +12,25 @@ module.exports = {
PASSWORD: '',
DATABASE: 'mlos'
},
+ PROXY_CACHE: {
+ enabled: true,
+ type: 'redis',
+ proxyConfig: {
+ cluster: undefined,
+ host: 'redis',
+ port: 6379
+ }
+ },
KAFKA: {
+ EVENT_TYPE_ACTION_TOPIC_MAP: {
+ POSITION: {
+ PREPARE: 'topic-transfer-position-batch',
+ BULK_PREPARE: null,
+ COMMIT: 'topic-transfer-position-batch',
+ BULK_COMMIT: null,
+ RESERVE: 'topic-transfer-position-batch'
+ }
+ },
CONSUMER: {
BULK: {
PREPARE: {
@@ -72,6 +90,13 @@ module.exports = {
'metadata.broker.list': 'kafka:29092'
}
}
+ },
+ POSITION_BATCH: {
+ config: {
+ rdkafkaConf: {
+ 'metadata.broker.list': 'kafka:29092'
+ }
+ }
}
},
ADMIN: {
diff --git a/docker/env.sh b/docker/env.sh
new file mode 100755
index 000000000..d3e0da0e4
--- /dev/null
+++ b/docker/env.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Retrieve the external IP address of the host machine (on macOS)
+# or the IP address of the docker0 interface (on Linux)
+get_external_ip() {
+ if [ "$(uname)" = "Linux" ]; then
+ echo "$(ip addr show docker0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)"
+ else
+ # Need to find a way to support Windows here
+ echo "$(route get ifconfig.me | grep interface | sed -e 's/.*: //' | xargs ipconfig getifaddr)"
+ fi
+}
+
+# set/override dynamic variables
+export REDIS_CLUSTER_ANNOUNCE_IP=$(get_external_ip)
diff --git a/docker/kafka/scripts/provision.sh b/docker/kafka/scripts/provision.sh
index 14a08c2aa..41485addc 100644
--- a/docker/kafka/scripts/provision.sh
+++ b/docker/kafka/scripts/provision.sh
@@ -25,8 +25,11 @@ topics=(
"topic-bulk-prepare"
"topic-bulk-fulfil"
"topic-bulk-processing"
- "topic-bulk-get",
+ "topic-bulk-get"
"topic-transfer-position-batch"
+ "topic-fx-quotes-post"
+ "topic-fx-quotes-put"
+ "topic-fx-quotes-get"
)
# Loop through the topics and create them using kafka-topics.sh
diff --git a/docker/ml-api-adapter/default.json b/docker/ml-api-adapter/default.json
index e701c2891..d58b20fce 100644
--- a/docker/ml-api-adapter/default.json
+++ b/docker/ml-api-adapter/default.json
@@ -1,4 +1,8 @@
{
+ "HUB_PARTICIPANT": {
+ "ID": 1,
+ "NAME": "Hub"
+ },
"PORT": 3000,
"HOSTNAME": "http://ml-api-adapter",
"ENDPOINT_SOURCE_URL": "http://host.docker.internal:3001",
@@ -13,7 +17,6 @@
},
"JWS": {
"JWS_SIGN": false,
- "FSPIOP_SOURCE_TO_SIGN": "switch",
"JWS_SIGNING_KEY_PATH": "secrets/jwsSigningKey.key"
}
},
diff --git a/documentation/db/erd-transfer-timeout.png b/documentation/db/erd-transfer-timeout.png
new file mode 100644
index 000000000..b8da0b8c7
Binary files /dev/null and b/documentation/db/erd-transfer-timeout.png differ
diff --git a/documentation/db/erd-transfer-timeout.txt b/documentation/db/erd-transfer-timeout.txt
new file mode 100644
index 000000000..ee441981f
--- /dev/null
+++ b/documentation/db/erd-transfer-timeout.txt
@@ -0,0 +1,81 @@
+# Visualize on https://erd.surge.sh
+# or https://quick-erd.surge.sh
+#
+# Relationship Types
+# - - one to one
+# -< - one to many
+# >- - many to one
+# >-< - many to many
+# -0 - one to zero or one
+# 0- - zero or one to one
+# 0-0 - zero or one to zero or one
+# -0< - one to zero or many
+# >0- - zero or many to one
+#
+////////////////////////////////////
+
+transfer
+---------------------
+transferId varchar(36) PK
+amount decimal(18,4)
+currencyId varchar(3) FK - currency.currencyId
+ilpCondition varchar(256)
+expirationDate datetime
+createdDate datetime
+
+
+transferStateChange__TSC
+---------------------
+transferStateChangeId bigint UN AI PK
+transferId varchar(36) FK >- transfer.transferId
+transferStateId varchar(50) FK - transferState.transferStateId
+reason varchar(512)
+createdDate datetime
+
+
+transferTimeout__TT
+---------------------
+transferTimeoutId bigint UN AI PK
+transferId varchar(36) UNIQUE FK - transfer.transferId
+expirationDate datetime
+createdDate datetime
+
+
+transferError__TE
+---------------------
+transferId varchar(36) PK
+transferStateChangeId bigint UN FK - transferStateChange.transferStateChangeId
+errorCode int UN
+errorDescription varchar(128)
+createdDate datetime
+
+
+segment
+---------------------
+segmentId int UN AI PK
+segmentType varchar(50)
+enumeration int
+tableName varchar(50)
+value bigint
+changedDate datetime
+# row example: 1, 'timeout', 0, 'transferStateChange', 255, '2024-04-24 18:07:15'
+
+
+expiringTransfer
+---------------------
+expiringTransferId bigint UN AI PK
+transferId varchar(36) UNIQUE FK - transfer.transferId
+expirationDate datetime INDEX
+createdDate datetime
+# todo: clarify, how we use this table
+
+
+
+# transfer (557, 340)
+# segment (348, 608)
+# expiringTransfer (1033, 574)
+# view: (5, -16)
+# zoom: 1.089
+# transferStateChange__TSC (38, 236)
+# transferTimeout__TT (974, 204)
+# transferError__TE (518, 34)
diff --git a/documentation/fx-implementation/README.md b/documentation/fx-implementation/README.md
new file mode 100644
index 000000000..299fe740c
--- /dev/null
+++ b/documentation/fx-implementation/README.md
@@ -0,0 +1,48 @@
+# FX Implementation
+
+## Implementation for Payer-Side Currency Conversion (Happy Path Only)
+
+We have developed functionality for foreign exchange (FX) transfer focusing on a specific scenario: Payer-side currency conversion.
+
+### Testing using ml-core-test-harness
+
+![Test Scenario](./assets/test-scenario.drawio.svg)
+
+To test the functionality, you can utilize [mojaloop/ml-core-test-harness](https://github.com/mojaloop/ml-core-test-harness):
+
+1. Clone the repository:
+ ```
+ git clone https://github.com/mojaloop/ml-core-test-harness.git
+ ```
+2. Checkout to the branch `feat/fx-impl`:
+ ```
+ git checkout feat/fx-impl
+ ```
+3. Run the services:
+ ```
+ docker-compose --profile all-services --profile ttk-provisioning --profile ttk-tests --profile debug up -d
+ ```
+4. Open the testing toolkit web UI at `http://localhost:9660`.
+5. Navigate to `Test Runner`, click on `Collection Manager`, and import the folder `docker/ml-testing-toolkit/test-cases/collections`.
+6. Select the file `fxp/payer_conversion.json`.
+7. Run the test case by clicking on the `Run` button.
+8. Verify that all tests have passed.
+9. Observe the sequence of requests and responses in each item of the test case.
+10. Open the last item, `Get Accounts for FXP AFTER transfer`, and go to `Scripts->Console Logs` to observe the position movements of different participant accounts, as shown below:
+ ```
+ "Payer Position BWP : 0 -> 300 (300)"
+
+ "Payee Position TZS : 0 -> -48000 (-48000)"
+
+ "FXP Source Currency BWP : 0 -> -300 (-300)"
+
+ "FXP Target Currency TZS : 0 -> 48000 (48000)"
+ ```
+
+### Implementation
+
+The implementation follows the information available in the repository [mojaloop/currency-conversion](https://github.com/mojaloop/currency-conversion).
+
+The flow diagram below illustrates the transfer with payer-side currency conversion:
+
+![FX Position Movements](./assets/fx-position-movements.drawio.svg)
diff --git a/documentation/fx-implementation/assets/fx-position-movements.drawio.svg b/documentation/fx-implementation/assets/fx-position-movements.drawio.svg
new file mode 100644
index 000000000..cd09ab325
--- /dev/null
+++ b/documentation/fx-implementation/assets/fx-position-movements.drawio.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/documentation/fx-implementation/assets/test-scenario.drawio.svg b/documentation/fx-implementation/assets/test-scenario.drawio.svg
new file mode 100644
index 000000000..4cb969e4e
--- /dev/null
+++ b/documentation/fx-implementation/assets/test-scenario.drawio.svg
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/documentation/sequence-diagrams/Handler - FX timeout.plantuml b/documentation/sequence-diagrams/Handler - FX timeout.plantuml
new file mode 100644
index 000000000..0cb2f3e97
--- /dev/null
+++ b/documentation/sequence-diagrams/Handler - FX timeout.plantuml
@@ -0,0 +1,123 @@
+@startuml
+title Transfer/ FX transfer Timeout-Handler Flow
+
+autonumber
+hide footbox
+skinparam ParticipantPadding 10
+
+box "Central Services" #MistyRose
+participant "Timeout \n handler (cron)" as toh
+participant "Position \n handler" as ph
+database "central-ledger\nDB" as clDb
+end box
+box Kafka
+queue "topic-\n transfer-position" as topicTP
+queue "topic-\n notification-event" as topicNE
+end box
+box "ML API Adapter Services" #LightBlue
+participant "Notification \n handler" as nh
+end box
+participant "FXP" as fxp
+actor "DFSP_1 \nPayer" as payer
+actor "DFSP_2 \nPayee" as payee
+
+legend
+DB tables:
+
+TT - transferTimeout fxTT - fxTransferTimeout
+TSC - transferStateChange fxTSC - fxTransferStateChange
+TE - transferError fxTE - fxTransferError
+end legend
+
+
+autonumber 1
+toh --> toh : run on cronTime\n HANDLERS_TIMEOUT_TIMEXP (default: 15sec)
+activate toh
+toh -> clDb : cleanup TT for transfers in particular states: \n [COMMITTED, ABORTED, RECEIVED_FULFIL, RECEIVED_REJECT, RESERVED_TIMEOUT]
+
+toh -> clDb : Insert (transferId, expirationDate) into TT for transfers in particular states:\n [RECEIVED_PREPARE, RESERVED]
+toh -> clDb : Insert EXPIRED_PREPARED state into TSC for transfers in RECEIVED_PREPARE states
+toh -> clDb : Insert RESERVED_TIMEOUT state into TSC for transfers in RESERVED state
+toh -> clDb : Insert expired error info into TE
+
+toh -> clDb : get expired transfers details from TT
+
+toh --> toh : for each expired transfer
+activate toh
+autonumber 8.1
+alt state === EXPIRED_PREPARED
+toh ->o topicNE : produce notification timeout-received message
+else state === RESERVED_TIMEOUT
+toh ->o topicTP : produce position timeout-reserved message
+end
+toh -> clDb : find related fxTransfer using cyril and check if it's NOT expeired yet
+alt related NOT expired fxTransfer found
+toh -> clDb : Upsert row with (fxTransferId, expirationDate) into fxTT
+note right: expirationDate === transfer.expirationDate \n OR now?
+alt fxState === RESERVED or RECEIVED_FULFIL_DEPENDENT
+toh -> clDb : Update fxState to RESERVED_TIMEOUT into fxTSC
+toh ->o topicTP : produce position fx-timeout-reserved message
+else fxState === RECEIVED_PREPARE
+toh -> clDb : Update fxState to EXPIRED_PREPARED into fxTSC
+toh ->o topicNE : produce notification fx-timeout-received message
+end
+end
+deactivate toh
+deactivate toh
+
+autonumber 9
+toh --> toh : run fxTimeout logic on cronTime\n HANDLERS_TIMEOUT_TIMEXP (default: 15sec)
+activate toh
+toh -> clDb : cleanup fxTT for fxTransfers in particular states: \n [COMMITTED, ABORTED, RECEIVED_FULFIL_DEPENDENT, RECEIVED_REJECT, RESERVED_TIMEOUT]
+
+toh -> clDb : Insert (fxTransferId, expirationDate) into fxTT for fxTransfers in particular states:\n [RECEIVED_PREPARE, RESERVED]
+toh -> clDb : Insert EXPIRED_PREPARED state into fxTSC for fxTransfers in RECEIVED_PREPARE states
+toh -> clDb : Insert RESERVED_TIMEOUT state into fxTSC for fxTransfers in RESERVED state
+toh -> clDb : Insert expired error info into fxTE
+
+toh -> clDb : get expired fxTransfers details from fxTT
+
+toh --> toh : for each expired fxTransfer
+activate toh
+autonumber 16.1
+alt state === EXPIRED_PREPARED
+toh ->o topicNE : produce notification fx-timeout-received message
+else state === RESERVED_TIMEOUT
+toh ->o topicTP : produce position fx-timeout-reserved message
+end
+toh -> clDb : find related transfer using cyril and check it's NOT expired yet
+note right: think, what if related transfer is already commited?
+alt related NOT expired transfer found
+toh -> clDb : Upsert (transferId, expirationDate) into TT
+toh -> clDb : Insert expired error info into TE
+alt state === RECEIVED_PREPARE
+toh -> clDb : Insert EXPIRED_PREPARED state into TSC with reason "related fxTransfer expired"
+toh ->o topicNE : produce notification timeout-received message
+else state === RESERVED
+toh -> clDb : Insert RESERVED_TIMEOUT state into TSC with reason "related fxTransfer expired"
+toh ->o topicTP : produce position timeout-reserved message
+end
+end
+
+deactivate toh
+deactivate toh
+
+autonumber 17
+topicNE o-> nh : consume notification\n message
+activate nh
+nh -> payer : send error notification\n callback to payer
+deactivate nh
+
+topicTP o-> ph : consume position timeout/fx-timeout\n message
+activate ph
+ph --> ph : process timeout / fx-timeout transfer
+ph ->o topicNE : produce notification timeout / fx-timeout messages
+
+deactivate ph
+
+topicNE o-> nh : consume notification\n message
+activate nh
+nh -> payee : send error notification\n callback to payee
+deactivate nh
+
+@enduml
diff --git a/documentation/sequence-diagrams/Handler - FX timeout.png b/documentation/sequence-diagrams/Handler - FX timeout.png
new file mode 100644
index 000000000..0074d43a5
Binary files /dev/null and b/documentation/sequence-diagrams/Handler - FX timeout.png differ
diff --git a/documentation/sequence-diagrams/Handler - timeout.plantuml b/documentation/sequence-diagrams/Handler - timeout.plantuml
new file mode 100644
index 000000000..3042a1540
--- /dev/null
+++ b/documentation/sequence-diagrams/Handler - timeout.plantuml
@@ -0,0 +1,81 @@
+@startuml
+title Transfer Timeout-Handler Flow \n(current impl.)
+
+autonumber
+hide footbox
+skinparam ParticipantPadding 10
+
+box "Central Services" #MistyRose
+participant "Timeout \n handler (cron)" as toh
+participant "Position \n handler" as ph
+database "central-ledger\nDB" as clDb
+end box
+box Kafka
+queue "topic-\n transfer-position" as topicTP
+queue "topic-\n notification-event" as topicNE
+end box
+box "ML API Adapter Services" #LightBlue
+participant "Notification \n handler" as nh
+end box
+actor "DFSP_1 \nPayer" as payer
+actor "DFSP_2 \nPayee" as payee
+
+toh --> toh : run on cronTime\n HANDLERS_TIMEOUT_TIMEXP
+activate toh
+toh --> toh : cleanup transferTimeout (TT)
+note right : TT innerJoin TSC\n where TSC.transferStateId in [...]
+activate toh
+autonumber 2.1
+toh -> clDb : delete from TT by ttIdList
+note right : table: TT (transferTimeout)
+deactivate toh
+
+autonumber 3
+toh -> clDb : get segmentId, intervalMin, intervalMax
+note right : tables:\n segment,\n TSC (transferStateChange)
+
+toh --> toh : update timeoutExpireReserved and get expiredTransfers
+activate toh
+autonumber 6.1
+toh -> clDb : Insert expirationDate into TT\n for transfers in [intervalMin, ... intervalMax]
+note right : table: TT
+toh -> clDb : Insert EXPIRED_PREPARED into TSC for RECEIVED_PREPARE state
+note right : table: TSC
+toh -> clDb : Insert RESERVED_TIMEOUT into TSC for RESERVED state
+note right : table: TSC
+toh -> clDb : Insert error info into transferError (TE)
+note right : table: TE
+toh -> clDb : get expired transfers details from TT
+note right : TT innerJoin other tables
+deactivate toh
+
+autonumber 7
+toh --> toh : for each expiredTransfer
+activate toh
+alt state === EXPIRED_PREPARED
+autonumber 7.1
+toh ->o topicNE : produce notification timeout-received message
+else state === RESERVED_TIMEOUT
+autonumber 7.1
+toh ->o topicTP : produce position timeout-reserved message
+end
+deactivate toh
+deactivate toh
+
+autonumber 8
+topicNE o-> nh : consume notification\n message
+activate nh
+nh -> payer : send notification\n callback to payer
+deactivate nh
+
+topicTP o-> ph : consume position timeout\n message
+activate ph
+ph --> ph : process position timeout
+ph ->o topicNE
+deactivate ph
+topicNE o-> nh : consume notification\n message
+activate nh
+nh -> payee : send notification\n callback to payee
+deactivate nh
+
+@enduml
diff --git a/documentation/sequence-diagrams/Handler - timeout.png b/documentation/sequence-diagrams/Handler - timeout.png
new file mode 100644
index 000000000..eb43611b4
Binary files /dev/null and b/documentation/sequence-diagrams/Handler - timeout.png differ
diff --git a/documentation/state-diagrams/transfer-ML-spec-states-diagram.png b/documentation/state-diagrams/transfer-ML-spec-states-diagram.png
new file mode 100644
index 000000000..2313c91cc
Binary files /dev/null and b/documentation/state-diagrams/transfer-ML-spec-states-diagram.png differ
diff --git a/documentation/state-diagrams/transfer-internal-states-diagram.png b/documentation/state-diagrams/transfer-internal-states-diagram.png
new file mode 100644
index 000000000..d2d7b3245
Binary files /dev/null and b/documentation/state-diagrams/transfer-internal-states-diagram.png differ
diff --git a/documentation/state-diagrams/transfer-internal-states.plantuml b/documentation/state-diagrams/transfer-internal-states.plantuml
new file mode 100644
index 000000000..5636e94d1
--- /dev/null
+++ b/documentation/state-diagrams/transfer-internal-states.plantuml
@@ -0,0 +1,74 @@
+@startuml
+
+state RECEIVED {
+ state RECEIVED_PREPARE {
+ }
+}
+
+state RESERVED_ {
+ state RESERVED {
+ }
+ state RESERVED_FORWARDED {
+ }
+ state RECEIVED_FULFIL {
+ }
+ state RECEIVED_FULFIL_DEPENDENT {
+ }
+ state RESERVED_TIMEOUT {
+ }
+ state RECEIVED_REJECT {
+ }
+ state RECEIVED_ERROR {
+ }
+}
+
+state COMMITTED {
+}
+
+state ABORTED {
+ state ABORTED_ERROR {
+ }
+ state ABORTED_REJECTED {
+ }
+ state EXPIRED_PREPARED {
+ }
+ state EXPIRED_RESERVED {
+ }
+ state FAILED {
+ }
+ state INVALID {
+ }
+}
+
+RECEIVED_FULFIL_DEPENDENT : only FX-transfer
+RECEIVED_FULFIL : only transfer
+
+[*] --> RECEIVED_PREPARE : Transfer Prepare Request [Prepare handler] \n (validation & dupl.check passed)
+[*] --> INVALID : Validation failed \n [Prepare handler]
+RECEIVED_PREPARE --> RESERVED : [Position handler]: Liquidity check passed, \n funds reserved
+RESERVED --> RECEIVED_REJECT : Reject callback from Payee with status "ABORTED"
+
+RECEIVED_FULFIL --> COMMITTED : Transfer committed [Position handler] \n (commit funds, assign T. to settlement window)
+RECEIVED_REJECT --> ABORTED_REJECTED : Transfer Aborted by Payee
+RECEIVED_ERROR --> ABORTED_ERROR : Hub aborts T.
+RECEIVED_PREPARE --> EXPIRED_PREPARED : Timeout handler \n detects T. being EXPIRED
+
+RESERVED --> RECEIVED_FULFIL : Fulfil callback from Payee \n with status "COMMITTED" \n [Fulfil handler]: \n fulfilment check passed
+RESERVED --> RECEIVED_ERROR : Fulfil callback from Payee fails validation\n [Fulfil handler]
+RESERVED --> RECEIVED_FULFIL_DEPENDENT : Recieved FX transfer fulfilment
+RESERVED --> RESERVED_FORWARDED : A Proxy participant has acknowledged the transfer to be forwarded
+RESERVED --> RESERVED_TIMEOUT : Timeout handler
+
+RESERVED_FORWARDED --> RECEIVED_FULFIL : Fulfil callback from Payee \n with status "COMMITTED" \n [Fulfil handler]: \n fulfilment check passed
+RESERVED_FORWARDED --> RECEIVED_ERROR : Fulfil callback from Payee fails validation\n [Fulfil handler]
+RESERVED_FORWARDED --> RECEIVED_FULFIL_DEPENDENT : Recieved FX transfer fulfilment
+
+RECEIVED_FULFIL_DEPENDENT --> COMMITTED : Dependant transfer committed [Position handler] \n (commit funds, assign T. to settlement window)
+RECEIVED_FULFIL_DEPENDENT --> RESERVED_TIMEOUT : Dependant transfer is timed out
+
+RESERVED_TIMEOUT --> EXPIRED_RESERVED : Hub aborts T. due to being EXPIRED
+
+COMMITTED --> [*]
+ABORTED --> [*]
+
+@enduml
diff --git a/documentation/state-diagrams/transfer-states.plantuml b/documentation/state-diagrams/transfer-states.plantuml
new file mode 100644
index 000000000..d945d1506
--- /dev/null
+++ b/documentation/state-diagrams/transfer-states.plantuml
@@ -0,0 +1,13 @@
+@startuml
+hide empty description
+
+[*] --> RECEIVED : Transfer Prepare Request
+RECEIVED --> RESERVED : Net debit cap limit check passed
+RECEIVED --> ABORTED : Failed validation OR timeout
+RESERVED --> ABORTED : Abort response from Payee
+RESERVED --> COMMITTED : Fulfil Response from Payee
+
+COMMITTED --> [*]
+ABORTED --> [*]
+
+@enduml
diff --git a/migrations/310204_transferParticipant-participantId.js b/migrations/310204_transferParticipant-participantId.js
new file mode 100644
index 000000000..fee87e99f
--- /dev/null
+++ b/migrations/310204_transferParticipant-participantId.js
@@ -0,0 +1,52 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijaya Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('transferParticipant').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('transferParticipant', (t) => {
+ t.integer('participantId').unsigned().notNullable()
+ // Disabling this as its throwing error while running the migration with existing data in the table
+ // t.foreign('participantId').references('participantId').inTable('participant')
+ t.index('participantId')
+ t.integer('participantCurrencyId').unsigned().nullable().alter()
+ })
+ }
+ })
+}
+
+exports.down = async (knex) => {
+ return await knex.schema.hasTable('transferParticipant').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('transferParticipant', (t) => {
+ t.dropIndex('participantId')
+ t.dropColumn('participantId')
+ t.integer('participantCurrencyId').unsigned().notNullable().alter()
+ })
+ }
+ })
+}
diff --git a/migrations/310403_participantPositionChange-participantCurrencyId.js b/migrations/310403_participantPositionChange-participantCurrencyId.js
new file mode 100644
index 000000000..e25a9ffd1
--- /dev/null
+++ b/migrations/310403_participantPositionChange-participantCurrencyId.js
@@ -0,0 +1,47 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * ModusBox
+ - Vijaya Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('participantPositionChange').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('participantPositionChange', (t) => {
+ t.integer('participantCurrencyId').unsigned().notNullable()
+ t.foreign('participantCurrencyId').references('participantCurrencyId').inTable('participantCurrency')
+ })
+ }
+ })
+}
+
+exports.down = async (knex) => {
+ return await knex.schema.hasTable('participantPositionChange').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('participantPositionChange', (t) => {
+ t.dropColumn('participantCurrencyId')
+ })
+ }
+ })
+}
diff --git a/migrations/310404_participantPositionChange-change.js b/migrations/310404_participantPositionChange-change.js
new file mode 100644
index 000000000..81632f9e3
--- /dev/null
+++ b/migrations/310404_participantPositionChange-change.js
@@ -0,0 +1,46 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * ModusBox
+ - Vijaya Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('participantPositionChange').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('participantPositionChange', (t) => {
+ t.decimal('change', 18, 2).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = async (knex) => {
+ return await knex.schema.hasTable('participantPositionChange').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('participantPositionChange', (t) => {
+ t.dropColumn('change')
+ })
+ }
+ })
+}
diff --git a/migrations/600010_fxTransferType.js b/migrations/600010_fxTransferType.js
new file mode 100644
index 000000000..767667df9
--- /dev/null
+++ b/migrations/600010_fxTransferType.js
@@ -0,0 +1,43 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferType').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferType', (t) => {
+ t.increments('fxTransferTypeId').primary().notNullable()
+ t.string('name', 50).notNullable()
+ t.string('description', 512).defaultTo(null).nullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxParticipantCurrencyType')
+}
diff --git a/migrations/600011_fxTransferType-indexes.js b/migrations/600011_fxTransferType-indexes.js
new file mode 100644
index 000000000..9d7cbabab
--- /dev/null
+++ b/migrations/600011_fxTransferType-indexes.js
@@ -0,0 +1,38 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransferType', (t) => {
+ t.unique('name')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransferType', (t) => {
+ t.dropUnique('name')
+ })
+}
diff --git a/migrations/600012_fxParticipantCurrencyType.js b/migrations/600012_fxParticipantCurrencyType.js
new file mode 100644
index 000000000..1efd6bf52
--- /dev/null
+++ b/migrations/600012_fxParticipantCurrencyType.js
@@ -0,0 +1,43 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxParticipantCurrencyType').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxParticipantCurrencyType', (t) => {
+ t.increments('fxParticipantCurrencyTypeId').primary().notNullable()
+ t.string('name', 50).notNullable()
+ t.string('description', 512).defaultTo(null).nullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxParticipantCurrencyType')
+}
diff --git a/migrations/600013_fxParticipantCurrencyType-indexes.js b/migrations/600013_fxParticipantCurrencyType-indexes.js
new file mode 100644
index 000000000..c77743674
--- /dev/null
+++ b/migrations/600013_fxParticipantCurrencyType-indexes.js
@@ -0,0 +1,38 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxParticipantCurrencyType', (t) => {
+ t.unique('name')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxParticipantCurrencyType', (t) => {
+ t.dropUnique('name')
+ })
+}
diff --git a/migrations/600100_fxTransferDuplicateCheck.js b/migrations/600100_fxTransferDuplicateCheck.js
new file mode 100644
index 000000000..e7260830a
--- /dev/null
+++ b/migrations/600100_fxTransferDuplicateCheck.js
@@ -0,0 +1,42 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+ 'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferDuplicateCheck').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferDuplicateCheck', (t) => {
+ t.string('commitRequestId', 36).primary().notNullable()
+ t.string('hash', 256).notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferDuplicateCheck')
+}
diff --git a/migrations/600110_fxTransferErrorDuplicateCheck.js.js b/migrations/600110_fxTransferErrorDuplicateCheck.js.js
new file mode 100644
index 000000000..2906a1d5a
--- /dev/null
+++ b/migrations/600110_fxTransferErrorDuplicateCheck.js.js
@@ -0,0 +1,17 @@
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferErrorDuplicateCheck').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferErrorDuplicateCheck', (t) => {
+ t.string('commitRequestId', 36).primary().notNullable()
+ t.string('hash', 256).notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferErrorDuplicateCheck')
+}
diff --git a/migrations/600200_fxTransfer.js b/migrations/600200_fxTransfer.js
new file mode 100644
index 000000000..161b4e27b
--- /dev/null
+++ b/migrations/600200_fxTransfer.js
@@ -0,0 +1,51 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+ 'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransfer').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransfer', (t) => {
+ t.string('commitRequestId', 36).primary().notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransferDuplicateCheck')
+ t.string('determiningTransferId', 36).defaultTo(null).nullable()
+ t.decimal('sourceAmount', 18, 4).notNullable()
+ t.decimal('targetAmount', 18, 4).notNullable()
+ t.string('sourceCurrency', 3).notNullable()
+ t.foreign('sourceCurrency').references('currencyId').inTable('currency')
+ t.string('targetCurrency', 3).notNullable()
+ t.foreign('targetCurrency').references('currencyId').inTable('currency')
+ t.string('ilpCondition', 256).notNullable()
+ t.dateTime('expirationDate').notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransfer')
+}
diff --git a/migrations/600201_fxTransfer-indexes.js b/migrations/600201_fxTransfer-indexes.js
new file mode 100644
index 000000000..541c8fb02
--- /dev/null
+++ b/migrations/600201_fxTransfer-indexes.js
@@ -0,0 +1,40 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransfer', (t) => {
+ t.index('sourceCurrency')
+ t.index('targetCurrency')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransfer', (t) => {
+ t.dropIndex('sourceCurrency')
+ t.dropIndex('targetCurrency')
+ })
+}
diff --git a/migrations/600400_fxTransferStateChange.js b/migrations/600400_fxTransferStateChange.js
new file mode 100644
index 000000000..bd028ab5e
--- /dev/null
+++ b/migrations/600400_fxTransferStateChange.js
@@ -0,0 +1,46 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferStateChange').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferStateChange', (t) => {
+ t.bigIncrements('fxTransferStateChangeId').primary().notNullable()
+ t.string('commitRequestId', 36).notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransfer')
+ t.string('transferStateId', 50).notNullable()
+ t.foreign('transferStateId').references('transferStateId').inTable('transferState')
+ t.string('reason', 512).defaultTo(null).nullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferStateChange')
+}
diff --git a/migrations/600401_fxTransferStateChange-indexes.js b/migrations/600401_fxTransferStateChange-indexes.js
new file mode 100644
index 000000000..03ffdb66f
--- /dev/null
+++ b/migrations/600401_fxTransferStateChange-indexes.js
@@ -0,0 +1,40 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransferStateChange', (t) => {
+ t.index('commitRequestId')
+ t.index('transferStateId')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransferStateChange', (t) => {
+ t.dropIndex('commitRequestId')
+ t.dropIndex('transferStateId')
+ })
+}
diff --git a/migrations/600501_fxWatchList.js b/migrations/600501_fxWatchList.js
new file mode 100644
index 000000000..167d32628
--- /dev/null
+++ b/migrations/600501_fxWatchList.js
@@ -0,0 +1,46 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+ 'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxWatchList').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxWatchList', (t) => {
+ t.bigIncrements('fxWatchListId').primary().notNullable()
+ t.string('commitRequestId', 36).notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransfer')
+ t.string('determiningTransferId', 36).notNullable()
+ t.integer('fxTransferTypeId').unsigned().notNullable()
+ t.foreign('fxTransferTypeId').references('fxTransferTypeId').inTable('fxTransferType')
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxWatchList')
+}
diff --git a/migrations/600502_fxWatchList-indexes.js b/migrations/600502_fxWatchList-indexes.js
new file mode 100644
index 000000000..84bbf5a22
--- /dev/null
+++ b/migrations/600502_fxWatchList-indexes.js
@@ -0,0 +1,40 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxWatchList', (t) => {
+ t.index('commitRequestId')
+ t.index('determiningTransferId')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxWatchList', (t) => {
+ t.dropIndex('commitRequestId')
+ t.dropIndex('determiningTransferId')
+ })
+}
diff --git a/migrations/600600_fxTransferFulfilmentDuplicateCheck.js b/migrations/600600_fxTransferFulfilmentDuplicateCheck.js
new file mode 100644
index 000000000..c907eca28
--- /dev/null
+++ b/migrations/600600_fxTransferFulfilmentDuplicateCheck.js
@@ -0,0 +1,43 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferFulfilmentDuplicateCheck').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferFulfilmentDuplicateCheck', (t) => {
+ t.string('commitRequestId', 36).primary().notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransfer')
+ t.string('hash', 256).nullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferFulfilmentDuplicateCheck')
+}
diff --git a/migrations/600601_fxTransferFulfilmentDuplicateCheck-indexes.js b/migrations/600601_fxTransferFulfilmentDuplicateCheck-indexes.js
new file mode 100644
index 000000000..dc265fd63
--- /dev/null
+++ b/migrations/600601_fxTransferFulfilmentDuplicateCheck-indexes.js
@@ -0,0 +1,38 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransferFulfilmentDuplicateCheck', (t) => {
+ t.index('commitRequestId')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransferFulfilmentDuplicateCheck', (t) => {
+ t.dropIndex('commitRequestId')
+ })
+}
diff --git a/migrations/600700_fxTransferFulfilment.js b/migrations/600700_fxTransferFulfilment.js
new file mode 100644
index 000000000..d20b680c6
--- /dev/null
+++ b/migrations/600700_fxTransferFulfilment.js
@@ -0,0 +1,47 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferFulfilment').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferFulfilment', (t) => {
+ t.string('commitRequestId', 36).primary().notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransfer')
+ t.string('ilpFulfilment', 256).nullable()
+ t.dateTime('completedDate').notNullable()
+ t.boolean('isValid').nullable()
+ t.bigInteger('settlementWindowId').unsigned().nullable()
+ t.foreign('settlementWindowId').references('settlementWindowId').inTable('settlementWindow')
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferFulfilment')
+}
diff --git a/migrations/600701_fxTransferFulfilment-indexes.js b/migrations/600701_fxTransferFulfilment-indexes.js
new file mode 100644
index 000000000..e32b93de9
--- /dev/null
+++ b/migrations/600701_fxTransferFulfilment-indexes.js
@@ -0,0 +1,42 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransferFulfilment', (t) => {
+ t.index('commitRequestId')
+ t.index('settlementWindowId')
+ t.unique(['commitRequestId', 'ilpFulfilment'])
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransferFulfilment', (t) => {
+ t.dropIndex('transferId')
+ t.dropIndex('settlementWindowId')
+ t.unique(['transferId', 'ilpFulfilment'])
+ })
+}
diff --git a/migrations/600800_fxTransferExtension.js b/migrations/600800_fxTransferExtension.js
new file mode 100644
index 000000000..2bb0845cb
--- /dev/null
+++ b/migrations/600800_fxTransferExtension.js
@@ -0,0 +1,47 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Infitx
+ - Kalin Krustev
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferExtension').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferExtension', (t) => {
+ t.bigIncrements('fxTransferExtensionId').primary().notNullable()
+ t.string('commitRequestId', 36).notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransfer')
+ t.boolean('isFulfilment').defaultTo(false).notNullable()
+ t.boolean('isError').defaultTo(false).notNullable()
+ t.string('key', 128).notNullable()
+ t.text('value').notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferExtension')
+}
diff --git a/migrations/601400_fxTransferTimeout.js b/migrations/601400_fxTransferTimeout.js
new file mode 100644
index 000000000..90bc01ac5
--- /dev/null
+++ b/migrations/601400_fxTransferTimeout.js
@@ -0,0 +1,43 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ - Eugen Klymniuk
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferTimeout').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferTimeout', (t) => {
+ t.bigIncrements('fxTransferTimeoutId').primary().notNullable()
+ t.string('commitRequestId', 36).notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransfer')
+ t.dateTime('expirationDate').notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferTimeout')
+}
diff --git a/migrations/601401_fxTransferTimeout-indexes.js b/migrations/601401_fxTransferTimeout-indexes.js
new file mode 100644
index 000000000..6a85c66d2
--- /dev/null
+++ b/migrations/601401_fxTransferTimeout-indexes.js
@@ -0,0 +1,37 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ - Eugen Klymniuk
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransferTimeout', (t) => {
+ t.unique('commitRequestId')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransferTimeout', (t) => {
+ t.dropUnique('commitRequestId')
+ })
+}
diff --git a/migrations/601500_fxTransferError.js b/migrations/601500_fxTransferError.js
new file mode 100644
index 000000000..ce53eaef6
--- /dev/null
+++ b/migrations/601500_fxTransferError.js
@@ -0,0 +1,44 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ - Eugen Klymniuk
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferError').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferError', (t) => {
+ t.string('commitRequestId', 36).primary().notNullable()
+ t.bigInteger('fxTransferStateChangeId').unsigned().notNullable()
+ t.foreign('fxTransferStateChangeId').references('fxTransferStateChangeId').inTable('fxTransferStateChange')
+ t.integer('errorCode').unsigned().notNullable()
+ t.string('errorDescription', 128).notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferError')
+}
diff --git a/migrations/601501_fxTransferError-indexes.js b/migrations/601501_fxTransferError-indexes.js
new file mode 100644
index 000000000..a63f278f9
--- /dev/null
+++ b/migrations/601501_fxTransferError-indexes.js
@@ -0,0 +1,37 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ - Eugen Klymniuk
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransferError', (t) => {
+ t.index('fxTransferStateChangeId')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransferError', (t) => {
+ t.dropIndex('fxTransferStateChangeId')
+ })
+}
diff --git a/migrations/610200_fxTransferParticipant.js b/migrations/610200_fxTransferParticipant.js
new file mode 100644
index 000000000..40b15f4ad
--- /dev/null
+++ b/migrations/610200_fxTransferParticipant.js
@@ -0,0 +1,52 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferParticipant').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('fxTransferParticipant', (t) => {
+ t.bigIncrements('fxTransferParticipantId').primary().notNullable()
+ t.string('commitRequestId', 36).notNullable()
+ t.foreign('commitRequestId').references('commitRequestId').inTable('fxTransfer')
+ t.integer('participantCurrencyId').unsigned().notNullable()
+ t.foreign('participantCurrencyId').references('participantCurrencyId').inTable('participantCurrency')
+ t.integer('transferParticipantRoleTypeId').unsigned().notNullable()
+ t.foreign('transferParticipantRoleTypeId').references('transferParticipantRoleTypeId').inTable('transferParticipantRoleType')
+ t.integer('ledgerEntryTypeId').unsigned().notNullable()
+ t.foreign('ledgerEntryTypeId').references('ledgerEntryTypeId').inTable('ledgerEntryType')
+ t.integer('fxParticipantCurrencyTypeId').unsigned()
+ t.foreign('fxParticipantCurrencyTypeId').references('fxParticipantCurrencyTypeId').inTable('fxParticipantCurrencyType')
+ t.decimal('amount', 18, 4).notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.dropTableIfExists('fxTransferParticipant')
+}
diff --git a/migrations/610201_fxTransferParticipant-indexes.js b/migrations/610201_fxTransferParticipant-indexes.js
new file mode 100644
index 000000000..3f413afff
--- /dev/null
+++ b/migrations/610201_fxTransferParticipant-indexes.js
@@ -0,0 +1,44 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = function (knex) {
+ return knex.schema.table('fxTransferParticipant', (t) => {
+ t.index('commitRequestId')
+ t.index('participantCurrencyId')
+ t.index('transferParticipantRoleTypeId')
+ t.index('ledgerEntryTypeId')
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.table('fxTransferParticipant', (t) => {
+ t.dropIndex('commitRequestId')
+ t.dropIndex('participantCurrencyId')
+ t.dropIndex('transferParticipantRoleTypeId')
+ t.dropIndex('ledgerEntryTypeId')
+ })
+}
diff --git a/migrations/610202_fxTransferParticipant-participantId.js b/migrations/610202_fxTransferParticipant-participantId.js
new file mode 100644
index 000000000..15000ac7e
--- /dev/null
+++ b/migrations/610202_fxTransferParticipant-participantId.js
@@ -0,0 +1,52 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('fxTransferParticipant').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('fxTransferParticipant', (t) => {
+ t.integer('participantId').unsigned().notNullable()
+ // Disabling this as its throwing error while running the migration with existing data in the table
+ // t.foreign('participantId').references('participantId').inTable('participant')
+ t.index('participantId')
+ t.integer('participantCurrencyId').unsigned().nullable().alter()
+ })
+ }
+ })
+}
+
+exports.down = async (knex) => {
+ return await knex.schema.hasTable('fxTransferParticipant').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('fxTransferParticipant', (t) => {
+ t.dropIndex('participantId')
+ t.dropColumn('participantId')
+ t.integer('participantCurrencyId').unsigned().notNullable().alter()
+ })
+ }
+ })
+}
diff --git a/migrations/610403_participantPositionChange-fxTransfer.js b/migrations/610403_participantPositionChange-fxTransfer.js
new file mode 100644
index 000000000..bdf853c96
--- /dev/null
+++ b/migrations/610403_participantPositionChange-fxTransfer.js
@@ -0,0 +1,46 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * INFITX
+ - Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('participantPositionChange').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('participantPositionChange', (t) => {
+ t.bigInteger('transferStateChangeId').unsigned().defaultTo(null).alter()
+ t.bigInteger('fxTransferStateChangeId').unsigned().defaultTo(null)
+ t.foreign('fxTransferStateChangeId').references('fxTransferStateChangeId').inTable('fxTransferStateChange')
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.alterTable('participantPositionChange', (t) => {
+ t.dropForeign('fxTransferStateChangeId')
+ t.dropColumn('fxTransferStateChangeId')
+ t.bigInteger('transferStateChangeId').unsigned().notNullable().alter()
+ })
+}
diff --git a/migrations/800101_feature-fixSubIdRef.js b/migrations/800101_feature-fixSubIdRef.js
index 3a0f410df..085b6ae71 100644
--- a/migrations/800101_feature-fixSubIdRef.js
+++ b/migrations/800101_feature-fixSubIdRef.js
@@ -24,8 +24,8 @@ Contributors
* Gates Foundation
- Name Surname
- * ModusBox
- - Vijay Kumar Guthi
+ * Infitx
+ - Vijay Kumar Guthi
--------------
******/
diff --git a/migrations/910101_feature904DataMigration.js b/migrations/910101_feature904DataMigration.js
index e798759e1..6d3c1ffbd 100644
--- a/migrations/910101_feature904DataMigration.js
+++ b/migrations/910101_feature904DataMigration.js
@@ -44,62 +44,56 @@ const tableNameSuffix = Time.getYMDString(new Date())
*/
const migrateData = async (knex) => {
return knex.transaction(async trx => {
- try {
- let exists = false
- exists = await knex.schema.hasTable(`transferExtension${tableNameSuffix}`)
- if (exists) {
- await knex.transacting(trx).raw(`
- insert into transferExtension (transferExtensionId, transferId, \`key\`, \`value\`, isFulfilment, isError, createdDate)
- select te.transferExtensionId, te.transferId, te.\`key\`, te.\`value\`,
- case when te.transferFulfilmentId is null then 0 else 1 end,
- case when te.transferErrorId is null then 0 else 1 end,
- te.createdDate
- from transferExtension${tableNameSuffix} as te`)
- }
- exists = await knex.schema.hasTable(`transferFulfilmentDuplicateCheck${tableNameSuffix}`) &&
- await knex.schema.hasTable(`transferFulfilment${tableNameSuffix}`)
- if (exists) {
- await knex.transacting(trx).raw(`
- insert into transferFulfilmentDuplicateCheck (transferId, \`hash\`, createdDate)
- select transferId, \`hash\`, createdDate from transferFulfilmentDuplicateCheck${tableNameSuffix}
- where transferFulfilmentId in(
- select transferFulfilmentId
- from (
- select transferFulfilmentId, transferId, ilpFulfilment, completedDate, isValid, settlementWindowId, createdDate,
- row_number() over(partition by transferId order by isValid desc, createdDate) rowNumber
- from transferFulfilment${tableNameSuffix}) t
- where t.rowNumber = 1)`)
- }
- exists = await knex.schema.hasTable(`transferFulfilment${tableNameSuffix}`)
- if (exists) {
- await knex.transacting(trx).raw(`
- insert into transferFulfilment (transferId, ilpFulfilment, completedDate, isValid, settlementWindowId, createdDate)
- select t.transferId, t.ilpFulfilment, t.completedDate, t.isValid, t.settlementWindowId, t.createdDate
+ let exists = false
+ exists = await knex.schema.hasTable(`transferExtension${tableNameSuffix}`)
+ if (exists) {
+ await knex.transacting(trx).raw(`
+ insert into transferExtension (transferExtensionId, transferId, \`key\`, \`value\`, isFulfilment, isError, createdDate)
+ select te.transferExtensionId, te.transferId, te.\`key\`, te.\`value\`,
+ case when te.transferFulfilmentId is null then 0 else 1 end,
+ case when te.transferErrorId is null then 0 else 1 end,
+ te.createdDate
+ from transferExtension${tableNameSuffix} as te`)
+ }
+ exists = await knex.schema.hasTable(`transferFulfilmentDuplicateCheck${tableNameSuffix}`) &&
+ await knex.schema.hasTable(`transferFulfilment${tableNameSuffix}`)
+ if (exists) {
+ await knex.transacting(trx).raw(`
+ insert into transferFulfilmentDuplicateCheck (transferId, \`hash\`, createdDate)
+ select transferId, \`hash\`, createdDate from transferFulfilmentDuplicateCheck${tableNameSuffix}
+ where transferFulfilmentId in(
+ select transferFulfilmentId
from (
select transferFulfilmentId, transferId, ilpFulfilment, completedDate, isValid, settlementWindowId, createdDate,
row_number() over(partition by transferId order by isValid desc, createdDate) rowNumber
from transferFulfilment${tableNameSuffix}) t
- where t.rowNumber = 1`)
- }
- exists = await knex.schema.hasTable(`transferErrorDuplicateCheck${tableNameSuffix}`)
- if (exists) {
- await knex.transacting(trx).raw(`
- insert into transferErrorDuplicateCheck (transferId, \`hash\`, createdDate)
- select transferId, \`hash\`, createdDate
- from transferErrorDuplicateCheck${tableNameSuffix}`)
- }
- exists = await knex.schema.hasTable(`transferError${tableNameSuffix}`)
- if (exists) {
- await knex.transacting(trx).raw(`
- insert into transferError (transferId, transferStateChangeId, errorCode, errorDescription, createdDate)
- select tsc.transferId, te.transferStateChangeId, te.errorCode, te.errorDescription, te.createdDate
- from transferError${tableNameSuffix} te
- join transferStateChange tsc on tsc.transferStateChangeId = te.transferStateChangeId`)
- }
- await trx.commit
- } catch (err) {
- await trx.rollback
- throw err
+ where t.rowNumber = 1)`)
+ }
+ exists = await knex.schema.hasTable(`transferFulfilment${tableNameSuffix}`)
+ if (exists) {
+ await knex.transacting(trx).raw(`
+ insert into transferFulfilment (transferId, ilpFulfilment, completedDate, isValid, settlementWindowId, createdDate)
+ select t.transferId, t.ilpFulfilment, t.completedDate, t.isValid, t.settlementWindowId, t.createdDate
+ from (
+ select transferFulfilmentId, transferId, ilpFulfilment, completedDate, isValid, settlementWindowId, createdDate,
+ row_number() over(partition by transferId order by isValid desc, createdDate) rowNumber
+ from transferFulfilment${tableNameSuffix}) t
+ where t.rowNumber = 1`)
+ }
+ exists = await knex.schema.hasTable(`transferErrorDuplicateCheck${tableNameSuffix}`)
+ if (exists) {
+ await knex.transacting(trx).raw(`
+ insert into transferErrorDuplicateCheck (transferId, \`hash\`, createdDate)
+ select transferId, \`hash\`, createdDate
+ from transferErrorDuplicateCheck${tableNameSuffix}`)
+ }
+ exists = await knex.schema.hasTable(`transferError${tableNameSuffix}`)
+ if (exists) {
+ await knex.transacting(trx).raw(`
+ insert into transferError (transferId, transferStateChangeId, errorCode, errorDescription, createdDate)
+ select tsc.transferId, te.transferStateChangeId, te.errorCode, te.errorDescription, te.createdDate
+ from transferError${tableNameSuffix} te
+ join transferStateChange tsc on tsc.transferStateChangeId = te.transferStateChangeId`)
}
})
}
diff --git a/migrations/910102_feature949DataMigration.js b/migrations/910102_feature949DataMigration.js
index 30bc7dee4..2bcb7e0f6 100644
--- a/migrations/910102_feature949DataMigration.js
+++ b/migrations/910102_feature949DataMigration.js
@@ -41,232 +41,226 @@ const RUN_DATA_MIGRATIONS = Config.DB_RUN_DATA_MIGRATIONS
*/
const migrateData = async (knex) => {
return knex.transaction(async trx => {
- try {
- await knex.raw('update currency set scale = \'2\' where currencyId = \'AED\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'AFA\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'AFN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ALL\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'AMD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ANG\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'AOA\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'AOR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ARS\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'AUD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'AWG\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'AZN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BAM\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BBD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BDT\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BGN\'').transacting(trx)
- await knex.raw('update currency set scale = \'3\' where currencyId = \'BHD\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'BIF\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BMD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BND\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BOB\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BRL\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BSD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BTN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BWP\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'BYN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'BZD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CAD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CDF\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CHF\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'CLP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CNY\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'COP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CRC\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CUC\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CUP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CVE\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'CZK\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'DJF\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'DKK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'DOP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'DZD\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'EEK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'EGP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ERN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ETB\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'EUR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'FJD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'FKP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'GBP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'GEL\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'GGP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'GHS\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'GIP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'GMD\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'GNF\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'GTQ\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'GYD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'HKD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'HNL\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'HRK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'HTG\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'HUF\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'IDR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ILS\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'IMP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'INR\'').transacting(trx)
- await knex.raw('update currency set scale = \'3\' where currencyId = \'IQD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'IRR\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'ISK\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'JEP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'JMD\'').transacting(trx)
- await knex.raw('update currency set scale = \'3\' where currencyId = \'JOD\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'JPY\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'KES\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'KGS\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'KHR\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'KMF\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'KPW\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'KRW\'').transacting(trx)
- await knex.raw('update currency set scale = \'3\' where currencyId = \'KWD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'KYD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'KZT\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'LAK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'LBP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'LKR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'LRD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'LSL\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'LTL\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'LVL\'').transacting(trx)
- await knex.raw('update currency set scale = \'3\' where currencyId = \'LYD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MAD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MDL\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MGA\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MKD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MMK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MNT\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MOP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MRO\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MUR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MVR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MWK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MXN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MYR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'MZN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'NAD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'NGN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'NIO\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'NOK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'NPR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'NZD\'').transacting(trx)
- await knex.raw('update currency set scale = \'3\' where currencyId = \'OMR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'PAB\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'PEN\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'PGK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'PHP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'PKR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'PLN\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'PYG\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'QAR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'RON\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'RSD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'RUB\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'RWF\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SAR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SBD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SCR\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SDG\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SEK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SGD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SHP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SLL\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SOS\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'SPL\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SRD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'STD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SVC\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SYP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'SZL\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'THB\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'TJS\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'TMT\'').transacting(trx)
- await knex.raw('update currency set scale = \'3\' where currencyId = \'TND\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'TOP\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'TRY\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'TTD\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'TVD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'TWD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'TZS\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'UAH\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'UGX\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'USD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'UYU\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'UZS\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'VEF\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'VND\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'VUV\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'WST\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'XAF\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'XAG\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'XAU\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'XCD\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'XDR\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'XFO\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'XFU\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'XOF\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'XPD\'').transacting(trx)
- await knex.raw('update currency set scale = \'0\' where currencyId = \'XPF\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'XPT\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'YER\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ZAR\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'ZMK\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ZMW\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'ZWD\'').transacting(trx)
- await knex.raw('update currency set scale = \'2\' where currencyId = \'ZWL\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'ZWN\'').transacting(trx)
- await knex.raw('update currency set scale = \'4\' where currencyId = \'ZWR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'AED\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'AFA\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'AFN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ALL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'AMD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ANG\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'AOA\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'AOR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ARS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'AUD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'AWG\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'AZN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BAM\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BBD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BDT\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BGN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'3\' where currencyId = \'BHD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'BIF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BMD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BND\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BOB\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BRL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BSD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BTN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BWP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'BYN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'BZD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CAD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CDF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CHF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'CLP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CNY\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'COP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CRC\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CUC\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CUP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CVE\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'CZK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'DJF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'DKK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'DOP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'DZD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'EEK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'EGP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ERN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ETB\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'EUR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'FJD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'FKP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'GBP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'GEL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'GGP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'GHS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'GIP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'GMD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'GNF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'GTQ\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'GYD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'HKD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'HNL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'HRK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'HTG\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'HUF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'IDR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ILS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'IMP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'INR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'3\' where currencyId = \'IQD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'IRR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'ISK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'JEP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'JMD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'3\' where currencyId = \'JOD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'JPY\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'KES\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'KGS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'KHR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'KMF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'KPW\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'KRW\'').transacting(trx)
+ await knex.raw('update currency set scale = \'3\' where currencyId = \'KWD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'KYD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'KZT\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'LAK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'LBP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'LKR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'LRD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'LSL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'LTL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'LVL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'3\' where currencyId = \'LYD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MAD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MDL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MGA\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MKD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MMK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MNT\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MOP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MRO\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MUR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MVR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MWK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MXN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MYR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'MZN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'NAD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'NGN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'NIO\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'NOK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'NPR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'NZD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'3\' where currencyId = \'OMR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'PAB\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'PEN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'PGK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'PHP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'PKR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'PLN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'PYG\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'QAR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'RON\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'RSD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'RUB\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'RWF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SAR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SBD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SCR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SDG\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SEK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SGD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SHP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SLL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SOS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'SPL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SRD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'STD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SVC\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SYP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'SZL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'THB\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'TJS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'TMT\'').transacting(trx)
+ await knex.raw('update currency set scale = \'3\' where currencyId = \'TND\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'TOP\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'TRY\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'TTD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'TVD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'TWD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'TZS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'UAH\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'UGX\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'USD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'UYU\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'UZS\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'VEF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'VND\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'VUV\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'WST\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'XAF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'XAG\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'XAU\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'XCD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'XDR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'XFO\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'XFU\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'XOF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'XPD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'0\' where currencyId = \'XPF\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'XPT\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'YER\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ZAR\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'ZMK\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ZMW\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'ZWD\'').transacting(trx)
+ await knex.raw('update currency set scale = \'2\' where currencyId = \'ZWL\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'ZWN\'').transacting(trx)
+ await knex.raw('update currency set scale = \'4\' where currencyId = \'ZWR\'').transacting(trx)
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'BOV\', \'Bolivia Mvdol\', 2)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'BOV\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'BYR\', \'Belarussian Ruble\', 0)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'0\' where currencyId = \'BYR\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'CHE\', \'Switzerland WIR Euro\', 2)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'CHE\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'CHW\', \'Switzerland WIR Franc\', 2)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'CHW\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'CLF\', \'Unidad de Fomento\', 4)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'CLF\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'COU\', \'Unidad de Valor Real\', 2)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'COU\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'MXV\', \'Mexican Unidad de Inversion (UDI)\', 2)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'MXV\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'SSP\', \'South Sudanese Pound\', 2)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'SSP\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'USN\', \'US Dollar (Next day)\', 2)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'USN\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'UYI\', \'Uruguay Peso en Unidades Indexadas (URUIURUI)\', 0)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'0\' where currencyId = \'UYI\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'XSU\', \'Sucre\', 4)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XSU\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'XTS\', \'Reserved for testing purposes\', 4)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XTS\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'XUA\', \'African Development Bank (ADB) Unit of Account\', 4)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XUA\'').transacting(trx) }
- try {
- await knex.raw('insert into currency (currencyId, name, scale) values (\'XXX\', \'Assigned for transactions where no currency is involved\', 4)').transacting(trx)
- } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XXX\'').transacting(trx) }
- await trx.commit
- } catch (err) {
- await trx.rollback
- throw err
- }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'BOV\', \'Bolivia Mvdol\', 2)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'BOV\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'BYR\', \'Belarussian Ruble\', 0)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'0\' where currencyId = \'BYR\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'CHE\', \'Switzerland WIR Euro\', 2)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'CHE\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'CHW\', \'Switzerland WIR Franc\', 2)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'CHW\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'CLF\', \'Unidad de Fomento\', 4)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'CLF\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'COU\', \'Unidad de Valor Real\', 2)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'COU\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'MXV\', \'Mexican Unidad de Inversion (UDI)\', 2)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'MXV\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'SSP\', \'South Sudanese Pound\', 2)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'SSP\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'USN\', \'US Dollar (Next day)\', 2)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'2\' where currencyId = \'USN\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'UYI\', \'Uruguay Peso en Unidades Indexadas (URUIURUI)\', 0)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'0\' where currencyId = \'UYI\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'XSU\', \'Sucre\', 4)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XSU\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'XTS\', \'Reserved for testing purposes\', 4)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XTS\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'XUA\', \'African Development Bank (ADB) Unit of Account\', 4)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XUA\'').transacting(trx) }
+ try {
+ await knex.raw('insert into currency (currencyId, name, scale) values (\'XXX\', \'Assigned for transactions where no currency is involved\', 4)').transacting(trx)
+ } catch (e) { await knex.raw('update currency set scale = \'4\' where currencyId = \'XXX\'').transacting(trx) }
})
}
diff --git a/migrations/950103_dropTransferParticipantStateChange.js b/migrations/950103_dropTransferParticipantStateChange.js
index 1956566ef..2cdfab6b7 100644
--- a/migrations/950103_dropTransferParticipantStateChange.js
+++ b/migrations/950103_dropTransferParticipantStateChange.js
@@ -19,7 +19,7 @@
- Name Surname
* ModusBox
- - Deon Botha
+ - Deon Botha
--------------
******/
diff --git a/migrations/950104_settlementModel-settlementAccountTypeId.js b/migrations/950104_settlementModel-settlementAccountTypeId.js
index d3ec68abd..99a5393c7 100644
--- a/migrations/950104_settlementModel-settlementAccountTypeId.js
+++ b/migrations/950104_settlementModel-settlementAccountTypeId.js
@@ -41,27 +41,22 @@ exports.up = async (knex) => {
t.integer('settlementAccountTypeId').unsigned().defaultTo(null)
})
await knex.transaction(async (trx) => {
- try {
- await knex.select('s.settlementModelId', 's.name', 'lat.name AS latName')
- .from('settlementModel AS s')
- .transacting(trx)
- .innerJoin('ledgerAccountType as lat', 's.ledgerAccountTypeId', 'lat.ledgerAccountTypeId')
- .then(async (models) => {
- for (const model of models) {
- let settlementAccountName
- if (model.latName === 'POSITION') {
- settlementAccountName = 'SETTLEMENT'
- } else {
- settlementAccountName = model.latName + '_SETTLEMENT'
- }
- await knex('settlementModel').transacting(trx).update({ settlementAccountTypeId: knex('ledgerAccountType').select('ledgerAccountTypeId').where('name', settlementAccountName) })
- .where('settlementModelId', model.settlementModelId)
+ await knex.select('s.settlementModelId', 's.name', 'lat.name AS latName')
+ .from('settlementModel AS s')
+ .transacting(trx)
+ .innerJoin('ledgerAccountType as lat', 's.ledgerAccountTypeId', 'lat.ledgerAccountTypeId')
+ .then(async (models) => {
+ for (const model of models) {
+ let settlementAccountName
+ if (model.latName === 'POSITION') {
+ settlementAccountName = 'SETTLEMENT'
+ } else {
+ settlementAccountName = model.latName + '_SETTLEMENT'
}
- })
- await trx.commit
- } catch (e) {
- await trx.rollback
- }
+ await knex('settlementModel').transacting(trx).update({ settlementAccountTypeId: knex('ledgerAccountType').select('ledgerAccountTypeId').where('name', settlementAccountName) })
+ .where('settlementModelId', model.settlementModelId)
+ }
+ })
})
await knex.schema.alterTable('settlementModel', (t) => {
t.integer('settlementAccountTypeId').alter().notNullable()
diff --git a/migrations/950108_participantProxy.js b/migrations/950108_participantProxy.js
new file mode 100644
index 000000000..7b6c2ef58
--- /dev/null
+++ b/migrations/950108_participantProxy.js
@@ -0,0 +1,52 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+'use strict'
+
+exports.up = async (knex) => {
+ return await knex.schema.hasTable('participant').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('participant', (t) => {
+ t.boolean('isProxy').defaultTo(false).notNullable()
+
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.alterTable('participant', (t) => {
+ t.dropColumn('isProxy')
+ })
+}
diff --git a/migrations/950109_fxQuote.js b/migrations/950109_fxQuote.js
new file mode 100644
index 000000000..99d8e9763
--- /dev/null
+++ b/migrations/950109_fxQuote.js
@@ -0,0 +1,53 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+// Notes: these changes are required for the quoting-service and are not used by central-ledger
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuote').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuote', (t) => {
+ t.string('conversionRequestId', 36).primary().notNullable()
+
+ // time keeping
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuote')
+}
diff --git a/migrations/950110_fxQuoteResponse.js b/migrations/950110_fxQuoteResponse.js
new file mode 100644
index 000000000..523132dd0
--- /dev/null
+++ b/migrations/950110_fxQuoteResponse.js
@@ -0,0 +1,59 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteResponse').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteResponse', (t) => {
+ t.bigIncrements('fxQuoteResponseId').primary().notNullable()
+
+ // reference to the original fxQuote
+ t.string('conversionRequestId', 36).notNullable()
+ t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote')
+
+ // ilpCondition sent in FXP response
+ t.string('ilpCondition', 256).notNullable()
+
+ // time keeping
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuoteResponse')
+}
diff --git a/migrations/950111_fxQuoteError.js b/migrations/950111_fxQuoteError.js
new file mode 100644
index 000000000..e74c25ad3
--- /dev/null
+++ b/migrations/950111_fxQuoteError.js
@@ -0,0 +1,57 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+// Notes: these changes are required for the quoting-service and are not used by central-ledger
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteError').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteError', (t) => {
+ t.bigIncrements('fxQuoteErrorId').primary().notNullable()
+ t.string('conversionRequestId', 36).notNullable()
+ t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote')
+ t.bigInteger('fxQuoteResponseId').unsigned().defaultTo(null).nullable().comment('The response to the initial fxQuote')
+ t.foreign('fxQuoteResponseId').references('fxQuoteResponseId').inTable('fxQuoteResponse')
+ t.integer('errorCode').unsigned().notNullable()
+ t.string('errorDescription', 128).notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('quoteError')
+}
diff --git a/migrations/950113_fxQuoteDuplicateCheck.js b/migrations/950113_fxQuoteDuplicateCheck.js
new file mode 100644
index 000000000..3c7afd9dc
--- /dev/null
+++ b/migrations/950113_fxQuoteDuplicateCheck.js
@@ -0,0 +1,52 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+// Notes: these changes are required for the quoting-service and are not used by central-ledger
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteDuplicateCheck').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteDuplicateCheck', (t) => {
+ t.string('conversionRequestId', 36).primary().notNullable()
+ t.string('hash', 1024).defaultTo(null).nullable().comment('hash value received for the quote request')
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuoteDuplicateCheck')
+}
diff --git a/migrations/950114_fxQuoteResponseDuplicateCheck.js b/migrations/950114_fxQuoteResponseDuplicateCheck.js
new file mode 100644
index 000000000..74a048083
--- /dev/null
+++ b/migrations/950114_fxQuoteResponseDuplicateCheck.js
@@ -0,0 +1,55 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+// Notes: these changes are required for the quoting-service and are not used by central-ledger
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteResponseDuplicateCheck').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteResponseDuplicateCheck', (t) => {
+ t.bigIncrements('fxQuoteResponseId').primary().unsigned().comment('The response to the initial quote')
+ t.foreign('fxQuoteResponseId').references('fxQuoteResponseId').inTable('fxQuoteResponse')
+ t.string('conversionRequestId', 36).notNullable()
+ t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote')
+ t.string('hash', 255).defaultTo(null).nullable().comment('hash value received for the quote response')
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuoteResponseDuplicateCheck')
+}
diff --git a/migrations/950115_fxQuoteConversionTerms.js b/migrations/950115_fxQuoteConversionTerms.js
new file mode 100644
index 000000000..82d57901f
--- /dev/null
+++ b/migrations/950115_fxQuoteConversionTerms.js
@@ -0,0 +1,70 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteConversionTerms').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteConversionTerms', (t) => {
+ t.string('conversionId').primary().notNullable()
+ t.string('determiningTransferId', 36).defaultTo(null).nullable()
+
+ // reference to the original fxQuote
+ t.string('conversionRequestId', 36).notNullable()
+ t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote')
+
+ t.integer('amountTypeId').unsigned().notNullable().comment('This is part of the transaction type that contains valid elements for - Amount Type')
+ t.foreign('amountTypeId').references('amountTypeId').inTable('amountType')
+ t.string('initiatingFsp', 255)
+ t.string('counterPartyFsp', 255)
+ t.decimal('sourceAmount', 18, 4).notNullable()
+ t.string('sourceCurrency', 3).notNullable()
+ t.foreign('sourceCurrency').references('currencyId').inTable('currency')
+ // Should only be nullable in POST /fxQuote request
+ t.decimal('targetAmount', 18, 4).defaultTo(null).nullable()
+ t.string('targetCurrency', 3).notNullable()
+ t.foreign('targetCurrency').references('currencyId').inTable('currency')
+
+ // time keeping
+ t.dateTime('expirationDate').notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuoteConversionTerms')
+}
diff --git a/migrations/950116_fxQuoteConversionTermsExtension.js b/migrations/950116_fxQuoteConversionTermsExtension.js
new file mode 100644
index 000000000..7daf55cbf
--- /dev/null
+++ b/migrations/950116_fxQuoteConversionTermsExtension.js
@@ -0,0 +1,55 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+// Notes: these changes are required for the quoting-service and are not used by central-ledger
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteConversionTermsExtension').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteConversionTermsExtension', (t) => {
+ t.bigIncrements('fxQuoteConversionTermExtension').primary().notNullable()
+ t.string('conversionId', 36).notNullable()
+ t.foreign('conversionId').references('conversionId').inTable('fxQuoteConversionTerms')
+ t.string('key', 128).notNullable()
+ t.text('value').notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuoteConversionTermsExtension')
+}
diff --git a/migrations/950117_fxQuoteResponseConversionTerms.js b/migrations/950117_fxQuoteResponseConversionTerms.js
new file mode 100644
index 000000000..b60b75686
--- /dev/null
+++ b/migrations/950117_fxQuoteResponseConversionTerms.js
@@ -0,0 +1,73 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteResponseConversionTerms').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteResponseConversionTerms', (t) => {
+ t.string('conversionId').primary().notNullable()
+ t.string('determiningTransferId', 36).defaultTo(null).nullable()
+
+ // reference to the original fxQuote
+ t.string('conversionRequestId', 36).notNullable()
+ t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote')
+
+ // reference to the original fxQuoteResponse
+ t.bigIncrements('fxQuoteResponseId', 36).notNullable()
+ t.foreign('fxQuoteResponseId').references('fxQuoteResponseId').inTable('fxQuoteResponse')
+
+ t.integer('amountTypeId').unsigned().notNullable().comment('This is part of the transaction type that contains valid elements for - Amount Type')
+ t.foreign('amountTypeId').references('amountTypeId').inTable('amountType')
+ t.string('initiatingFsp', 255)
+ t.string('counterPartyFsp', 255)
+ t.decimal('sourceAmount', 18, 4).notNullable()
+ t.string('sourceCurrency', 3).notNullable()
+ t.foreign('sourceCurrency').references('currencyId').inTable('currency')
+ t.decimal('targetAmount', 18, 4).notNullable()
+ t.string('targetCurrency', 3).notNullable()
+ t.foreign('targetCurrency').references('currencyId').inTable('currency')
+
+ // time keeping
+ t.dateTime('expirationDate').notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuoteResponseConversionTerms')
+}
diff --git a/migrations/950118_fxQuoteResponseConversionTermsExtension.js b/migrations/950118_fxQuoteResponseConversionTermsExtension.js
new file mode 100644
index 000000000..1cd7317fc
--- /dev/null
+++ b/migrations/950118_fxQuoteResponseConversionTermsExtension.js
@@ -0,0 +1,55 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+// Notes: these changes are required for the quoting-service and are not used by central-ledger
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxQuoteResponseConversionTermsExtension').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxQuoteResponseConversionTermsExtension', (t) => {
+ t.bigIncrements('fxQuoteResponseConversionTermsExtension').primary().notNullable()
+ t.string('conversionId', 36).notNullable()
+ t.foreign('conversionId').references('conversionId').inTable('fxQuoteResponseConversionTerms')
+ t.string('key', 128).notNullable()
+ t.text('value').notNullable()
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxQuoteResponseConversionTermsExtension')
+}
diff --git a/migrations/950119_fxCharge.js b/migrations/950119_fxCharge.js
new file mode 100644
index 000000000..81799e192
--- /dev/null
+++ b/migrations/950119_fxCharge.js
@@ -0,0 +1,61 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+'use strict'
+
+exports.up = (knex) => {
+ return knex.schema.hasTable('fxCharge').then((exists) => {
+ if (!exists) {
+ return knex.schema.createTable('fxCharge', (t) => {
+ t.bigIncrements('fxChargeId').primary().notNullable()
+ t.string('chargeType', 32).notNullable().comment('A description of the charge which is being levied.')
+
+ // fxCharge should only be sent back in the response to an fxQuote
+ // so reference the terms in fxQuoteResponse `conversionTerms`
+ t.string('conversionId', 36).notNullable()
+ t.foreign('conversionId').references('conversionId').inTable('fxQuoteResponseConversionTerms')
+
+ t.decimal('sourceAmount', 18, 4).nullable().comment('The amount of the charge which is being levied, expressed in the source currency.')
+ t.string('sourceCurrency', 3).nullable().comment('The currency in which the source amount charge is being levied.')
+
+ t.decimal('targetAmount', 18, 4).nullable().comment('The amount of the charge which is being levied, expressed in the target currency.')
+ t.string('targetCurrency', 3).nullable().comment('The currency in which the target amount charge is being levied.')
+ })
+ }
+ })
+}
+
+exports.down = (knex) => {
+ return knex.schema.dropTableIfExists('fxCharge')
+}
diff --git a/migrations/960100_create_externalParticipant.js b/migrations/960100_create_externalParticipant.js
new file mode 100644
index 000000000..a0f4ab5f7
--- /dev/null
+++ b/migrations/960100_create_externalParticipant.js
@@ -0,0 +1,47 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Eugen Klymniuk
+ --------------
+ **********/
+
+exports.up = async (knex) => {
+ return knex.schema.hasTable('externalParticipant').then(function(exists) {
+ if (!exists) {
+ return knex.schema.createTable('externalParticipant', (t) => {
+ t.bigIncrements('externalParticipantId').primary().notNullable()
+ t.string('name', 30).notNullable()
+ t.unique('name')
+ t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable()
+ t.integer('proxyId').unsigned().notNullable()
+ t.foreign('proxyId').references('participantId').inTable('participant')
+ })
+ }
+ })
+}
+
+exports.down = function (knex) {
+ return knex.schema.hasTable('externalParticipant').then(function(exists) {
+ if (!exists) {
+ return knex.schema.dropTableIfExists('externalParticipant')
+ }
+ })
+}
diff --git a/migrations/960110_alter_transferParticipant__addFiled_externalParticipantId.js b/migrations/960110_alter_transferParticipant__addFiled_externalParticipantId.js
new file mode 100644
index 000000000..13b01119e
--- /dev/null
+++ b/migrations/960110_alter_transferParticipant__addFiled_externalParticipantId.js
@@ -0,0 +1,50 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Eugen Klymniuk
+ --------------
+ **********/
+
+const EP_ID_FIELD = 'externalParticipantId'
+
+exports.up = async (knex) => {
+ return knex.schema.hasTable('transferParticipant').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('transferParticipant', (t) => {
+ t.bigint(EP_ID_FIELD).unsigned().nullable()
+ t.foreign(EP_ID_FIELD).references(EP_ID_FIELD).inTable('externalParticipant')
+ t.index(EP_ID_FIELD)
+ })
+ }
+ })
+}
+
+exports.down = async (knex) => {
+ return knex.schema.hasTable('transferParticipant').then(function(exists) {
+ if (exists) {
+ return knex.schema.alterTable('transferParticipant', (t) => {
+ t.dropIndex(EP_ID_FIELD)
+ t.dropForeign(EP_ID_FIELD)
+ t.dropColumn(EP_ID_FIELD)
+ })
+ }
+ })
+}
diff --git a/migrations/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js b/migrations/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js
new file mode 100644
index 000000000..ecf4adefd
--- /dev/null
+++ b/migrations/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js
@@ -0,0 +1,50 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Eugen Klymniuk
+ --------------
+ **********/
+
+const EP_ID_FIELD = 'externalParticipantId'
+
+exports.up = async (knex) => {
+ return knex.schema.hasTable('fxTransferParticipant').then((exists) => {
+ if (exists) {
+ return knex.schema.alterTable('fxTransferParticipant', (t) => {
+ t.bigint(EP_ID_FIELD).unsigned().nullable()
+ t.foreign(EP_ID_FIELD).references(EP_ID_FIELD).inTable('externalParticipant')
+ t.index(EP_ID_FIELD)
+ })
+ }
+ })
+}
+
+exports.down = async (knex) => {
+ return knex.schema.hasTable('fxTransferParticipant').then((exists) => {
+ if (exists) {
+ return knex.schema.alterTable('fxTransferParticipant', (t) => {
+ t.dropIndex(EP_ID_FIELD)
+ t.dropForeign(EP_ID_FIELD)
+ t.dropColumn(EP_ID_FIELD)
+ })
+ }
+ })
+}
diff --git a/package-lock.json b/package-lock.json
index 1535b785d..9d3f562c4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,67 +1,72 @@
{
"name": "@mojaloop/central-ledger",
- "version": "17.7.8",
+ "version": "17.8.0-snapshot.34",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@mojaloop/central-ledger",
- "version": "17.7.8",
+ "version": "17.8.0-snapshot.34",
"license": "Apache-2.0",
"dependencies": {
"@hapi/basic": "7.0.2",
"@hapi/catbox-memory": "6.0.2",
"@hapi/good": "9.0.1",
- "@hapi/hapi": "21.3.10",
+ "@hapi/hapi": "21.3.12",
"@hapi/inert": "7.1.0",
"@hapi/joi": "17.1.1",
"@hapi/vision": "7.0.3",
- "@mojaloop/central-services-error-handling": "13.0.1",
+ "@mojaloop/central-services-error-handling": "13.0.2",
"@mojaloop/central-services-health": "15.0.0",
- "@mojaloop/central-services-logger": "11.3.1",
- "@mojaloop/central-services-metrics": "12.0.8",
- "@mojaloop/central-services-shared": "18.3.8",
- "@mojaloop/central-services-stream": "11.3.1",
- "@mojaloop/database-lib": "11.0.5",
+ "@mojaloop/central-services-logger": "11.5.1",
+ "@mojaloop/central-services-metrics": "12.4.2",
+ "@mojaloop/central-services-shared": "18.14.1",
+ "@mojaloop/central-services-stream": "11.4.1",
+ "@mojaloop/database-lib": "11.0.6",
"@mojaloop/event-sdk": "14.1.1",
+ "@mojaloop/inter-scheme-proxy-cache-lib": "2.3.1",
"@mojaloop/ml-number": "11.2.4",
"@mojaloop/object-store-lib": "12.0.3",
"@now-ims/hapi-now-auth": "2.1.0",
- "ajv": "8.16.0",
+ "ajv": "8.17.1",
"ajv-keywords": "5.1.0",
"base64url": "3.0.1",
"blipp": "4.0.2",
"commander": "12.1.0",
- "cron": "3.1.7",
+ "cron": "3.3.1",
"decimal.js": "10.4.3",
"docdash": "2.0.2",
"event-stream": "4.0.1",
"five-bells-condition": "5.0.1",
- "glob": "10.4.1",
+ "glob": "10.4.3",
+ "hapi-auth-basic": "5.0.0",
"hapi-auth-bearer-token": "8.0.0",
- "hapi-swagger": "17.2.1",
+ "hapi-swagger": "17.3.2",
"ilp-packet": "2.2.0",
"knex": "3.1.0",
"lodash": "4.17.21",
"moment": "2.30.1",
"mongo-uri-builder": "^4.0.0",
+ "parse-strings-in-object": "2.0.0",
"rc": "1.2.8",
"require-glob": "^4.1.0"
},
"devDependencies": {
+ "@types/mock-knex": "0.4.8",
"async-retry": "1.3.3",
- "audit-ci": "^7.0.1",
+ "audit-ci": "^7.1.0",
"get-port": "5.1.1",
- "jsdoc": "4.0.3",
+ "jsdoc": "4.0.4",
"jsonpath": "1.1.1",
- "nodemon": "3.1.3",
- "npm-check-updates": "16.14.20",
- "nyc": "17.0.0",
+ "mock-knex": "0.4.13",
+ "nodemon": "3.1.9",
+ "npm-check-updates": "17.1.11",
+ "nyc": "17.1.0",
"pre-commit": "1.2.2",
"proxyquire": "2.1.3",
"replace": "^1.2.2",
"sinon": "17.0.0",
- "standard": "17.1.0",
+ "standard": "17.1.2",
"standard-version": "^9.5.0",
"tap-spec": "^5.0.0",
"tap-xunit": "2.4.1",
@@ -95,9 +100,9 @@
}
},
"node_modules/@apidevtools/json-schema-ref-parser": {
- "version": "11.6.2",
- "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.2.tgz",
- "integrity": "sha512-ENUdLLT04aDbbHCRwfKf8gR67AhV0CdFrOAtk+FcakBAgaq6ds3HLK9X0BCyiFUz8pK9uP+k6YZyJaGG7Mt7vQ==",
+ "version": "11.7.0",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz",
+ "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==",
"dependencies": {
"@jsdevtools/ono": "^7.1.3",
"@types/json-schema": "^7.0.15",
@@ -554,11 +559,9 @@
}
},
"node_modules/@colors/colors": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
- "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
- "dev": true,
- "optional": true,
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
+ "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
"engines": {
"node": ">=0.1.90"
}
@@ -705,12 +708,6 @@
"resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz",
"integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw=="
},
- "node_modules/@gar/promisify": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
- "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
- "dev": true
- },
"node_modules/@grpc/grpc-js": {
"version": "1.10.9",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz",
@@ -798,9 +795,9 @@
}
},
"node_modules/@hapi/bounce": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-3.0.1.tgz",
- "integrity": "sha512-G+/Pp9c1Ha4FDP+3Sy/Xwg2O4Ahaw3lIZFSX+BL4uWi64CmiETuZPxhKDUD4xBMOUZbBlzvO8HjiK8ePnhBadA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-3.0.2.tgz",
+ "integrity": "sha512-d0XmlTi3H9HFDHhQLjg4F4auL1EY3Wqj7j7/hGDhFFe6xAbnm3qiGrXeT93zZnPH8gH+SKAFYiRzu26xkXcH3g==",
"dependencies": {
"@hapi/boom": "^10.0.1",
"@hapi/hoek": "^11.0.2"
@@ -897,19 +894,19 @@
"deprecated": "This version has been deprecated and is no longer supported or maintained"
},
"node_modules/@hapi/hapi": {
- "version": "21.3.10",
- "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-21.3.10.tgz",
- "integrity": "sha512-CmEcmTREW394MaGGKvWpoOK4rG8tKlpZLs30tbaBzhCrhiL2Ti/HARek9w+8Ya4nMBGcd+kDAzvU44OX8Ms0Jg==",
+ "version": "21.3.12",
+ "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-21.3.12.tgz",
+ "integrity": "sha512-GCUP12dkb3QMjpFl+wEFO73nqKRmsnD5um/QDOn6lj2GjGBrDXPcT194mNARO+PPNXZOR4KmvIpHt/lceUncfg==",
"dependencies": {
- "@hapi/accept": "^6.0.1",
+ "@hapi/accept": "^6.0.3",
"@hapi/ammo": "^6.0.1",
"@hapi/boom": "^10.0.1",
- "@hapi/bounce": "^3.0.1",
+ "@hapi/bounce": "^3.0.2",
"@hapi/call": "^9.0.1",
"@hapi/catbox": "^12.1.1",
"@hapi/catbox-memory": "^6.0.2",
"@hapi/heavy": "^8.0.1",
- "@hapi/hoek": "^11.0.2",
+ "@hapi/hoek": "^11.0.6",
"@hapi/mimos": "^7.0.1",
"@hapi/podium": "^5.0.1",
"@hapi/shot": "^6.0.1",
@@ -917,7 +914,7 @@
"@hapi/statehood": "^8.1.1",
"@hapi/subtext": "^8.1.0",
"@hapi/teamwork": "^6.0.0",
- "@hapi/topo": "^6.0.1",
+ "@hapi/topo": "^6.0.2",
"@hapi/validate": "^2.0.1"
},
"engines": {
@@ -953,9 +950,9 @@
}
},
"node_modules/@hapi/hoek": {
- "version": "11.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz",
- "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ=="
+ "version": "11.0.7",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.7.tgz",
+ "integrity": "sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ=="
},
"node_modules/@hapi/inert": {
"version": "7.1.0",
@@ -1294,6 +1291,11 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@ioredis/commands": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
+ "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg=="
+ },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -1496,19 +1498,12 @@
}
},
"node_modules/@mojaloop/central-services-error-handling": {
- "version": "13.0.1",
- "resolved": "https://registry.npmjs.org/@mojaloop/central-services-error-handling/-/central-services-error-handling-13.0.1.tgz",
- "integrity": "sha512-Hl0KBHX30LbF127tgqNK/fdo0hwa6Bt23tb8DesLstYawKtCesJtk9lPuo6jE+dafNeG2QusUwVQyI+7kwAUHQ==",
+ "version": "13.0.2",
+ "resolved": "https://registry.npmjs.org/@mojaloop/central-services-error-handling/-/central-services-error-handling-13.0.2.tgz",
+ "integrity": "sha512-HSxI7OrtPdA94aHNWmAD50Ve8lR6FmgOX2LaZSL/TPfx22PVTTht0eXU+IQSN/srF20f2tvCa2CdFxWBQf6Ilg==",
"dependencies": {
+ "fast-safe-stringify": "2.1.1",
"lodash": "4.17.21"
- },
- "peerDependencies": {
- "@mojaloop/sdk-standard-components": ">=18.x.x"
- },
- "peerDependenciesMeta": {
- "@mojaloop/sdk-standard-components": {
- "optional": false
- }
}
},
"node_modules/@mojaloop/central-services-health": {
@@ -1570,51 +1565,88 @@
}
},
"node_modules/@mojaloop/central-services-logger": {
- "version": "11.3.1",
- "resolved": "https://registry.npmjs.org/@mojaloop/central-services-logger/-/central-services-logger-11.3.1.tgz",
- "integrity": "sha512-XVU2K5grE1ZcIyxUXeMlvoVkeIcs9y1/0EKxa2Bk5sEbqXUtHuR8jqbAGlwaUIi9T9YWZRJyVC77nOQe/X1teA==",
+ "version": "11.5.1",
+ "resolved": "https://registry.npmjs.org/@mojaloop/central-services-logger/-/central-services-logger-11.5.1.tgz",
+ "integrity": "sha512-l+6+w35NqFJn1Xl82l55x71vCARWTkO6hYAgwbFuqVRqX0jqaRi4oiXG2WwPRVMLqVv8idAboCMX/I6vg/d4Kw==",
"dependencies": {
- "@types/node": "^20.12.7",
"parse-strings-in-object": "2.0.0",
"rc": "1.2.8",
"safe-stable-stringify": "^2.4.3",
- "winston": "3.13.0"
+ "winston": "3.14.2"
+ }
+ },
+ "node_modules/@mojaloop/central-services-logger/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@mojaloop/central-services-logger/node_modules/winston": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-3.14.2.tgz",
+ "integrity": "sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==",
+ "dependencies": {
+ "@colors/colors": "^1.6.0",
+ "@dabh/diagnostics": "^2.0.2",
+ "async": "^3.2.3",
+ "is-stream": "^2.0.0",
+ "logform": "^2.6.0",
+ "one-time": "^1.0.0",
+ "readable-stream": "^3.4.0",
+ "safe-stable-stringify": "^2.3.1",
+ "stack-trace": "0.0.x",
+ "triple-beam": "^1.3.0",
+ "winston-transport": "^4.7.0"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
}
},
"node_modules/@mojaloop/central-services-metrics": {
- "version": "12.0.8",
- "resolved": "https://registry.npmjs.org/@mojaloop/central-services-metrics/-/central-services-metrics-12.0.8.tgz",
- "integrity": "sha512-eYWX56zMlj0M0bE6qBLzhwDjo0C4LUQLcQW8du3xJ3mhxH0fSmw+Y5wsmuPmUVQZ90EU4S8l39VcXwh6ludLVg==",
+ "version": "12.4.2",
+ "resolved": "https://registry.npmjs.org/@mojaloop/central-services-metrics/-/central-services-metrics-12.4.2.tgz",
+ "integrity": "sha512-0XFW9nBJNY70tya/DEYlGl12adfb/3cAWuHv88vF8JI+JQAIE/6ePyET1Wb3tMp0BUcjFF5b1XbbYcOF69wKZQ==",
"dependencies": {
- "prom-client": "14.2.0"
+ "prom-client": "15.1.3"
}
},
"node_modules/@mojaloop/central-services-shared": {
- "version": "18.3.8",
- "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-18.3.8.tgz",
- "integrity": "sha512-Wk+uG+mnOFrFNeDq0ffE+OXvcAtfemSPocPdCRFvnF0p123tV9CiH540R29XrXlRTLt78JS4N3GBYyR7E3ZfBA==",
+ "version": "18.14.1",
+ "resolved": "https://registry.npmjs.org/@mojaloop/central-services-shared/-/central-services-shared-18.14.1.tgz",
+ "integrity": "sha512-m04gmTfm7WBqdFgZBPljgUWRQ+htCTQJQ9jjblvj4b5Rbw0YI4gntsjyBxFKcVIIqluCeSmhzb9GPTIP/6Simg==",
"dependencies": {
"@hapi/catbox": "12.1.1",
"@hapi/catbox-memory": "5.0.1",
- "axios": "1.7.2",
+ "@mojaloop/inter-scheme-proxy-cache-lib": "2.3.1",
+ "axios": "1.7.9",
"clone": "2.1.2",
- "dotenv": "16.4.5",
+ "dotenv": "16.4.7",
"env-var": "7.5.0",
"event-stream": "4.0.1",
- "immutable": "4.3.6",
+ "fast-safe-stringify": "^2.1.1",
+ "immutable": "5.0.3",
+ "ioredis": "^5.4.1",
"lodash": "4.17.21",
"mustache": "4.2.0",
- "openapi-backend": "5.10.6",
- "raw-body": "2.5.2",
+ "openapi-backend": "5.11.1",
+ "raw-body": "3.0.0",
"rc": "1.2.8",
"shins": "2.6.0",
+ "ulidx": "2.4.1",
"uuid4": "2.0.3",
"widdershins": "^4.0.1",
- "yaml": "2.4.5"
+ "yaml": "2.6.1"
},
"peerDependencies": {
"@mojaloop/central-services-error-handling": ">=13.x.x",
- "@mojaloop/central-services-logger": ">=11.x.x",
+ "@mojaloop/central-services-logger": ">=11.5.x",
"@mojaloop/central-services-metrics": ">=12.x.x",
"@mojaloop/event-sdk": ">=14.1.1",
"ajv": "8.x.x",
@@ -1649,12 +1681,6 @@
"@hapi/hoek": "9.x.x"
}
},
- "node_modules/@mojaloop/central-services-shared/node_modules/@hapi/boom/node_modules/@hapi/hoek": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.3.tgz",
- "integrity": "sha512-jKtjLLDiH95b002sJVc5c74PE6KKYftuyVdVmsuYId5stTaWcRFqE+5ukZI4gDUKjGn8wv2C3zPn3/nyjEI7gg==",
- "deprecated": "This version has been deprecated and is no longer supported or maintained"
- },
"node_modules/@mojaloop/central-services-shared/node_modules/@hapi/catbox-memory": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-5.0.1.tgz",
@@ -1664,18 +1690,17 @@
"@hapi/hoek": "9.x.x"
}
},
- "node_modules/@mojaloop/central-services-shared/node_modules/@hapi/catbox-memory/node_modules/@hapi/hoek": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.3.tgz",
- "integrity": "sha512-jKtjLLDiH95b002sJVc5c74PE6KKYftuyVdVmsuYId5stTaWcRFqE+5ukZI4gDUKjGn8wv2C3zPn3/nyjEI7gg==",
- "deprecated": "This version has been deprecated and is no longer supported or maintained"
+ "node_modules/@mojaloop/central-services-shared/node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
},
"node_modules/@mojaloop/central-services-stream": {
- "version": "11.3.1",
- "resolved": "https://registry.npmjs.org/@mojaloop/central-services-stream/-/central-services-stream-11.3.1.tgz",
- "integrity": "sha512-mSdWvEFJEjKkZdDs+e1yeZm/gFfXTqA+eVRIBmp8p67QJy36ZTaAvrvebGYKZ60MBN2syDrqL+DbQMJdoxHLEA==",
+ "version": "11.4.1",
+ "resolved": "https://registry.npmjs.org/@mojaloop/central-services-stream/-/central-services-stream-11.4.1.tgz",
+ "integrity": "sha512-LbnT/JAqliL8xWf/vCt5fJGIP8+o5Gcx265GPXbJPKSQrJ8UV5cUs1CIv0S/nYjrZuvfeEI3RQYuc93NF9qO3g==",
"dependencies": {
- "async": "3.2.5",
+ "async": "3.2.6",
"async-exit-hook": "2.0.1",
"events": "3.3.0",
"node-rdkafka": "2.18.0"
@@ -1694,9 +1719,9 @@
}
},
"node_modules/@mojaloop/database-lib": {
- "version": "11.0.5",
- "resolved": "https://registry.npmjs.org/@mojaloop/database-lib/-/database-lib-11.0.5.tgz",
- "integrity": "sha512-u7MOtJIwwlyxeFlUplf7kcdjnyOZpXS1rqEQw21WBIRTl4RXqQl6/ThTCIjCxxGc4dK/BfZz7Spo10RHcWvSgw==",
+ "version": "11.0.6",
+ "resolved": "https://registry.npmjs.org/@mojaloop/database-lib/-/database-lib-11.0.6.tgz",
+ "integrity": "sha512-5rg8aBkHEaz6MkgVZqXkYFFVKAc80iQejmyZaws3vuZnrG6YfAhTGQTSZCDfYX3WqtDpt4OE8yhYeBua82ftMA==",
"dependencies": {
"knex": "3.1.0",
"lodash": "4.17.21",
@@ -1741,6 +1766,21 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
},
+ "node_modules/@mojaloop/inter-scheme-proxy-cache-lib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@mojaloop/inter-scheme-proxy-cache-lib/-/inter-scheme-proxy-cache-lib-2.3.1.tgz",
+ "integrity": "sha512-94HhBs/DJOwyE24CSVBpySrulMHN/xntc9c/0ZjpOzVHBsu/HJmfiA/CuwTo0GGNFrCxM9FgwjccafQeEs2B1A==",
+ "dependencies": {
+ "@mojaloop/central-services-logger": "11.5.1",
+ "ajv": "^8.17.1",
+ "convict": "^6.2.4",
+ "fast-safe-stringify": "^2.1.1",
+ "ioredis": "^5.4.1"
+ },
+ "engines": {
+ "node": ">=18.x"
+ }
+ },
"node_modules/@mojaloop/ml-number": {
"version": "11.2.4",
"resolved": "https://registry.npmjs.org/@mojaloop/ml-number/-/ml-number-11.2.4.tgz",
@@ -1765,60 +1805,10 @@
}
}
},
- "node_modules/@mojaloop/sdk-standard-components": {
- "version": "18.1.0",
- "resolved": "https://registry.npmjs.org/@mojaloop/sdk-standard-components/-/sdk-standard-components-18.1.0.tgz",
- "integrity": "sha512-8g4JuVl3f9t80OEtvn9BeUtlZIW4kcL40f72FZobtqQjAZ+yz4J0BlWS/OEJDpuYV1qoyxGiuMRojKqP2Yio7g==",
- "peer": true,
- "dependencies": {
- "base64url": "3.0.1",
- "fast-safe-stringify": "^2.1.1",
- "ilp-packet": "2.2.0",
- "jsonwebtoken": "9.0.2",
- "jws": "4.0.0"
- }
- },
- "node_modules/@mojaloop/sdk-standard-components/node_modules/jsonwebtoken": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
- "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
- "peer": true,
- "dependencies": {
- "jws": "^3.2.2",
- "lodash": "^4.17.21",
- "ms": "^2.1.1",
- "semver": "^7.3.8"
- },
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- }
- },
- "node_modules/@mojaloop/sdk-standard-components/node_modules/jsonwebtoken/node_modules/jws": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
- "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
- "peer": true,
- "dependencies": {
- "jwa": "^1.4.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/@mojaloop/sdk-standard-components/node_modules/jwa": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
- "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
- "peer": true,
- "dependencies": {
- "buffer-equal-constant-time": "1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
"node_modules/@mongodb-js/saslprep": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz",
- "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==",
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
+ "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==",
"optional": true,
"dependencies": {
"sparse-bitfield": "^3.0.3"
@@ -1919,427 +1909,134 @@
"safe-buffer": "^5.0.1"
}
},
- "node_modules/@npmcli/fs": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz",
- "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==",
- "dev": true,
- "dependencies": {
- "semver": "^7.3.5"
- },
+ "node_modules/@opentelemetry/api": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
+ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
"engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ "node": ">=8.0.0"
}
},
- "node_modules/@npmcli/git": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz",
- "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==",
- "dev": true,
- "dependencies": {
- "@npmcli/promise-spawn": "^6.0.0",
- "lru-cache": "^7.4.4",
- "npm-pick-manifest": "^8.0.0",
- "proc-log": "^3.0.0",
- "promise-inflight": "^1.0.1",
- "promise-retry": "^2.0.1",
- "semver": "^7.3.5",
- "which": "^3.0.0"
- },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "optional": true,
"engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ "node": ">=14"
}
},
- "node_modules/@npmcli/git/node_modules/which": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
- "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
- "dev": true,
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
"dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/which.js"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
}
},
- "node_modules/@npmcli/installed-package-contents": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz",
- "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==",
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+ },
+ "node_modules/@sideway/address": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
+ "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@sideway/address/node_modules/@hapi/hoek": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.3.tgz",
+ "integrity": "sha512-jKtjLLDiH95b002sJVc5c74PE6KKYftuyVdVmsuYId5stTaWcRFqE+5ukZI4gDUKjGn8wv2C3zPn3/nyjEI7gg==",
+ "deprecated": "This version has been deprecated and is no longer supported or maintained"
+ },
+ "node_modules/@sideway/formula": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
+ },
+ "node_modules/@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
+ "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
"dev": true,
"dependencies": {
- "npm-bundled": "^3.0.0",
- "npm-normalize-package-bin": "^3.0.0"
- },
- "bin": {
- "installed-package-contents": "lib/index.js"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ "type-detect": "4.0.8"
}
},
- "node_modules/@npmcli/move-file": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
- "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
- "deprecated": "This functionality has been moved to @npmcli/fs",
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "11.2.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
+ "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
"dev": true,
"dependencies": {
- "mkdirp": "^1.0.4",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "@sinonjs/commons": "^3.0.0"
}
},
- "node_modules/@npmcli/move-file/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "node_modules/@sinonjs/samsam": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
+ "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
"dev": true,
"dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "@sinonjs/commons": "^2.0.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
}
},
- "node_modules/@npmcli/move-file/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@npmcli/node-gyp": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz",
- "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==",
- "dev": true,
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@npmcli/promise-spawn": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz",
- "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==",
- "dev": true,
- "dependencies": {
- "which": "^3.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@npmcli/promise-spawn/node_modules/which": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
- "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/which.js"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@npmcli/run-script": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz",
- "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==",
- "dev": true,
- "dependencies": {
- "@npmcli/node-gyp": "^3.0.0",
- "@npmcli/promise-spawn": "^6.0.0",
- "node-gyp": "^9.0.0",
- "read-package-json-fast": "^3.0.0",
- "which": "^3.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@npmcli/run-script/node_modules/which": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
- "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/which.js"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
- "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "optional": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@pnpm/config.env-replace": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
- "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==",
- "dev": true,
- "engines": {
- "node": ">=12.22.0"
- }
- },
- "node_modules/@pnpm/network.ca-file": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
- "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "4.2.10"
- },
- "engines": {
- "node": ">=12.22.0"
- }
- },
- "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": {
- "version": "4.2.10",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
- "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
- "dev": true
- },
- "node_modules/@pnpm/npm-conf": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz",
- "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==",
- "dev": true,
- "dependencies": {
- "@pnpm/config.env-replace": "^1.1.0",
- "@pnpm/network.ca-file": "^1.0.1",
- "config-chain": "^1.1.11"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@protobufjs/aspromise": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
- "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
- },
- "node_modules/@protobufjs/base64": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
- "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
- },
- "node_modules/@protobufjs/codegen": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
- "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
- },
- "node_modules/@protobufjs/eventemitter": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
- "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
- },
- "node_modules/@protobufjs/fetch": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
- "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
- "dependencies": {
- "@protobufjs/aspromise": "^1.1.1",
- "@protobufjs/inquire": "^1.1.0"
- }
- },
- "node_modules/@protobufjs/float": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
- "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
- },
- "node_modules/@protobufjs/inquire": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
- "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
- },
- "node_modules/@protobufjs/path": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
- "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
- },
- "node_modules/@protobufjs/pool": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
- "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
- },
- "node_modules/@protobufjs/utf8": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
- "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
- },
- "node_modules/@sideway/address": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
- "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
- "dependencies": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "node_modules/@sideway/address/node_modules/@hapi/hoek": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.3.tgz",
- "integrity": "sha512-jKtjLLDiH95b002sJVc5c74PE6KKYftuyVdVmsuYId5stTaWcRFqE+5ukZI4gDUKjGn8wv2C3zPn3/nyjEI7gg==",
- "deprecated": "This version has been deprecated and is no longer supported or maintained"
- },
- "node_modules/@sideway/formula": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
- "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
- },
- "node_modules/@sideway/pinpoint": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
- "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
- },
- "node_modules/@sigstore/bundle": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz",
- "integrity": "sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==",
- "dev": true,
- "dependencies": {
- "@sigstore/protobuf-specs": "^0.2.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@sigstore/protobuf-specs": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz",
- "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==",
- "dev": true,
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@sigstore/sign": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz",
- "integrity": "sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==",
- "dev": true,
- "dependencies": {
- "@sigstore/bundle": "^1.1.0",
- "@sigstore/protobuf-specs": "^0.2.0",
- "make-fetch-happen": "^11.0.1"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@sigstore/tuf": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz",
- "integrity": "sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==",
- "dev": true,
- "dependencies": {
- "@sigstore/protobuf-specs": "^0.2.0",
- "tuf-js": "^1.1.7"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@sindresorhus/is": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz",
- "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/is?sponsor=1"
- }
- },
- "node_modules/@sinonjs/commons": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
- "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
- "dev": true,
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/@sinonjs/fake-timers": {
- "version": "11.2.2",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
- "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^3.0.0"
- }
- },
- "node_modules/@sinonjs/samsam": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
- "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^2.0.0",
- "lodash.get": "^4.4.2",
- "type-detect": "^4.0.8"
- }
- },
- "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
- "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
+ "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
+ "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
"dev": true,
"dependencies": {
"type-detect": "4.0.8"
@@ -2351,55 +2048,6 @@
"integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
"dev": true
},
- "node_modules/@szmarczak/http-timer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
- "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==",
- "dev": true,
- "dependencies": {
- "defer-to-connect": "^2.0.1"
- },
- "engines": {
- "node": ">=14.16"
- }
- },
- "node_modules/@tootallnate/once": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
- "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
- "dev": true,
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tufjs/canonical-json": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz",
- "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==",
- "dev": true,
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@tufjs/models": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz",
- "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==",
- "dev": true,
- "dependencies": {
- "@tufjs/canonical-json": "1.0.0",
- "minimatch": "^9.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/@types/http-cache-semantics": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
- "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
- "dev": true
- },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -2444,6 +2092,15 @@
"integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
"dev": true
},
+ "node_modules/@types/mock-knex": {
+ "version": "0.4.8",
+ "resolved": "https://registry.npmjs.org/@types/mock-knex/-/mock-knex-0.4.8.tgz",
+ "integrity": "sha512-xRoaH9GmsgP5JBdMadzJSg/63HCifgJZsWmCJ5Z1rA36Fg3Y7Yb03dMzMIk5sHnBWcPkWqY/zyDO4nStI+Frbg==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/node": {
"version": "20.12.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
@@ -2458,12 +2115,6 @@
"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
"dev": true
},
- "node_modules/@types/semver-utils": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@types/semver-utils/-/semver-utils-1.1.3.tgz",
- "integrity": "sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==",
- "dev": true
- },
"node_modules/@types/triple-beam": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
@@ -2524,40 +2175,16 @@
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/add-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
- "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
- "dev": true
- },
- "node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "dev": true,
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/agentkeepalive": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
- "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==",
- "dev": true,
- "dependencies": {
- "humanize-ms": "^1.2.1"
- },
- "engines": {
- "node": ">= 8.0.0"
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/add-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
+ "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==",
+ "dev": true
+ },
"node_modules/aggregate-error": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@@ -2572,12 +2199,12 @@
}
},
"node_modules/ajv": {
- "version": "8.16.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz",
- "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==",
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dependencies": {
"fast-deep-equal": "^3.1.3",
- "fast-uri": "^2.3.0",
+ "fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
@@ -2637,47 +2264,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/ansi-align": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
- "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.1.0"
- }
- },
- "node_modules/ansi-align/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/ansi-align/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-align/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -2724,58 +2310,28 @@
"node": ">=8"
}
},
- "node_modules/aproba": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
- "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
- "dev": true
- },
"node_modules/archy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
"integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
"dev": true
},
- "node_modules/are-we-there-yet": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
- "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
- "dev": true,
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^3.6.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/are-we-there-yet/node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dev": true,
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/array-buffer-byte-length": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
- "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "is-array-buffer": "^3.0.1"
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -2793,15 +2349,16 @@
"dev": true
},
"node_modules/array-includes": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz",
- "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==",
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
"is-string": "^1.0.7"
},
"engines": {
@@ -2819,6 +2376,26 @@
"node": ">=8"
}
},
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/array.prototype.findlastindex": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz",
@@ -2875,30 +2452,34 @@
}
},
"node_modules/array.prototype.tosorted": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz",
- "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-shim-unscopables": "^1.0.0",
- "get-intrinsic": "^1.2.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/arraybuffer.prototype.slice": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz",
- "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
"dev": true,
"dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
- "is-array-buffer": "^3.0.2",
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.3",
+ "es-errors": "^1.2.1",
+ "get-intrinsic": "^1.2.3",
+ "is-array-buffer": "^3.0.4",
"is-shared-array-buffer": "^1.0.2"
},
"engines": {
@@ -2928,9 +2509,9 @@
}
},
"node_modules/async": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
- "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="
},
"node_modules/async-exit-hook": {
"version": "2.0.1",
@@ -2949,24 +2530,15 @@
"retry": "0.13.1"
}
},
- "node_modules/asynciterator.prototype": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
- "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==",
- "dev": true,
- "dependencies": {
- "has-symbols": "^1.0.3"
- }
- },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/audit-ci": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/audit-ci/-/audit-ci-7.0.1.tgz",
- "integrity": "sha512-NAZuQYyZHmtrNGpS4qfUp8nFvB+6UdfSOg7NUcsyvuDVfulXH3lpnN2PcXOUj7Jr3epAoQ6BCpXmjMODC8SBgQ==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/audit-ci/-/audit-ci-7.1.0.tgz",
+ "integrity": "sha512-PjjEejlST57S/aDbeWLic0glJ8CNl/ekY3kfGFPMrPkmuaYaDKcMH0F9x9yS9Vp6URhuefSCubl/G0Y2r6oP0g==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
@@ -2987,10 +2559,13 @@
}
},
"node_modules/available-typed-arrays": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
- "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"dev": true,
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -2999,9 +2574,9 @@
}
},
"node_modules/axios": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
- "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+ "version": "1.7.9",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
+ "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
@@ -3084,9 +2659,9 @@
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
},
"node_modules/body-parser": {
- "version": "1.20.2",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
- "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
@@ -3096,7 +2671,7 @@
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
- "qs": "6.11.0",
+ "qs": "6.13.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
@@ -3130,18 +2705,18 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/body-parser/node_modules/qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "node_modules/body-parser/node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dependencies": {
- "side-channel": "^1.0.4"
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
},
"engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 0.8"
}
},
"node_modules/boolbase": {
@@ -3149,63 +2724,20 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
- "node_modules/boxen": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz",
- "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==",
- "dev": true,
+ "node_modules/boom": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz",
+ "integrity": "sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==",
+ "deprecated": "This module has moved and is now available at @hapi/boom. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.",
"dependencies": {
- "ansi-align": "^3.0.1",
- "camelcase": "^7.0.1",
- "chalk": "^5.2.0",
- "cli-boxes": "^3.0.0",
- "string-width": "^5.1.2",
- "type-fest": "^2.13.0",
- "widest-line": "^4.0.1",
- "wrap-ansi": "^8.1.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/boxen/node_modules/camelcase": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz",
- "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/boxen/node_modules/chalk": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
- "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
- "dev": true,
- "engines": {
- "node": "^12.17.0 || ^14.13 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "hoek": "6.x.x"
}
},
- "node_modules/boxen/node_modules/type-fest": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
- "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
- "dev": true,
- "engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
+ "node_modules/boom/node_modules/hoek": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz",
+ "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==",
+ "deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues."
},
"node_modules/brace-expansion": {
"version": "2.0.1",
@@ -3305,56 +2837,6 @@
"node": ">= 0.8"
}
},
- "node_modules/cacache": {
- "version": "17.1.4",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz",
- "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==",
- "dev": true,
- "dependencies": {
- "@npmcli/fs": "^3.1.0",
- "fs-minipass": "^3.0.0",
- "glob": "^10.2.2",
- "lru-cache": "^7.7.1",
- "minipass": "^7.0.3",
- "minipass-collect": "^1.0.2",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "p-map": "^4.0.0",
- "ssri": "^10.0.0",
- "tar": "^6.1.11",
- "unique-filename": "^3.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/cacheable-lookup": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
- "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- }
- },
- "node_modules/cacheable-request": {
- "version": "10.2.14",
- "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz",
- "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==",
- "dev": true,
- "dependencies": {
- "@types/http-cache-semantics": "^4.0.2",
- "get-stream": "^6.0.1",
- "http-cache-semantics": "^4.1.1",
- "keyv": "^4.5.3",
- "mimic-response": "^4.0.0",
- "normalize-url": "^8.0.0",
- "responselike": "^3.0.0"
- },
- "engines": {
- "node": ">=14.16"
- }
- },
"node_modules/caching-transform": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
@@ -3486,20 +2968,24 @@
}
},
"node_modules/cheerio": {
- "version": "1.0.0-rc.12",
- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
- "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
+ "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
"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"
+ "domutils": "^3.1.0",
+ "encoding-sniffer": "^0.2.0",
+ "htmlparser2": "^9.1.0",
+ "parse5": "^7.1.2",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^6.19.5",
+ "whatwg-mimetype": "^4.0.0"
},
"engines": {
- "node": ">= 6"
+ "node": ">=18.17"
},
"funding": {
"url": "https://github.com/cheeriojs/cheerio?sponsor=1"
@@ -3547,96 +3033,13 @@
"fsevents": "~2.3.2"
}
},
- "node_modules/chownr": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
- "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ci-info": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/clean-stack": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
- "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/cli-boxes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
- "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/cli-table3": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz",
- "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0"
- },
- "engines": {
- "node": "10.* || >= 12.*"
- },
- "optionalDependencies": {
- "@colors/colors": "1.5.0"
- }
- },
- "node_modules/cli-table3/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/cli-table3/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cli-table3/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
"dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
"engines": {
- "node": ">=8"
+ "node": ">=6"
}
},
"node_modules/cliui": {
@@ -3705,6 +3108,14 @@
"node": ">=0.8"
}
},
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
+ "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -3747,15 +3158,6 @@
"simple-swizzle": "^0.2.2"
}
},
- "node_modules/color-support": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "dev": true,
- "bin": {
- "color-support": "bin.js"
- }
- },
"node_modules/color/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -3892,74 +3294,6 @@
"typedarray": "^0.0.6"
}
},
- "node_modules/config-chain": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
- "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
- "dev": true,
- "dependencies": {
- "ini": "^1.3.4",
- "proto-list": "~1.2.1"
- }
- },
- "node_modules/config-chain/node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
- },
- "node_modules/configstore": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz",
- "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==",
- "dev": true,
- "dependencies": {
- "dot-prop": "^6.0.1",
- "graceful-fs": "^4.2.6",
- "unique-string": "^3.0.0",
- "write-file-atomic": "^3.0.3",
- "xdg-basedir": "^5.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/yeoman/configstore?sponsor=1"
- }
- },
- "node_modules/configstore/node_modules/dot-prop": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
- "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
- "dev": true,
- "dependencies": {
- "is-obj": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/configstore/node_modules/xdg-basedir": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
- "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
- "dev": true
- },
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -4314,12 +3648,24 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
+ "node_modules/convict": {
+ "version": "6.2.4",
+ "resolved": "https://registry.npmjs.org/convict/-/convict-6.2.4.tgz",
+ "integrity": "sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==",
+ "dependencies": {
+ "lodash.clonedeep": "^4.5.0",
+ "yargs-parser": "^20.2.7"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
"engines": {
- "node": ">= 0.6"
+ "node": ">=18"
}
},
"node_modules/cookie-signature": {
@@ -4333,18 +3679,18 @@
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/cron": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/cron/-/cron-3.1.7.tgz",
- "integrity": "sha512-tlBg7ARsAMQLzgwqVxy8AZl/qlTc5nibqYwtNGoCrd+cV+ugI+tvZC1oT/8dFH8W455YrywGykx/KMmAqOr7Jw==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/cron/-/cron-3.3.1.tgz",
+ "integrity": "sha512-KpvuzJEbeTMTfLsXhUuDfsFYr8s5roUlLKb4fa68GszWrA4783C7q6m9yj4vyc6neyD/V9e0YiADSX2c+yRDXg==",
"dependencies": {
"@types/luxon": "~3.4.0",
- "luxon": "~3.4.0"
+ "luxon": "~3.5.0"
}
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -4354,33 +3700,6 @@
"node": ">= 8"
}
},
- "node_modules/crypto-random-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz",
- "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==",
- "dev": true,
- "dependencies": {
- "type-fest": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/crypto-random-string/node_modules/type-fest": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
- "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
@@ -4416,6 +3735,57 @@
"node": ">=8"
}
},
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/dateformat": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
@@ -4484,33 +3854,6 @@
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
"integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
},
- "node_modules/decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "dev": true,
- "dependencies": {
- "mimic-response": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decompress-response/node_modules/mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/deep-equal": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz",
@@ -4589,15 +3932,6 @@
"node": ">=0.8"
}
},
- "node_modules/defer-to-connect": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
- "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -4648,11 +3982,13 @@
"node": ">=0.4.0"
}
},
- "node_modules/delegates": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
- "dev": true
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "engines": {
+ "node": ">=0.10"
+ }
},
"node_modules/depd": {
"version": "2.0.0",
@@ -4747,17 +4083,6 @@
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
- "node_modules/dom-serializer/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
@@ -4820,9 +4145,9 @@
}
},
"node_modules/dotenv": {
- "version": "16.4.5",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
- "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
+ "version": "16.4.7",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+ "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
"engines": {
"node": ">=12"
},
@@ -5049,20 +4374,23 @@
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
},
"node_modules/encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/encoding": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
- "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
- "optional": true,
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
+ "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
"dependencies": {
- "iconv-lite": "^0.6.2"
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
}
},
"node_modules/end-of-stream": {
@@ -5074,22 +4402,16 @@
}
},
"node_modules/entities": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
- "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/env-paths": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
- "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/env-var": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/env-var/-/env-var-7.5.0.tgz",
@@ -5098,12 +4420,6 @@
"node": ">=10"
}
},
- "node_modules/err-code": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
- "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
- "dev": true
- },
"node_modules/error-callsites": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/error-callsites/-/error-callsites-2.0.4.tgz",
@@ -5122,50 +4438,57 @@
}
},
"node_modules/es-abstract": {
- "version": "1.22.3",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
- "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==",
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
+ "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
"dev": true,
"dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "arraybuffer.prototype.slice": "^1.0.2",
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.5",
- "es-set-tostringtag": "^2.0.1",
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.3",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
"es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.6",
- "get-intrinsic": "^1.2.2",
- "get-symbol-description": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "get-symbol-description": "^1.0.2",
"globalthis": "^1.0.3",
"gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.0",
- "has-proto": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
- "hasown": "^2.0.0",
- "internal-slot": "^1.0.5",
- "is-array-buffer": "^3.0.2",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.0.7",
+ "is-array-buffer": "^3.0.4",
"is-callable": "^1.2.7",
- "is-negative-zero": "^2.0.2",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
"is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
+ "is-shared-array-buffer": "^1.0.3",
"is-string": "^1.0.7",
- "is-typed-array": "^1.1.12",
+ "is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
"object-inspect": "^1.13.1",
"object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.1",
- "safe-array-concat": "^1.0.1",
- "safe-regex-test": "^1.0.0",
- "string.prototype.trim": "^1.2.8",
- "string.prototype.trimend": "^1.0.7",
- "string.prototype.trimstart": "^1.0.7",
- "typed-array-buffer": "^1.0.0",
- "typed-array-byte-length": "^1.0.0",
- "typed-array-byte-offset": "^1.0.0",
- "typed-array-length": "^1.0.4",
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.2",
+ "safe-array-concat": "^1.1.2",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
"unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.13"
+ "which-typed-array": "^1.1.15"
},
"engines": {
"node": ">= 0.4"
@@ -5194,36 +4517,51 @@
}
},
"node_modules/es-iterator-helpers": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz",
- "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==",
+ "version": "1.0.19",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz",
+ "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==",
"dev": true,
"dependencies": {
- "asynciterator.prototype": "^1.0.0",
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.7",
"define-properties": "^1.2.1",
- "es-abstract": "^1.22.1",
- "es-set-tostringtag": "^2.0.1",
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.0.3",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
"globalthis": "^1.0.3",
- "has-property-descriptors": "^1.0.0",
- "has-proto": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
- "internal-slot": "^1.0.5",
+ "internal-slot": "^1.0.7",
"iterator.prototype": "^1.1.2",
- "safe-array-concat": "^1.0.1"
+ "safe-array-concat": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
- "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+ "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.2.2",
- "has-tostringtag": "^1.0.0",
- "hasown": "^2.0.0"
+ "get-intrinsic": "^1.2.4",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -5274,18 +4612,6 @@
"node": ">=6"
}
},
- "node_modules/escape-goat": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz",
- "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -5737,33 +5063,36 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.33.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
- "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==",
+ "version": "7.36.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz",
+ "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "array-includes": "^3.1.6",
- "array.prototype.flatmap": "^1.3.1",
- "array.prototype.tosorted": "^1.1.1",
+ "array-includes": "^3.1.8",
+ "array.prototype.findlast": "^1.2.5",
+ "array.prototype.flatmap": "^1.3.2",
+ "array.prototype.tosorted": "^1.1.4",
"doctrine": "^2.1.0",
- "es-iterator-helpers": "^1.0.12",
+ "es-iterator-helpers": "^1.0.19",
"estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
- "object.entries": "^1.1.6",
- "object.fromentries": "^2.0.6",
- "object.hasown": "^1.1.2",
- "object.values": "^1.1.6",
+ "object.entries": "^1.1.8",
+ "object.fromentries": "^2.0.8",
+ "object.values": "^1.2.0",
"prop-types": "^15.8.1",
- "resolve": "^2.0.0-next.4",
+ "resolve": "^2.0.0-next.5",
"semver": "^6.3.1",
- "string.prototype.matchall": "^4.0.8"
+ "string.prototype.matchall": "^4.0.11",
+ "string.prototype.repeat": "^1.0.0"
},
"engines": {
"node": ">=4"
},
"peerDependencies": {
- "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
}
},
"node_modules/eslint-plugin-react/node_modules/brace-expansion": {
@@ -6110,29 +5439,18 @@
}
},
"node_modules/execa/node_modules/cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
- "dependencies": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- },
- "engines": {
- "node": ">=4.8"
- }
- },
- "node_modules/execa/node_modules/get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+ "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"dependencies": {
- "pump": "^3.0.0"
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
},
"engines": {
- "node": ">=6"
+ "node": ">=4.8"
}
},
"node_modules/execa/node_modules/is-stream": {
@@ -6194,43 +5512,37 @@
"which": "bin/which"
}
},
- "node_modules/exponential-backoff": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
- "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==",
- "dev": true
- },
"node_modules/express": {
- "version": "4.19.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
- "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.2",
+ "body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.6.0",
+ "cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
- "encodeurl": "~1.0.2",
+ "encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
- "finalhandler": "1.2.0",
+ "finalhandler": "1.3.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
- "merge-descriptors": "1.0.1",
+ "merge-descriptors": "1.0.3",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
+ "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7",
- "qs": "6.11.0",
+ "qs": "6.13.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
- "send": "0.18.0",
- "serve-static": "1.15.0",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
@@ -6239,12 +5551,16 @@
},
"engines": {
"node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/express/node_modules/cookie": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
- "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"engines": {
"node": ">= 0.6"
}
@@ -6262,20 +5578,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/express/node_modules/qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
- "dependencies": {
- "side-channel": "^1.0.4"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/extensible-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/extensible-error/-/extensible-error-1.0.2.tgz",
@@ -6312,21 +5614,15 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
- "node_modules/fast-memoize": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
- "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==",
- "dev": true
- },
"node_modules/fast-safe-stringify": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
},
"node_modules/fast-uri": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.3.0.tgz",
- "integrity": "sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw=="
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz",
+ "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw=="
},
"node_modules/fastq": {
"version": "1.15.0",
@@ -6426,12 +5722,12 @@
}
},
"node_modules/finalhandler": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
"dependencies": {
"debug": "2.6.9",
- "encodeurl": "~1.0.2",
+ "encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
@@ -6514,63 +5810,6 @@
"node": ">=12.0.0"
}
},
- "node_modules/flat-cache/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/flat-cache/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/flat-cache/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/flat-cache/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/flatted": {
"version": "3.2.9",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
@@ -6583,9 +5822,9 @@
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
},
"node_modules/follow-redirects": {
- "version": "1.15.6",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
- "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"funding": [
{
"type": "individual",
@@ -6616,9 +5855,9 @@
"integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg=="
},
"node_modules/foreground-child": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
- "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
@@ -6631,9 +5870,9 @@
}
},
"node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@@ -6643,15 +5882,6 @@
"node": ">= 6"
}
},
- "node_modules/form-data-encoder": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
- "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==",
- "dev": true,
- "engines": {
- "node": ">= 14.17"
- }
- },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -6660,15 +5890,6 @@
"node": ">= 0.6"
}
},
- "node_modules/fp-and-or": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/fp-and-or/-/fp-and-or-0.1.4.tgz",
- "integrity": "sha512-+yRYRhpnFPWXSly/6V4Lw9IfOV26uu30kynGJ03PW+MnjOEQe45RZ141QcS0aJehYBYA50GfCDnsRbFJdhssRw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -6702,18 +5923,6 @@
}
]
},
- "node_modules/fs-minipass": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
- "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
- "dev": true,
- "dependencies": {
- "minipass": "^7.0.3"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/fs-readfile-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fs-readfile-promise/-/fs-readfile-promise-2.0.1.tgz",
@@ -6807,63 +6016,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/gauge": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
- "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
- "dev": true,
- "dependencies": {
- "aproba": "^1.0.3 || ^2.0.0",
- "color-support": "^1.1.3",
- "console-control-strings": "^1.1.0",
- "has-unicode": "^2.0.1",
- "signal-exit": "^3.0.7",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "wide-align": "^1.1.5"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/gauge/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/gauge/node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true
- },
- "node_modules/gauge/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/gauge/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -7067,25 +6219,25 @@
}
},
"node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "dev": true,
- "engines": {
- "node": ">=10"
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dependencies": {
+ "pump": "^3.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+ "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bind": "^1.0.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
@@ -7181,21 +6333,22 @@
"dev": true
},
"node_modules/glob": {
- "version": "10.4.1",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz",
- "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==",
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz",
+ "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": ">=16 || 14 >=14.18"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -7212,30 +6365,6 @@
"node": ">= 6"
}
},
- "node_modules/global-dirs": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz",
- "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==",
- "dev": true,
- "dependencies": {
- "ini": "2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/global-dirs/node_modules/ini": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
- "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -7290,31 +6419,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/got": {
- "version": "12.6.1",
- "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz",
- "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==",
- "dev": true,
- "dependencies": {
- "@sindresorhus/is": "^5.2.0",
- "@szmarczak/http-timer": "^5.0.1",
- "cacheable-lookup": "^7.0.0",
- "cacheable-request": "^10.2.8",
- "decompress-response": "^6.0.0",
- "form-data-encoder": "^2.1.2",
- "get-stream": "^6.0.1",
- "http2-wrapper": "^2.1.10",
- "lowercase-keys": "^3.0.0",
- "p-cancelable": "^3.0.0",
- "responselike": "^3.0.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/got?sponsor=1"
- }
- },
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -7346,6 +6450,50 @@
"uglify-js": "^3.1.4"
}
},
+ "node_modules/hapi": {
+ "version": "18.1.0",
+ "resolved": "https://registry.npmjs.org/hapi/-/hapi-18.1.0.tgz",
+ "integrity": "sha512-nSU1VLyTAgp7P5gy47QzJIP2JAb+wOFvJIV3gnL0lFj/mD+HuTXhyUsDYXjF/dhADMVXVEz31z6SUHBJhtsvGA==",
+ "deprecated": "This version contains severe security issues and defects and should not be used! Please upgrade to the latest version of @hapi/hapi or consider a commercial license (https://github.com/hapijs/hapi/issues/4114)",
+ "hasShrinkwrap": true,
+ "peer": true,
+ "dependencies": {
+ "accept": "3.x.x",
+ "ammo": "3.x.x",
+ "boom": "7.x.x",
+ "bounce": "1.x.x",
+ "call": "5.x.x",
+ "catbox": "10.x.x",
+ "catbox-memory": "4.x.x",
+ "heavy": "6.x.x",
+ "hoek": "6.x.x",
+ "joi": "14.x.x",
+ "mimos": "4.x.x",
+ "podium": "3.x.x",
+ "shot": "4.x.x",
+ "somever": "2.x.x",
+ "statehood": "6.x.x",
+ "subtext": "6.x.x",
+ "teamwork": "3.x.x",
+ "topo": "3.x.x"
+ }
+ },
+ "node_modules/hapi-auth-basic": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/hapi-auth-basic/-/hapi-auth-basic-5.0.0.tgz",
+ "integrity": "sha512-4ceLge/CYBtEAvfnbwBPPck2wb9O7wksaeSOF0C1lp8GX2IuIm8BqtZtvDGLhqNH5j3ztP4im/TfCj3oYQ9bgA==",
+ "deprecated": "This module has moved and is now available at @hapi/basic. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.",
+ "dependencies": {
+ "boom": "7.x.x",
+ "hoek": "5.x.x"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ },
+ "peerDependencies": {
+ "hapi": ">=17.x.x"
+ }
+ },
"node_modules/hapi-auth-bearer-token": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/hapi-auth-bearer-token/-/hapi-auth-bearer-token-8.0.0.tgz",
@@ -7368,26 +6516,194 @@
"integrity": "sha512-jKtjLLDiH95b002sJVc5c74PE6KKYftuyVdVmsuYId5stTaWcRFqE+5ukZI4gDUKjGn8wv2C3zPn3/nyjEI7gg==",
"deprecated": "This version has been deprecated and is no longer supported or maintained"
},
- "node_modules/hapi-swagger": {
- "version": "17.2.1",
- "resolved": "https://registry.npmjs.org/hapi-swagger/-/hapi-swagger-17.2.1.tgz",
- "integrity": "sha512-IaF3OHfYjzDuyi5EQgS0j0xB7sbAAD4DaTwexdhPYqEBI/J7GWMXFbftGObCIOeMVDufjoSBZWeaarEkNn6/ww==",
- "dependencies": {
- "@apidevtools/json-schema-ref-parser": "^11.1.0",
- "@hapi/boom": "^10.0.1",
- "@hapi/hoek": "^11.0.2",
- "handlebars": "^4.7.8",
- "http-status": "^1.7.3",
- "swagger-parser": "^10.0.3",
- "swagger-ui-dist": "^5.9.1"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "@hapi/hapi": ">=20.x.x",
- "joi": "17.x"
- }
+ "node_modules/hapi-swagger": {
+ "version": "17.3.2",
+ "resolved": "https://registry.npmjs.org/hapi-swagger/-/hapi-swagger-17.3.2.tgz",
+ "integrity": "sha512-mj1KPBl5UY4rLTLj9CrgNCps29iZ7vKNTEey3Ztm7fZ/DrMdJ7KHdxSucACyaFdPAiEpfJtHvm/5lxJVXVxa4g==",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "^11.7.0",
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.4",
+ "handlebars": "^4.7.8",
+ "http-status": "^1.7.4",
+ "swagger-parser": "^10.0.3",
+ "swagger-ui-dist": "^5.17.14"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "@hapi/hapi": ">=20.x.x",
+ "joi": "17.x"
+ }
+ },
+ "node_modules/hapi/node_modules/accept": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/accept/-/accept-3.1.3.tgz",
+ "integrity": "sha512-OgOEAidVEOKPup+Gv2+2wdH2AgVKI9LxsJ4hicdJ6cY0faUuZdZoi56kkXWlHp9qicN1nWQLmW5ZRGk+SBS5xg==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/ammo": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/ammo/-/ammo-3.0.3.tgz",
+ "integrity": "sha512-vo76VJ44MkUBZL/BzpGXaKzMfroF4ZR6+haRuw9p+eSWfoNaH2AxVc8xmiEPC08jhzJSeM6w7/iMUGet8b4oBQ==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/b64": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/b64/-/b64-4.1.2.tgz",
+ "integrity": "sha512-+GUspBxlH3CJaxMUGUE1EBoWM6RKgWiYwUDal0qdf8m3ArnXNN1KzKVo5HOnE/FSq4HHyWf3TlHLsZI8PKQgrQ==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/boom": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz",
+ "integrity": "sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/bounce": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bounce/-/bounce-1.2.3.tgz",
+ "integrity": "sha512-3G7B8CyBnip5EahCZJjnvQ1HLyArC6P5e+xcolo13BVI9ogFaDOsNMAE7FIWliHtIkYI8/nTRCvCY9tZa3Mu4g==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/bourne": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/bourne/-/bourne-1.1.1.tgz",
+ "integrity": "sha512-Ou0l3W8+n1FuTOoIfIrCk9oF9WVWc+9fKoAl67XQr9Ws0z7LgILRZ7qtc9xdT4BveSKtnYXfKPgn8pFAqeQRew==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/call": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/call/-/call-5.0.3.tgz",
+ "integrity": "sha512-eX16KHiAYXugbFu6VifstSdwH6aMuWWb4s0qvpq1nR1b+Sf+u68jjttg8ixDBEldPqBi30bDU35OJQWKeTLKxg==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/catbox": {
+ "version": "10.0.6",
+ "resolved": "https://registry.npmjs.org/catbox/-/catbox-10.0.6.tgz",
+ "integrity": "sha512-gQWCnF/jbHcfwGbQ4FQxyRiAwLRipqWTTXjpq7rTqqdcsnZosFa0L3LsCZcPTF33QIeMMkS7QmFBHt6QdzGPvg==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/catbox-memory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/catbox-memory/-/catbox-memory-4.0.1.tgz",
+ "integrity": "sha512-ZmqNiLsYCIu9qvBJ/MQbznDV2bFH5gFiH67TgIJgSSffJFtTXArT+MM3AvJQlby9NSkLHOX4eH/uuUqnch/Ldw==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/content": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/content/-/content-4.0.6.tgz",
+ "integrity": "sha512-lR9ND3dXiMdmsE84K6l02rMdgiBVmtYWu1Vr/gfSGHcIcznBj2QxmSdUgDuNFOA+G9yrb1IIWkZ7aKtB6hDGyA==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/cryptiles": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-4.1.3.tgz",
+ "integrity": "sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/heavy": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/heavy/-/heavy-6.1.2.tgz",
+ "integrity": "sha512-cJp884bqhiebNcEHydW0g6V1MUGYOXRPw9c7MFiHQnuGxtbWuSZpsbojwb2kxb3AA1/Rfs8CNiV9MMOF8pFRDg==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/hoek": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz",
+ "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/iron": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/iron/-/iron-5.0.6.tgz",
+ "integrity": "sha512-zYUMOSkEXGBdwlV/AXF9zJC0aLuTJUKHkGeYS5I2g225M5i6SrxQyGJGhPgOR8BK1omL6N5i6TcwfsXbP8/Exw==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/joi": {
+ "version": "14.3.1",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-14.3.1.tgz",
+ "integrity": "sha512-LQDdM+pkOrpAn4Lp+neNIFV3axv1Vna3j38bisbQhETPMANYRbFJFUyOZcOClYvM/hppMhGWuKSFEK9vjrB+bQ==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/mime-db": {
+ "version": "1.37.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+ "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/mimos": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/mimos/-/mimos-4.0.2.tgz",
+ "integrity": "sha512-5XBsDqBqzSN88XPPH/TFpOalWOjHJM5Z2d3AMx/30iq+qXvYKd/8MPhqBwZDOLtoaIWInR3nLzMQcxfGK9djXA==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/nigel": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/nigel/-/nigel-3.0.4.tgz",
+ "integrity": "sha512-3SZCCS/duVDGxFpTROHEieC+itDo4UqL9JNUyQJv3rljudQbK6aqus5B4470OxhESPJLN93Qqxg16rH7DUjbfQ==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/pez": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/pez/-/pez-4.0.5.tgz",
+ "integrity": "sha512-HvL8uiFIlkXbx/qw4B8jKDCWzo7Pnnd65Uvanf9OOCtb20MRcb9gtTVBf9NCnhETif1/nzbDHIjAWC/sUp7LIQ==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/podium": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/podium/-/podium-3.2.0.tgz",
+ "integrity": "sha512-rbwvxwVkI6gRRlxZQ1zUeafrpGxZ7QPHIheinehAvGATvGIPfWRkaTeWedc5P4YjXJXEV8ZbBxPtglNylF9hjw==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/shot": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/shot/-/shot-4.0.7.tgz",
+ "integrity": "sha512-RKaKAGKxJ11EjJl0cf2fYVSsd4KB5Cncb9J0v7w+0iIaXpxNqFWTYNDNhBX7f0XSyDrjOH9a4OWZ9Gp/ZML+ew==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/somever": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/somever/-/somever-2.0.0.tgz",
+ "integrity": "sha512-9JaIPP+HxwYGqCDqqK3tRaTqdtQHoK6Qy3IrXhIt2q5x8fs8RcfU7BMWlFTCOgFazK8p88zIv1tHQXvAwtXMyw==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/statehood": {
+ "version": "6.0.9",
+ "resolved": "https://registry.npmjs.org/statehood/-/statehood-6.0.9.tgz",
+ "integrity": "sha512-jbFg1+MYEqfC7ABAoWZoeF4cQUtp3LUvMDUGExL76cMmleBHG7I6xlZFsE8hRi7nEySIvutHmVlLmBe9+2R5LQ==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/subtext": {
+ "version": "6.0.12",
+ "resolved": "https://registry.npmjs.org/subtext/-/subtext-6.0.12.tgz",
+ "integrity": "sha512-yT1wCDWVgqvL9BIkWzWqgj5spUSYo/Enu09iUV8t2ZvHcr2tKGTGg2kc9tUpVEsdhp1ihsZeTAiDqh0TQciTPQ==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/teamwork": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/teamwork/-/teamwork-3.0.3.tgz",
+ "integrity": "sha512-OCB56z+G70iA1A1OFoT+51TPzfcgN0ks75uN3yhxA+EU66WTz2BevNDK4YzMqfaL5tuAvxy4iFUn35/u8pxMaQ==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/topo": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz",
+ "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==",
+ "peer": true
+ },
+ "node_modules/hapi/node_modules/vise": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/vise/-/vise-3.0.2.tgz",
+ "integrity": "sha512-X52VtdRQbSBXdjcazRiY3eRgV3vTQ0B+7Wh8uC9cVv7lKfML5m9+9NHlbcgCY0R9EAqD1v/v7o9mhGh2A3ANFg==",
+ "extraneous": true
+ },
+ "node_modules/hapi/node_modules/wreck": {
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/wreck/-/wreck-14.1.3.tgz",
+ "integrity": "sha512-hb/BUtjX3ObbwO3slCOLCenQ4EP8e+n8j6FmTne3VhEFp5XV1faSJojiyxVSvw34vgdeTG5baLTl4NmjwokLlw==",
+ "extraneous": true
},
"node_modules/har-schema": {
"version": "2.0.0",
@@ -7496,9 +6812,9 @@
}
},
"node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"engines": {
"node": ">= 0.4"
},
@@ -7518,12 +6834,12 @@
}
},
"node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"dependencies": {
- "has-symbols": "^1.0.2"
+ "has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -7532,24 +6848,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
- "dev": true
- },
- "node_modules/has-yarn": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz",
- "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/hasha": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
@@ -7567,9 +6865,9 @@
}
},
"node_modules/hasown": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
- "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -7591,16 +6889,13 @@
"integrity": "sha512-FK1vmMj8BbEipEy8DLIvp71t5UsC7n2D6En/UfM/91PCwmOpj6f2iu0Y0coRC62KSRHHC+dquM2xMULV/X7NFg==",
"deprecated": "Use the 'highlight.js' package instead https://npm.im/highlight.js"
},
- "node_modules/hosted-git-info": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz",
- "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^7.5.1"
- },
+ "node_modules/hoek": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz",
+ "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==",
+ "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
"engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "node": ">=8.9.0"
}
},
"node_modules/html-escaper": {
@@ -7610,9 +6905,9 @@
"dev": true
},
"node_modules/htmlparser2": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
- "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+ "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
@@ -7623,27 +6918,10 @@
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
- "domutils": "^3.0.1",
- "entities": "^4.4.0"
- }
- },
- "node_modules/htmlparser2/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
+ "domutils": "^3.1.0",
+ "entities": "^4.5.0"
}
},
- "node_modules/http-cache-semantics": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
- "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
- "dev": true
- },
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -7659,24 +6937,10 @@
"node": ">= 0.8"
}
},
- "node_modules/http-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
- "dev": true,
- "dependencies": {
- "@tootallnate/once": "2",
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/http-status": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.7.3.tgz",
- "integrity": "sha512-GS8tL1qHT2nBCMJDYMHGkkkKQLNkIAHz37vgO68XKvzv+XyqB4oh/DfmMHdtRzfqSJPj1xKG2TaELZtlCz6BEQ==",
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.7.4.tgz",
+ "integrity": "sha512-c2qSwNtTlHVYAhMj9JpGdyo0No/+DiKXCJ9pHtZ2Yf3QmPnBIytKSRT7BuyIiQ7icXLynavGmxUqkOjSrAuMuA==",
"engines": {
"node": ">= 0.4.0"
}
@@ -7686,44 +6950,6 @@
"resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz",
"integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA=="
},
- "node_modules/http2-wrapper": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz",
- "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==",
- "dev": true,
- "dependencies": {
- "quick-lru": "^5.1.1",
- "resolve-alpn": "^1.2.0"
- },
- "engines": {
- "node": ">=10.19.0"
- }
- },
- "node_modules/http2-wrapper/node_modules/quick-lru": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
- "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "dev": true,
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/httpsnippet": {
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/httpsnippet/-/httpsnippet-1.25.0.tgz",
@@ -7874,20 +7100,10 @@
"node": ">=0.8.0"
}
},
- "node_modules/humanize-ms": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
- "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
- "dev": true,
- "dependencies": {
- "ms": "^2.0.0"
- }
- },
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "optional": true,
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
@@ -7909,18 +7125,6 @@
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"dev": true
},
- "node_modules/ignore-walk": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz",
- "integrity": "sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==",
- "dev": true,
- "dependencies": {
- "minimatch": "^9.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/ilp-packet": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ilp-packet/-/ilp-packet-2.2.0.tgz",
@@ -7949,9 +7153,9 @@
}
},
"node_modules/immutable": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz",
- "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ=="
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz",
+ "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw=="
},
"node_modules/import-fresh": {
"version": "3.3.0",
@@ -7990,15 +7194,6 @@
"node": ">=4"
}
},
- "node_modules/import-lazy": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
- "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -8017,12 +7212,6 @@
"node": ">=8"
}
},
- "node_modules/infer-owner": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
- "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
- "dev": true
- },
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -8038,22 +7227,13 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
- "node_modules/ini": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
- "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
- "dev": true,
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/internal-slot": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz",
- "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
+ "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.2.2",
+ "es-errors": "^1.3.0",
"hasown": "^2.0.0",
"side-channel": "^1.0.4"
},
@@ -8077,6 +7257,29 @@
"node": ">=4"
}
},
+ "node_modules/ioredis": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.4.1.tgz",
+ "integrity": "sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==",
+ "dependencies": {
+ "@ioredis/commands": "^1.1.1",
+ "cluster-key-slot": "^1.1.0",
+ "debug": "^4.3.4",
+ "denque": "^2.1.0",
+ "lodash.defaults": "^4.2.0",
+ "lodash.isarguments": "^3.1.0",
+ "redis-errors": "^1.2.0",
+ "redis-parser": "^3.0.0",
+ "standard-as-callback": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ioredis"
+ }
+ },
"node_modules/ip-address": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
@@ -8119,14 +7322,16 @@
}
},
"node_modules/is-array-buffer": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
- "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+ "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.0",
- "is-typed-array": "^1.1.10"
+ "get-intrinsic": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8209,18 +7414,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-ci": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
- "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
- "dev": true,
- "dependencies": {
- "ci-info": "^3.2.0"
- },
- "bin": {
- "is-ci": "bin.js"
- }
- },
"node_modules/is-core-module": {
"version": "2.13.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
@@ -8232,6 +7425,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-data-view": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+ "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+ "dev": true,
+ "dependencies": {
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
@@ -8313,41 +7521,22 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-installed-globally": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
- "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==",
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
"dev": true,
- "dependencies": {
- "global-dirs": "^3.0.0",
- "is-path-inside": "^3.0.2"
- },
"engines": {
- "node": ">=10"
+ "node": ">= 0.4"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-lambda": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
- "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
- "dev": true
- },
- "node_modules/is-map": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
- "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
"dev": true,
"engines": {
"node": ">= 0.4"
@@ -8356,18 +7545,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-npm": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz",
- "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -8460,21 +7637,27 @@
}
},
"node_modules/is-set": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
- "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-shared-array-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
- "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2"
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8534,12 +7717,12 @@
}
},
"node_modules/is-typed-array": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
- "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
+ "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
"dev": true,
"dependencies": {
- "which-typed-array": "^1.1.11"
+ "which-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
@@ -8555,10 +7738,13 @@
"dev": true
},
"node_modules/is-weakmap": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
- "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -8576,13 +7762,16 @@
}
},
"node_modules/is-weakset": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
- "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
+ "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8605,15 +7794,6 @@
"node": ">=4"
}
},
- "node_modules/is-yarn-global": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz",
- "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -8670,54 +7850,12 @@
"archy": "^1.0.0",
"cross-spawn": "^7.0.3",
"istanbul-lib-coverage": "^3.2.0",
- "p-map": "^3.0.0",
- "rimraf": "^3.0.0",
- "uuid": "^8.3.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-processinfo/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/istanbul-lib-processinfo/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/istanbul-lib-processinfo/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
+ "p-map": "^3.0.0",
+ "rimraf": "^3.0.0",
+ "uuid": "^8.3.2"
},
"engines": {
- "node": "*"
+ "node": ">=8"
}
},
"node_modules/istanbul-lib-processinfo/node_modules/p-map": {
@@ -8732,21 +7870,6 @@
"node": ">=8"
}
},
- "node_modules/istanbul-lib-processinfo/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/istanbul-lib-report": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
@@ -8817,14 +7940,14 @@
}
},
"node_modules/jackspeak": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
- "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.2.tgz",
+ "integrity": "sha512-qH3nOSj8q/8+Eg8LUPOq3C+6HWkpUioIjDsq1+D4zY91oZvpPttw8GwtF1nReRYKXl+1AORyFqtm2f5Q1SB6/Q==",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"engines": {
- "node": ">=14"
+ "node": "14 >=14.21 || 16 >=16.20 || >=18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -8834,9 +7957,9 @@
}
},
"node_modules/jake": {
- "version": "10.9.1",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz",
- "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==",
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
"dependencies": {
"async": "^3.2.3",
"chalk": "^4.0.2",
@@ -8944,10 +8067,11 @@
"integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
},
"node_modules/jsdoc": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.3.tgz",
- "integrity": "sha512-Nu7Sf35kXJ1MWDZIMAuATRQTg1iIPdzh7tqJ6jjvaU/GfDf+qi5UV8zJR3Mo+/pYFvm8mzay4+6O5EWigaQBQw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz",
+ "integrity": "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@babel/parser": "^7.20.15",
"@jsdoc/salty": "^0.2.1",
@@ -9005,24 +8129,6 @@
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
"dev": true
},
- "node_modules/json-parse-even-better-errors": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz",
- "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==",
- "dev": true,
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/json-parse-helpfulerror": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz",
- "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==",
- "dev": true,
- "dependencies": {
- "jju": "^1.1.0"
- }
- },
"node_modules/json-pointer": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz",
@@ -9060,12 +8166,6 @@
"node": ">=6"
}
},
- "node_modules/jsonlines": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsonlines/-/jsonlines-0.1.1.tgz",
- "integrity": "sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==",
- "dev": true
- },
"node_modules/jsonparse": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
@@ -9145,27 +8245,6 @@
"integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
"dev": true
},
- "node_modules/jwa": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
- "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
- "peer": true,
- "dependencies": {
- "buffer-equal-constant-time": "1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/jws": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
- "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
- "peer": true,
- "dependencies": {
- "jwa": "^2.0.0",
- "safe-buffer": "^5.0.1"
- }
- },
"node_modules/kareem": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz",
@@ -9201,15 +8280,6 @@
"graceful-fs": "^4.1.9"
}
},
- "node_modules/kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/knex": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz",
@@ -9278,20 +8348,10 @@
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
},
- "node_modules/latest-version": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz",
- "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==",
- "dev": true,
- "dependencies": {
- "package-json": "^8.1.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
+ "node_modules/layerr": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/layerr/-/layerr-3.0.0.tgz",
+ "integrity": "sha512-tv754Ki2dXpPVApOrjTyRo4/QegVb9eVFq4mjqp4+NM5NaX7syQvN5BBNfV/ZpAHCEHV24XdUVrBAoka4jt3pA=="
},
"node_modules/lazy-cache": {
"version": "1.0.4",
@@ -9335,6 +8395,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "dev": true,
"dependencies": {
"uc.micro": "^2.0.0"
}
@@ -9342,7 +8403,8 @@
"node_modules/linkify-it/node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
- "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "dev": true
},
"node_modules/load-json-file": {
"version": "5.3.0",
@@ -9403,6 +8465,16 @@
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
},
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+ },
+ "node_modules/lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
+ },
"node_modules/lodash.flattendeep": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
@@ -9414,6 +8486,11 @@
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
},
+ "node_modules/lodash.isarguments": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+ "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="
+ },
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@@ -9446,14 +8523,6 @@
"node": ">= 12.0.0"
}
},
- "node_modules/logform/node_modules/@colors/colors": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
- "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
- "engines": {
- "node": ">=0.1.90"
- }
- },
"node_modules/long": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
@@ -9479,18 +8548,6 @@
"loose-envify": "cli.js"
}
},
- "node_modules/lowercase-keys": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
- "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/lru-cache": {
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
@@ -9500,9 +8557,9 @@
}
},
"node_modules/luxon": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.3.tgz",
- "integrity": "sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg==",
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz",
+ "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==",
"engines": {
"node": ">=12"
}
@@ -9531,41 +8588,6 @@
"semver": "bin/semver.js"
}
},
- "node_modules/make-fetch-happen": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz",
- "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==",
- "dev": true,
- "dependencies": {
- "agentkeepalive": "^4.2.1",
- "cacache": "^17.0.0",
- "http-cache-semantics": "^4.1.1",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.0",
- "is-lambda": "^1.0.1",
- "lru-cache": "^7.7.1",
- "minipass": "^5.0.0",
- "minipass-fetch": "^3.0.0",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "negotiator": "^0.6.3",
- "promise-retry": "^2.0.1",
- "socks-proxy-agent": "^7.0.0",
- "ssri": "^10.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/make-fetch-happen/node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/map-age-cleaner": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
@@ -9598,6 +8620,7 @@
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "dev": true,
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
@@ -9620,17 +8643,6 @@
"markdown-it": "*"
}
},
- "node_modules/markdown-it-attrs": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-1.2.1.tgz",
- "integrity": "sha512-EYYKLF9RvQJx1Etsb6EsBGWL7qNQLpg9BRej5f06+UdX75T5gvldEn7ts6bkLIQqugE15SGn4lw1CXDS1A+XUA==",
- "engines": {
- "node": ">=6"
- },
- "peerDependencies": {
- "markdown-it": ">=7.0.1"
- }
- },
"node_modules/markdown-it-emoji": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
@@ -9641,26 +8653,17 @@
"resolved": "https://registry.npmjs.org/markdown-it-lazy-headers/-/markdown-it-lazy-headers-0.1.3.tgz",
"integrity": "sha512-65BxqvmYLpVifv6MvTElthY8zvZ/TpZBCdshr/mTpsFkqwcwWtfD3YoSE7RYSn7ugnEAAaj2gywszq+hI/Pxgg=="
},
- "node_modules/markdown-it/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
"node_modules/markdown-it/node_modules/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
- "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+ "dev": true
},
"node_modules/markdown-it/node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
- "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "dev": true
},
"node_modules/marked": {
"version": "4.3.0",
@@ -9936,9 +8939,12 @@
}
},
"node_modules/merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"node_modules/merge2": {
"version": "1.4.1",
@@ -9957,11 +8963,11 @@
}
},
"node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dependencies": {
- "braces": "^3.0.2",
+ "braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@@ -10006,18 +9012,6 @@
"node": ">=6"
}
},
- "node_modules/mimic-response": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
- "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@@ -10033,207 +9027,47 @@
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
},
"node_modules/minimatch": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
- "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "dev": true,
- "dependencies": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/minipass-collect": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
- "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
- "dev": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minipass-collect/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-fetch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz",
- "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==",
- "dev": true,
- "dependencies": {
- "minipass": "^7.0.3",
- "minipass-sized": "^1.0.3",
- "minizlib": "^2.1.2"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- },
- "optionalDependencies": {
- "encoding": "^0.1.13"
- }
- },
- "node_modules/minipass-flush": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
- "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
- "dev": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minipass-flush/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-json-stream": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz",
- "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==",
- "dev": true,
- "dependencies": {
- "jsonparse": "^1.3.1",
- "minipass": "^3.0.0"
- }
- },
- "node_modules/minipass-json-stream/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-pipeline": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
- "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
- "dev": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-pipeline/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-sized": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
- "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
- "dev": true,
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
"dependencies": {
- "minipass": "^3.0.0"
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=8"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/minipass-sized/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/minizlib": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
- "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "node_modules/minimist-options": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+ "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
"dev": true,
"dependencies": {
- "minipass": "^3.0.0",
- "yallist": "^4.0.0"
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0",
+ "kind-of": "^6.0.3"
},
"engines": {
- "node": ">= 8"
+ "node": ">= 6"
}
},
- "node_modules/minizlib/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"engines": {
- "node": ">=8"
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/mkdirp": {
@@ -10267,6 +9101,29 @@
"lodash": "^4.17.21"
}
},
+ "node_modules/mock-knex": {
+ "version": "0.4.13",
+ "resolved": "https://registry.npmjs.org/mock-knex/-/mock-knex-0.4.13.tgz",
+ "integrity": "sha512-UmZlxiJH7bBdzjSWcrLJ1tnLfPNL7GfJO1IWL4sHWfMzLqdA3VAVWhotq1YiyE5NwVcrQdoXj3TGGjhTkBeIcQ==",
+ "dev": true,
+ "dependencies": {
+ "bluebird": "^3.4.1",
+ "lodash": "^4.14.2",
+ "semver": "^5.3.0"
+ },
+ "peerDependencies": {
+ "knex": "> 0.8"
+ }
+ },
+ "node_modules/mock-knex/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
"node_modules/modify-values": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
@@ -10299,9 +9156,9 @@
}
},
"node_modules/mongodb": {
- "version": "5.9.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.0.tgz",
- "integrity": "sha512-g+GCMHN1CoRUA+wb1Agv0TI4YTSiWr42B5ulkiAfLLHitGK1R+PkSAf3Lr5rPZwi/3F04LiaZEW0Kxro9Fi2TA==",
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz",
+ "integrity": "sha512-H60HecKO4Bc+7dhOv4sJlgvenK4fQNqqUIlXxZYQNbfEWSALGAwGoyJd/0Qwk4TttFXUOHJ2ZJQe/52ScaUwtQ==",
"dependencies": {
"bson": "^5.5.0",
"mongodb-connection-string-url": "^2.6.0",
@@ -10348,13 +9205,13 @@
}
},
"node_modules/mongoose": {
- "version": "7.6.4",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.6.4.tgz",
- "integrity": "sha512-kadPkS/f5iZJrrMxxOvSoOAErXmdnb28lMvHmuYgmV1ZQTpRqpp132PIPHkJMbG4OC2H0eSXYw/fNzYTH+LUcw==",
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.8.3.tgz",
+ "integrity": "sha512-eFnbkKgyVrICoHB6tVJ4uLanS7d5AIo/xHkEbQeOv6g2sD7gh/1biRwvFifsmbtkIddQVNr3ROqHik6gkknN3g==",
"dependencies": {
"bson": "^5.5.0",
"kareem": "2.5.1",
- "mongodb": "5.9.0",
+ "mongodb": "5.9.2",
"mpath": "0.9.0",
"mquery": "5.0.0",
"ms": "2.1.3",
@@ -10433,9 +9290,9 @@
"integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw=="
},
"node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"funding": [
{
"type": "github",
@@ -10465,384 +9322,116 @@
},
"node_modules/neo-async": {
"version": "2.6.2",
- "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
- "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
- },
- "node_modules/nice-try": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
- },
- "node_modules/nise": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz",
- "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^2.0.0",
- "@sinonjs/fake-timers": "^10.0.2",
- "@sinonjs/text-encoding": "^0.7.1",
- "just-extend": "^4.0.2",
- "path-to-regexp": "^1.7.0"
- }
- },
- "node_modules/nise/node_modules/@sinonjs/commons": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
- "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
- "dev": true,
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/nise/node_modules/@sinonjs/fake-timers": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
- "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
- "dev": true,
- "dependencies": {
- "@sinonjs/commons": "^3.0.0"
- }
- },
- "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
- "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
- "dev": true,
- "dependencies": {
- "type-detect": "4.0.8"
- }
- },
- "node_modules/nise/node_modules/isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
- "dev": true
- },
- "node_modules/nise/node_modules/path-to-regexp": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
- "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
- "dev": true,
- "dependencies": {
- "isarray": "0.0.1"
- }
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-fetch-h2": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz",
- "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==",
- "dependencies": {
- "http2-client": "^1.2.5"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- }
- },
- "node_modules/node-fetch/node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
- },
- "node_modules/node-fetch/node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "node_modules/node-fetch/node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/node-gyp": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz",
- "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==",
- "dev": true,
- "dependencies": {
- "env-paths": "^2.2.0",
- "exponential-backoff": "^3.1.1",
- "glob": "^7.1.4",
- "graceful-fs": "^4.2.6",
- "make-fetch-happen": "^10.0.3",
- "nopt": "^6.0.0",
- "npmlog": "^6.0.0",
- "rimraf": "^3.0.2",
- "semver": "^7.3.5",
- "tar": "^6.1.2",
- "which": "^2.0.2"
- },
- "bin": {
- "node-gyp": "bin/node-gyp.js"
- },
- "engines": {
- "node": "^12.13 || ^14.13 || >=16"
- }
- },
- "node_modules/node-gyp/node_modules/@npmcli/fs": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
- "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
- "dev": true,
- "dependencies": {
- "@gar/promisify": "^1.1.3",
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/node-gyp/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/node-gyp/node_modules/cacache": {
- "version": "16.1.3",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
- "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
- "dev": true,
- "dependencies": {
- "@npmcli/fs": "^2.1.0",
- "@npmcli/move-file": "^2.0.0",
- "chownr": "^2.0.0",
- "fs-minipass": "^2.1.0",
- "glob": "^8.0.1",
- "infer-owner": "^1.0.4",
- "lru-cache": "^7.7.1",
- "minipass": "^3.1.6",
- "minipass-collect": "^1.0.2",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "mkdirp": "^1.0.4",
- "p-map": "^4.0.0",
- "promise-inflight": "^1.0.1",
- "rimraf": "^3.0.2",
- "ssri": "^9.0.0",
- "tar": "^6.1.11",
- "unique-filename": "^2.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/node-gyp/node_modules/cacache/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/node-gyp/node_modules/cacache/node_modules/glob": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
- "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^5.0.1",
- "once": "^1.3.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/node-gyp/node_modules/cacache/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/node-gyp/node_modules/fs-minipass": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
- "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
- "dev": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/node-gyp/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
},
- "node_modules/node-gyp/node_modules/make-fetch-happen": {
- "version": "10.2.1",
- "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
- "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
+ "node_modules/nise": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz",
+ "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==",
"dev": true,
"dependencies": {
- "agentkeepalive": "^4.2.1",
- "cacache": "^16.1.0",
- "http-cache-semantics": "^4.1.0",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.0",
- "is-lambda": "^1.0.1",
- "lru-cache": "^7.7.1",
- "minipass": "^3.1.6",
- "minipass-collect": "^1.0.2",
- "minipass-fetch": "^2.0.3",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "negotiator": "^0.6.3",
- "promise-retry": "^2.0.1",
- "socks-proxy-agent": "^7.0.0",
- "ssri": "^9.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "@sinonjs/commons": "^2.0.0",
+ "@sinonjs/fake-timers": "^10.0.2",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
}
},
- "node_modules/node-gyp/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "node_modules/nise/node_modules/@sinonjs/commons": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
+ "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
"dev": true,
"dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
+ "type-detect": "4.0.8"
}
},
- "node_modules/node-gyp/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "node_modules/nise/node_modules/@sinonjs/fake-timers": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
+ "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
"dev": true,
"dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
+ "@sinonjs/commons": "^3.0.0"
}
},
- "node_modules/node-gyp/node_modules/minipass-fetch": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
- "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
+ "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
+ "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
"dev": true,
"dependencies": {
- "minipass": "^3.1.6",
- "minipass-sized": "^1.0.3",
- "minizlib": "^2.1.2"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- },
- "optionalDependencies": {
- "encoding": "^0.1.13"
+ "type-detect": "4.0.8"
}
},
- "node_modules/node-gyp/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "node_modules/nise/node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true
+ },
+ "node_modules/nise/node_modules/path-to-regexp": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz",
+ "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==",
"dev": true,
"dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "isarray": "0.0.1"
}
},
- "node_modules/node-gyp/node_modules/ssri": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
- "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
- "dev": true,
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
- "minipass": "^3.1.1"
+ "whatwg-url": "^5.0.0"
},
"engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
}
},
- "node_modules/node-gyp/node_modules/unique-filename": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
- "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
- "dev": true,
+ "node_modules/node-fetch-h2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz",
+ "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==",
"dependencies": {
- "unique-slug": "^3.0.0"
+ "http2-client": "^1.2.5"
},
"engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "node": "4.x || >=6.0.0"
}
},
- "node_modules/node-gyp/node_modules/unique-slug": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
- "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
- "dev": true,
+ "node_modules/node-fetch/node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/node-fetch/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/node-fetch/node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
- "imurmurhash": "^0.1.4"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
}
},
"node_modules/node-preload": {
@@ -10885,9 +9474,9 @@
"dev": true
},
"node_modules/nodemon": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.3.tgz",
- "integrity": "sha512-m4Vqs+APdKzDFpuaL9F9EVOF85+h070FnkHVEoU4+rmT6Vw0bmNl7s61VEkY/cJkL7RCv1p4urnUDUMrS5rk2w==",
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
+ "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
"dev": true,
"dependencies": {
"chokidar": "^3.5.2",
@@ -10955,48 +9544,6 @@
"node": ">=4"
}
},
- "node_modules/nopt": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
- "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
- "dev": true,
- "dependencies": {
- "abbrev": "^1.0.0"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/normalize-package-data": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz",
- "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==",
- "dev": true,
- "dependencies": {
- "hosted-git-info": "^6.0.0",
- "is-core-module": "^2.8.1",
- "semver": "^7.3.5",
- "validate-npm-package-license": "^3.0.4"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/normalize-package-data/node_modules/hosted-git-info": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz",
- "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^7.5.1"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -11005,211 +9552,18 @@
"node": ">=0.10.0"
}
},
- "node_modules/normalize-url": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz",
- "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm-bundled": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz",
- "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==",
- "dev": true,
- "dependencies": {
- "npm-normalize-package-bin": "^3.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/npm-check-updates": {
- "version": "16.14.20",
- "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-16.14.20.tgz",
- "integrity": "sha512-sYbIhun4DrjO7NFOTdvs11nCar0etEhZTsEjL47eM0TuiGMhmYughRCxG2SpGRmGAQ7AkwN7bw2lWzoE7q6yOQ==",
- "dev": true,
- "dependencies": {
- "@types/semver-utils": "^1.1.1",
- "chalk": "^5.3.0",
- "cli-table3": "^0.6.3",
- "commander": "^10.0.1",
- "fast-memoize": "^2.5.2",
- "find-up": "5.0.0",
- "fp-and-or": "^0.1.4",
- "get-stdin": "^8.0.0",
- "globby": "^11.0.4",
- "hosted-git-info": "^5.1.0",
- "ini": "^4.1.1",
- "js-yaml": "^4.1.0",
- "json-parse-helpfulerror": "^1.0.3",
- "jsonlines": "^0.1.1",
- "lodash": "^4.17.21",
- "make-fetch-happen": "^11.1.1",
- "minimatch": "^9.0.3",
- "p-map": "^4.0.0",
- "pacote": "15.2.0",
- "parse-github-url": "^1.0.2",
- "progress": "^2.0.3",
- "prompts-ncu": "^3.0.0",
- "rc-config-loader": "^4.1.3",
- "remote-git-tags": "^3.0.0",
- "rimraf": "^5.0.5",
- "semver": "^7.5.4",
- "semver-utils": "^1.1.4",
- "source-map-support": "^0.5.21",
- "spawn-please": "^2.0.2",
- "strip-ansi": "^7.1.0",
- "strip-json-comments": "^5.0.1",
- "untildify": "^4.0.0",
- "update-notifier": "^6.0.2"
- },
- "bin": {
- "ncu": "build/src/bin/cli.js",
- "npm-check-updates": "build/src/bin/cli.js"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
- "node_modules/npm-check-updates/node_modules/chalk": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
- "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
- "dev": true,
- "engines": {
- "node": "^12.17.0 || ^14.13 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/npm-check-updates/node_modules/commander": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
- "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
- "dev": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/npm-check-updates/node_modules/strip-json-comments": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz",
- "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm-install-checks": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz",
- "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==",
- "dev": true,
- "dependencies": {
- "semver": "^7.1.1"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm-normalize-package-bin": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
- "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
+ "version": "17.1.11",
+ "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.11.tgz",
+ "integrity": "sha512-TR2RuGIH7P3Qrb0jfdC/nT7JWqXPKjDlxuNQt3kx4oNVf1Pn5SBRB7KLypgYZhruivJthgTtfkkyK4mz342VjA==",
"dev": true,
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm-package-arg": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz",
- "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==",
- "dev": true,
- "dependencies": {
- "hosted-git-info": "^6.0.0",
- "proc-log": "^3.0.0",
- "semver": "^7.3.5",
- "validate-npm-package-name": "^5.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm-package-arg/node_modules/hosted-git-info": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz",
- "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^7.5.1"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm-packlist": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz",
- "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==",
- "dev": true,
- "dependencies": {
- "ignore-walk": "^6.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm-pick-manifest": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz",
- "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==",
- "dev": true,
- "dependencies": {
- "npm-install-checks": "^6.0.0",
- "npm-normalize-package-bin": "^3.0.0",
- "npm-package-arg": "^10.0.0",
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm-registry-fetch": {
- "version": "14.0.5",
- "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz",
- "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==",
- "dev": true,
- "dependencies": {
- "make-fetch-happen": "^11.0.0",
- "minipass": "^5.0.0",
- "minipass-fetch": "^3.0.0",
- "minipass-json-stream": "^1.0.1",
- "minizlib": "^2.1.2",
- "npm-package-arg": "^10.0.0",
- "proc-log": "^3.0.0"
+ "bin": {
+ "ncu": "build/cli.js",
+ "npm-check-updates": "build/cli.js"
},
"engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/npm-registry-fetch/node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
+ "node": "^18.18.0 || >=20.0.0",
+ "npm": ">=8.12.1"
}
},
"node_modules/npm-run-path": {
@@ -11231,21 +9585,6 @@
"node": ">=4"
}
},
- "node_modules/npmlog": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
- "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
- "dev": true,
- "dependencies": {
- "are-we-there-yet": "^3.0.0",
- "console-control-strings": "^1.1.0",
- "gauge": "^4.0.3",
- "set-blocking": "^2.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@@ -11266,9 +9605,9 @@
}
},
"node_modules/nyc": {
- "version": "17.0.0",
- "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.0.0.tgz",
- "integrity": "sha512-ISp44nqNCaPugLLGGfknzQwSwt10SSS5IMoPR7GLoMAyS18Iw5js8U7ga2VF9lYuMZ42gOHr3UddZw4WZltxKg==",
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz",
+ "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==",
"dev": true,
"dependencies": {
"@istanbuljs/load-nyc-config": "^1.0.0",
@@ -11278,7 +9617,7 @@
"decamelize": "^1.2.0",
"find-cache-dir": "^3.2.0",
"find-up": "^4.1.0",
- "foreground-child": "^2.0.0",
+ "foreground-child": "^3.3.0",
"get-package-type": "^0.1.0",
"glob": "^7.1.6",
"istanbul-lib-coverage": "^3.0.0",
@@ -11334,29 +9673,16 @@
"dev": true
},
"node_modules/nyc/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/nyc/node_modules/foreground-child": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
- "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"dependencies": {
- "cross-spawn": "^7.0.0",
- "signal-exit": "^3.0.2"
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
},
"engines": {
- "node": ">=8.0.0"
+ "node": ">=8"
}
},
"node_modules/nyc/node_modules/glob": {
@@ -11442,21 +9768,6 @@
"node": ">=8"
}
},
- "node_modules/nyc/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/nyc/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -11676,13 +9987,13 @@
}
},
"node_modules/object.assign": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
- "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
"has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
},
@@ -11694,28 +10005,29 @@
}
},
"node_modules/object.entries": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz",
- "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==",
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz",
+ "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.fromentries": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz",
- "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -11736,28 +10048,15 @@
"get-intrinsic": "^1.2.1"
}
},
- "node_modules/object.hasown": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz",
- "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==",
- "dev": true,
- "dependencies": {
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/object.values": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz",
- "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+ "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -11807,14 +10106,14 @@
}
},
"node_modules/openapi-backend": {
- "version": "5.10.6",
- "resolved": "https://registry.npmjs.org/openapi-backend/-/openapi-backend-5.10.6.tgz",
- "integrity": "sha512-vTjBRys/O4JIHdlRHUKZ7pxS+gwIJreAAU9dvYRFrImtPzQ5qxm5a6B8BTVT9m6I8RGGsShJv35MAc3Tu2/y/A==",
+ "version": "5.11.1",
+ "resolved": "https://registry.npmjs.org/openapi-backend/-/openapi-backend-5.11.1.tgz",
+ "integrity": "sha512-TsIbku0692sU1X5Ewhzj49ivd8EIT0GDtwbB7XvT234lY3+oJfTe3cUWaBzeKGeX+a1mjcluuJ4V+wTancRbdA==",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^11.1.0",
"ajv": "^8.6.2",
"bath-es5": "^3.0.3",
- "cookie": "^0.5.0",
+ "cookie": "^1.0.1",
"dereference-json-schema": "^0.2.1",
"lodash": "^4.17.15",
"mock-json-schema": "^1.0.7",
@@ -11830,9 +10129,9 @@
}
},
"node_modules/openapi-sampler": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.3.1.tgz",
- "integrity": "sha512-Ert9mvc2tLPmmInwSyGZS+v4Ogu9/YoZuq9oP3EdUklg2cad6+IGndP9yqJJwbgdXwZibiq5fpv6vYujchdJFg==",
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.5.1.tgz",
+ "integrity": "sha512-tIWIrZUKNAsbqf3bd9U1oH6JEXo8LNYuDlXw26By67EygpjT+ArFnsxxyTMjFWRfbqo5ozkvgSQDK69Gd8CddA==",
"dependencies": {
"@types/json-schema": "^7.0.7",
"json-pointer": "0.6.2"
@@ -11904,15 +10203,6 @@
"node": ">= 0.4.0"
}
},
- "node_modules/p-cancelable": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
- "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==",
- "dev": true,
- "engines": {
- "node": ">=12.20"
- }
- },
"node_modules/p-defer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
@@ -11967,21 +10257,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/p-map": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
- "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
- "dev": true,
- "dependencies": {
- "aggregate-error": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -12005,64 +10280,10 @@
"node": ">=8"
}
},
- "node_modules/package-json": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz",
- "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==",
- "dev": true,
- "dependencies": {
- "got": "^12.1.0",
- "registry-auth-token": "^5.0.1",
- "registry-url": "^6.0.0",
- "semver": "^7.3.7"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/pacote": {
- "version": "15.2.0",
- "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz",
- "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==",
- "dev": true,
- "dependencies": {
- "@npmcli/git": "^4.0.0",
- "@npmcli/installed-package-contents": "^2.0.1",
- "@npmcli/promise-spawn": "^6.0.1",
- "@npmcli/run-script": "^6.0.0",
- "cacache": "^17.0.0",
- "fs-minipass": "^3.0.0",
- "minipass": "^5.0.0",
- "npm-package-arg": "^10.0.0",
- "npm-packlist": "^7.0.0",
- "npm-pick-manifest": "^8.0.0",
- "npm-registry-fetch": "^14.0.0",
- "proc-log": "^3.0.0",
- "promise-retry": "^2.0.1",
- "read-package-json": "^6.0.0",
- "read-package-json-fast": "^3.0.0",
- "sigstore": "^1.3.0",
- "ssri": "^10.0.0",
- "tar": "^6.1.11"
- },
- "bin": {
- "pacote": "lib/bin.js"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/pacote/node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
+ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw=="
},
"node_modules/parent-module": {
"version": "2.0.0",
@@ -12075,18 +10296,6 @@
"node": ">=8"
}
},
- "node_modules/parse-github-url": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz",
- "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==",
- "dev": true,
- "bin": {
- "parse-github-url": "cli.js"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
@@ -12142,15 +10351,15 @@
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
- "node_modules/parse5/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "engines": {
- "node": ">=0.12"
+ "node_modules/parse5-parser-stream": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "dependencies": {
+ "parse5": "^7.0.0"
},
"funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parseurl": {
@@ -12208,17 +10417,14 @@
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
- "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
- "engines": {
- "node": "14 || >=16.14"
- }
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
},
"node_modules/path-to-regexp": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
},
"node_modules/path-type": {
"version": "4.0.0",
@@ -12427,10 +10633,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/postcss": {
- "version": "8.4.38",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
- "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "version": "8.4.45",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz",
+ "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==",
"funding": [
{
"type": "opencollective",
@@ -12447,7 +10662,7 @@
],
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
+ "picocolors": "^1.0.1",
"source-map-js": "^1.2.0"
},
"engines": {
@@ -12549,15 +10764,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/proc-log": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz",
- "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==",
- "dev": true,
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -12575,65 +10781,16 @@
"node": ">=8"
}
},
- "node_modules/progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "dev": true,
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/prom-client": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-14.2.0.tgz",
- "integrity": "sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA==",
+ "version": "15.1.3",
+ "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz",
+ "integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==",
"dependencies": {
+ "@opentelemetry/api": "^1.4.0",
"tdigest": "^0.1.1"
},
"engines": {
- "node": ">=10"
- }
- },
- "node_modules/promise-inflight": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
- "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
- "dev": true
- },
- "node_modules/promise-retry": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
- "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
- "dev": true,
- "dependencies": {
- "err-code": "^2.0.2",
- "retry": "^0.12.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/promise-retry/node_modules/retry": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
- "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/prompts-ncu": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/prompts-ncu/-/prompts-ncu-3.0.0.tgz",
- "integrity": "sha512-qyz9UxZ5MlPKWVhWrCmSZ1ahm2GVYdjLb8og2sg0IPth1KRuhcggHGuijz0e41dkx35p1t1q3GRISGH7QGALFA==",
- "dev": true,
- "dependencies": {
- "kleur": "^4.0.1",
- "sisteransi": "^1.0.5"
- },
- "engines": {
- "node": ">= 14"
+ "node": "^16 || ^18 || >=20"
}
},
"node_modules/prop-types": {
@@ -12647,12 +10804,6 @@
"react-is": "^16.13.1"
}
},
- "node_modules/proto-list": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
- "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
- "dev": true
- },
"node_modules/protobufjs": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.0.tgz",
@@ -12747,23 +10898,9 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/pupa": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz",
- "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==",
"dev": true,
- "dependencies": {
- "escape-goat": "^4.0.0"
- },
"engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=6"
}
},
"node_modules/q": {
@@ -12777,9 +10914,9 @@
}
},
"node_modules/qs": {
- "version": "6.12.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz",
- "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==",
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dependencies": {
"side-channel": "^1.0.6"
},
@@ -12832,30 +10969,19 @@
}
},
"node_modules/raw-body": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
- "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
+ "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
+ "iconv-lite": "0.6.3",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/raw-body/node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -12870,18 +10996,6 @@
"rc": "cli.js"
}
},
- "node_modules/rc-config-loader": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/rc-config-loader/-/rc-config-loader-4.1.3.tgz",
- "integrity": "sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==",
- "dev": true,
- "dependencies": {
- "debug": "^4.3.4",
- "js-yaml": "^4.1.0",
- "json5": "^2.2.2",
- "require-from-string": "^2.0.2"
- }
- },
"node_modules/rc/node_modules/ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
@@ -12907,34 +11021,6 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true
},
- "node_modules/read-package-json": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz",
- "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==",
- "dev": true,
- "dependencies": {
- "glob": "^10.2.2",
- "json-parse-even-better-errors": "^3.0.0",
- "normalize-package-data": "^5.0.0",
- "npm-normalize-package-bin": "^3.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/read-package-json-fast": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz",
- "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==",
- "dev": true,
- "dependencies": {
- "json-parse-even-better-errors": "^3.0.0",
- "npm-normalize-package-bin": "^3.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -13164,16 +11250,36 @@
"node": ">=8"
}
},
+ "node_modules/redis-errors": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
+ "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/redis-parser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
+ "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
+ "dependencies": {
+ "redis-errors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/reflect.getprototypeof": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
- "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz",
+ "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.1",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
"globalthis": "^1.0.3",
"which-builtin-type": "^1.1.3"
},
@@ -13193,14 +11299,15 @@
}
},
"node_modules/regexp.prototype.flags": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
- "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
+ "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "set-function-name": "^2.0.0"
+ "call-bind": "^1.0.6",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -13218,34 +11325,7 @@
"node": ">=8"
},
"funding": {
- "url": "https://github.com/sponsors/mysticatea"
- }
- },
- "node_modules/registry-auth-token": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz",
- "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==",
- "dev": true,
- "dependencies": {
- "@pnpm/npm-conf": "^2.1.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/registry-url": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz",
- "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==",
- "dev": true,
- "dependencies": {
- "rc": "1.2.8"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/mysticatea"
}
},
"node_modules/release-zalgo": {
@@ -13260,15 +11340,6 @@
"node": ">=4"
}
},
- "node_modules/remote-git-tags": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz",
- "integrity": "sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
@@ -13642,12 +11713,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/resolve-alpn": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
- "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
- "dev": true
- },
"node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -13656,21 +11721,6 @@
"node": ">=8"
}
},
- "node_modules/responselike": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz",
- "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==",
- "dev": true,
- "dependencies": {
- "lowercase-keys": "^3.0.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/resumer": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
@@ -13710,23 +11760,64 @@
}
},
"node_modules/rimraf": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz",
- "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
"dev": true,
"dependencies": {
- "glob": "^10.3.7"
+ "glob": "^7.1.3"
},
"bin": {
- "rimraf": "dist/esm/bin.mjs"
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rimraf/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
},
"engines": {
- "node": ">=14"
+ "node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/rimraf/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -13750,13 +11841,13 @@
}
},
"node_modules/safe-array-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz",
- "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1",
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
"has-symbols": "^1.0.3",
"isarray": "^2.0.5"
},
@@ -13793,15 +11884,18 @@
]
},
"node_modules/safe-regex-test": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
- "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+ "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
"is-regex": "^1.1.4"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -13832,6 +11926,24 @@
"postcss": "^8.3.11"
}
},
+ "node_modules/sanitize-html/node_modules/htmlparser2": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+ "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "entities": "^4.4.0"
+ }
+ },
"node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@@ -13846,27 +11958,6 @@
"node": ">=10"
}
},
- "node_modules/semver-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz",
- "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==",
- "dev": true,
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/semver-utils": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/semver-utils/-/semver-utils-1.1.4.tgz",
- "integrity": "sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==",
- "dev": true
- },
"node_modules/semver/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -13879,9 +11970,9 @@
}
},
"node_modules/send": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
- "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
@@ -13914,6 +12005,14 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/serialize-error": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz",
@@ -13940,14 +12039,14 @@
}
},
"node_modules/serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
"dependencies": {
- "encodeurl": "~1.0.2",
+ "encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
- "send": "0.18.0"
+ "send": "0.19.0"
},
"engines": {
"node": ">= 0.8.0"
@@ -13975,14 +12074,15 @@
}
},
"node_modules/set-function-name": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
- "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"dev": true,
"dependencies": {
- "define-data-property": "^1.0.1",
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
"functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.0"
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -14056,6 +12156,14 @@
"wordwrap": "0.0.2"
}
},
+ "node_modules/shins/node_modules/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/shins/node_modules/linkify-it": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
@@ -14079,6 +12187,17 @@
"markdown-it": "bin/markdown-it.js"
}
},
+ "node_modules/shins/node_modules/markdown-it-attrs": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-1.2.1.tgz",
+ "integrity": "sha512-EYYKLF9RvQJx1Etsb6EsBGWL7qNQLpg9BRej5f06+UdX75T5gvldEn7ts6bkLIQqugE15SGn4lw1CXDS1A+XUA==",
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "markdown-it": ">=7.0.1"
+ }
+ },
"node_modules/shins/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -14213,25 +12332,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/sigstore": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz",
- "integrity": "sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==",
- "dev": true,
- "dependencies": {
- "@sigstore/bundle": "^1.1.0",
- "@sigstore/protobuf-specs": "^0.2.0",
- "@sigstore/sign": "^1.0.0",
- "@sigstore/tuf": "^1.0.3",
- "make-fetch-happen": "^11.0.1"
- },
- "bin": {
- "sigstore": "bin/sigstore.js"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -14275,12 +12375,6 @@
"url": "https://opencollective.com/sinon"
}
},
- "node_modules/sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "dev": true
- },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -14311,20 +12405,6 @@
"npm": ">= 3.0.0"
}
},
- "node_modules/socks-proxy-agent": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
- "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
- "dev": true,
- "dependencies": {
- "agent-base": "^6.0.2",
- "debug": "^4.3.3",
- "socks": "^2.6.2"
- },
- "engines": {
- "node": ">= 10"
- }
- },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -14334,23 +12414,13 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
- "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "dev": true,
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
"node_modules/sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
@@ -14360,18 +12430,6 @@
"memory-pager": "^1.0.2"
}
},
- "node_modules/spawn-please": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/spawn-please/-/spawn-please-2.0.2.tgz",
- "integrity": "sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^7.0.3"
- },
- "engines": {
- "node": ">=14"
- }
- },
"node_modules/spawn-sync": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz",
@@ -14400,16 +12458,6 @@
"node": ">=8"
}
},
- "node_modules/spawn-wrap/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
"node_modules/spawn-wrap/node_modules/foreground-child": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
@@ -14423,53 +12471,6 @@
"node": ">=8.0.0"
}
},
- "node_modules/spawn-wrap/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/spawn-wrap/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/spawn-wrap/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/spawn-wrap/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -14556,18 +12557,6 @@
"node": ">= 0.6"
}
},
- "node_modules/ssri": {
- "version": "10.0.5",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz",
- "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==",
- "dev": true,
- "dependencies": {
- "minipass": "^7.0.3"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/stack-trace": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
@@ -14577,9 +12566,9 @@
}
},
"node_modules/standard": {
- "version": "17.1.0",
- "resolved": "https://registry.npmjs.org/standard/-/standard-17.1.0.tgz",
- "integrity": "sha512-jaDqlNSzLtWYW4lvQmU0EnxWMUGQiwHasZl5ZEIwx3S/ijZDjZOzs1y1QqKwKs5vqnFpGtizo4NOYX2s0Voq/g==",
+ "version": "17.1.2",
+ "resolved": "https://registry.npmjs.org/standard/-/standard-17.1.2.tgz",
+ "integrity": "sha512-WLm12WoXveKkvnPnPnaFUUHuOB2cUdAsJ4AiGHL2G0UNMrcRAWY2WriQaV8IQ3oRmYr0AWUbLNr94ekYFAHOrA==",
"dev": true,
"funding": [
{
@@ -14595,6 +12584,7 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"eslint": "^8.41.0",
"eslint-config-standard": "17.1.0",
@@ -14602,8 +12592,8 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-promise": "^6.1.1",
- "eslint-plugin-react": "^7.32.2",
- "standard-engine": "^15.0.0",
+ "eslint-plugin-react": "^7.36.1",
+ "standard-engine": "^15.1.0",
"version-guard": "^1.1.1"
},
"bin": {
@@ -14613,6 +12603,11 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/standard-as-callback": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
+ "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
+ },
"node_modules/standard-engine": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-15.1.0.tgz",
@@ -14938,39 +12933,56 @@
"dependencies": {
"ansi-regex": "^5.0.1"
},
- "engines": {
- "node": ">=8"
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz",
+ "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.7",
+ "regexp.prototype.flags": "^1.5.2",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/string.prototype.matchall": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
- "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==",
+ "node_modules/string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "get-intrinsic": "^1.2.1",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.5",
- "regexp.prototype.flags": "^1.5.0",
- "set-function-name": "^2.0.0",
- "side-channel": "^1.0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
}
},
"node_modules/string.prototype.trim": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz",
- "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==",
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+ "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -14980,28 +12992,31 @@
}
},
"node_modules/string.prototype.trimend": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz",
- "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+ "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz",
- "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -15147,9 +13162,9 @@
}
},
"node_modules/swagger-ui-dist": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.3.tgz",
- "integrity": "sha512-/OgHfO96RWXF+p/EOjEnvKNEh94qAG/VHukgmVKh5e6foX9kas1WbjvQnDDj0sSTAMr9MHRBqAWytDcQi0VOrg=="
+ "version": "5.17.14",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz",
+ "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw=="
},
"node_modules/swagger2openapi": {
"version": "7.0.8",
@@ -15572,56 +13587,6 @@
"node": "*"
}
},
- "node_modules/tar": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
- "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
- "dev": true,
- "dependencies": {
- "chownr": "^2.0.0",
- "fs-minipass": "^2.0.0",
- "minipass": "^5.0.0",
- "minizlib": "^2.1.1",
- "mkdirp": "^1.0.3",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tar/node_modules/fs-minipass": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
- "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
- "dev": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tar/node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/tarn": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz",
@@ -15891,20 +13856,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
- "node_modules/tuf-js": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz",
- "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==",
- "dev": true,
- "dependencies": {
- "@tufjs/models": "1.0.4",
- "debug": "^4.3.4",
- "make-fetch-happen": "^11.1.1"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
@@ -15953,29 +13904,30 @@
}
},
"node_modules/typed-array-buffer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
- "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1",
- "is-typed-array": "^1.1.10"
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
- "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+ "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
- "has-proto": "^1.0.1",
- "is-typed-array": "^1.1.10"
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
@@ -15985,16 +13937,17 @@
}
},
"node_modules/typed-array-byte-offset": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
- "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+ "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
"dev": true,
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
- "has-proto": "^1.0.1",
- "is-typed-array": "^1.1.10"
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
},
"engines": {
"node": ">= 0.4"
@@ -16004,14 +13957,20 @@
}
},
"node_modules/typed-array-length": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
- "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+ "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
- "is-typed-array": "^1.1.9"
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -16055,6 +14014,17 @@
"integrity": "sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q==",
"optional": true
},
+ "node_modules/ulidx": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/ulidx/-/ulidx-2.4.1.tgz",
+ "integrity": "sha512-xY7c8LPyzvhvew0Fn+Ek3wBC9STZAuDI/Y5andCKi9AX6/jvfaX45PhsDX8oxgPL0YFp0Jhr8qWMbS/p9375Xg==",
+ "dependencies": {
+ "layerr": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@@ -16082,50 +14052,19 @@
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
"dev": true
},
+ "node_modules/undici": {
+ "version": "6.19.8",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz",
+ "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==",
+ "engines": {
+ "node": ">=18.17"
+ }
+ },
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
- "node_modules/unique-filename": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz",
- "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==",
- "dev": true,
- "dependencies": {
- "unique-slug": "^4.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/unique-slug": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz",
- "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==",
- "dev": true,
- "dependencies": {
- "imurmurhash": "^0.1.4"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/unique-string": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
- "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==",
- "dev": true,
- "dependencies": {
- "crypto-random-string": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -16134,15 +14073,6 @@
"node": ">= 0.8"
}
},
- "node_modules/untildify": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
- "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/update-browserslist-db": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
@@ -16173,58 +14103,6 @@
"browserslist": ">= 4.21.0"
}
},
- "node_modules/update-notifier": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz",
- "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==",
- "dev": true,
- "dependencies": {
- "boxen": "^7.0.0",
- "chalk": "^5.0.1",
- "configstore": "^6.0.0",
- "has-yarn": "^3.0.0",
- "import-lazy": "^4.0.0",
- "is-ci": "^3.0.1",
- "is-installed-globally": "^0.4.0",
- "is-npm": "^6.0.0",
- "is-yarn-global": "^0.4.0",
- "latest-version": "^7.0.0",
- "pupa": "^3.1.0",
- "semver": "^7.3.7",
- "semver-diff": "^4.0.0",
- "xdg-basedir": "^5.1.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/yeoman/update-notifier?sponsor=1"
- }
- },
- "node_modules/update-notifier/node_modules/chalk": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
- "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
- "dev": true,
- "engines": {
- "node": "^12.17.0 || ^14.13 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/update-notifier/node_modules/xdg-basedir": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
- "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -16275,18 +14153,6 @@
"spdx-expression-parse": "^3.0.0"
}
},
- "node_modules/validate-npm-package-name": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz",
- "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==",
- "dev": true,
- "dependencies": {
- "builtins": "^5.0.0"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
"node_modules/validator": {
"version": "13.11.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz",
@@ -16329,6 +14195,25 @@
"node": ">=12"
}
},
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/whatwg-url": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
@@ -16372,13 +14257,13 @@
}
},
"node_modules/which-builtin-type": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz",
- "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz",
+ "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==",
"dev": true,
"dependencies": {
- "function.prototype.name": "^1.1.5",
- "has-tostringtag": "^1.0.0",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
"is-async-function": "^2.0.0",
"is-date-object": "^1.0.5",
"is-finalizationregistry": "^1.0.2",
@@ -16387,8 +14272,8 @@
"is-weakref": "^1.0.2",
"isarray": "^2.0.5",
"which-boxed-primitive": "^1.0.2",
- "which-collection": "^1.0.1",
- "which-typed-array": "^1.1.9"
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.15"
},
"engines": {
"node": ">= 0.4"
@@ -16404,15 +14289,18 @@
"dev": true
},
"node_modules/which-collection": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
- "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
"dependencies": {
- "is-map": "^2.0.1",
- "is-set": "^2.0.1",
- "is-weakmap": "^2.0.1",
- "is-weakset": "^2.0.1"
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -16424,16 +14312,16 @@
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
},
"node_modules/which-typed-array": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
- "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+ "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
"dev": true,
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
- "has-tostringtag": "^1.0.0"
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -16487,6 +14375,14 @@
"wrap-ansi": "^2.0.0"
}
},
+ "node_modules/widdershins/node_modules/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/widdershins/node_modules/find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@@ -16703,62 +14599,6 @@
"decamelize": "^1.2.0"
}
},
- "node_modules/wide-align": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
- "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "dev": true,
- "dependencies": {
- "string-width": "^1.0.2 || 2 || 3 || 4"
- }
- },
- "node_modules/wide-align/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/wide-align/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wide-align/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/widest-line": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
- "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==",
- "dev": true,
- "dependencies": {
- "string-width": "^5.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/window-size": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
@@ -16814,14 +14654,6 @@
"node": ">= 6"
}
},
- "node_modules/winston/node_modules/@colors/colors": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
- "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
- "engines": {
- "node": ">=0.1.90"
- }
- },
"node_modules/winston/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -16995,9 +14827,9 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yaml": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz",
- "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==",
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz",
+ "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==",
"bin": {
"yaml": "bin.mjs"
},
@@ -17026,7 +14858,6 @@
"version": "20.2.9",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "dev": true,
"engines": {
"node": ">=10"
}
diff --git a/package.json b/package.json
index 0eeb773eb..673c9de19 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@mojaloop/central-ledger",
- "version": "17.7.8",
+ "version": "17.8.0-snapshot.34",
"description": "Central ledger hosted by a scheme to record and settle transfers",
"license": "Apache-2.0",
"author": "ModusBox",
@@ -31,13 +31,15 @@
"pre-commit": [
"lint",
"dep:check",
+ "audit:check",
"test"
],
"scripts": {
"start": "npm run start:api",
"start:api": "node src/api/index.js",
- "watch:api": "npx nodemon src/api/index.js",
"start:handlers": "node src/handlers/index.js",
+ "start:debug": "npm start --node-options --inspect=0.0.0.0",
+ "watch:api": "npx nodemon src/api/index.js",
"dev": "npm run docker:stop && docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --build -d",
"lint": "npx standard",
"lint:fix": "npx standard --fix",
@@ -50,10 +52,10 @@
"test:int": "npx tape 'test/integration/**/*.test.js' ",
"test:int-override": "npx tape 'test/integration-override/**/*.test.js'",
"test:int:spec": "npm run test:int | npx tap-spec",
- "test:xint": "npm run test:int | tap-xunit > ./test/results/xunit-integration.xml",
- "test:xint-override": "npm run test:int-override | tap-xunit > ./test/results/xunit-integration-override.xml",
- "test:integration": "sh ./test/scripts/test-integration.sh",
- "test:functional": "sh ./test/scripts/test-functional.sh",
+ "test:xint": "npm run test:int | tee /dev/tty | tap-xunit > ./test/results/xunit-integration.xml",
+ "test:xint-override": "npm run test:int-override | tee /dev/tty | tap-xunit > ./test/results/xunit-integration-override.xml",
+ "test:integration": "./test/scripts/test-integration.sh",
+ "test:functional": "./test/scripts/test-functional.sh",
"migrate": "npm run migrate:latest && npm run seed:run",
"migrate:latest": "npx knex $npm_package_config_knex migrate:latest",
"migrate:create": "npx knex migrate:make $npm_package_config_knex",
@@ -61,7 +63,7 @@
"migrate:current": "npx knex migrate:currentVersion $npm_package_config_knex",
"seed:run": "npx knex seed:run $npm_package_config_knex",
"docker:build": "docker build --build-arg NODE_VERSION=\"$(cat .nvmrc)-alpine\" -t mojaloop/central-ledger:local .",
- "docker:up": "docker-compose -f docker-compose.yml up",
+ "docker:up": ". ./docker/env.sh && docker-compose -f docker-compose.yml up -d",
"docker:up:backend": "docker-compose up -d ml-api-adapter mysql mockserver kafka kowl temp_curl",
"docker:up:int": "docker compose up -d kafka init-kafka objstore mysql",
"docker:script:populateTestData": "sh ./test/util/scripts/populateTestData.sh",
@@ -79,42 +81,45 @@
"wait-4-docker": "node ./scripts/_wait4_all.js"
},
"dependencies": {
- "@hapi/good": "9.0.1",
- "@hapi/hapi": "21.3.10",
"@hapi/basic": "7.0.2",
+ "@hapi/catbox-memory": "6.0.2",
+ "@hapi/good": "9.0.1",
+ "@hapi/hapi": "21.3.12",
"@hapi/inert": "7.1.0",
"@hapi/joi": "17.1.1",
"@hapi/vision": "7.0.3",
- "@hapi/catbox-memory": "6.0.2",
- "@mojaloop/database-lib": "11.0.5",
- "@mojaloop/central-services-error-handling": "13.0.1",
+ "@mojaloop/central-services-error-handling": "13.0.2",
"@mojaloop/central-services-health": "15.0.0",
- "@mojaloop/central-services-logger": "11.3.1",
- "@mojaloop/central-services-metrics": "12.0.8",
- "@mojaloop/central-services-shared": "18.3.8",
- "@mojaloop/central-services-stream": "11.3.1",
+ "@mojaloop/central-services-logger": "11.5.1",
+ "@mojaloop/central-services-metrics": "12.4.2",
+ "@mojaloop/central-services-shared": "18.14.1",
+ "@mojaloop/central-services-stream": "11.4.1",
+ "@mojaloop/database-lib": "11.0.6",
"@mojaloop/event-sdk": "14.1.1",
+ "@mojaloop/inter-scheme-proxy-cache-lib": "2.3.1",
"@mojaloop/ml-number": "11.2.4",
"@mojaloop/object-store-lib": "12.0.3",
"@now-ims/hapi-now-auth": "2.1.0",
- "ajv": "8.16.0",
+ "ajv": "8.17.1",
"ajv-keywords": "5.1.0",
"base64url": "3.0.1",
"blipp": "4.0.2",
"commander": "12.1.0",
- "cron": "3.1.7",
+ "cron": "3.3.1",
"decimal.js": "10.4.3",
"docdash": "2.0.2",
"event-stream": "4.0.1",
"five-bells-condition": "5.0.1",
- "glob": "10.4.1",
+ "glob": "10.4.3",
+ "hapi-auth-basic": "5.0.0",
"hapi-auth-bearer-token": "8.0.0",
- "hapi-swagger": "17.2.1",
+ "hapi-swagger": "17.3.2",
"ilp-packet": "2.2.0",
"knex": "3.1.0",
"lodash": "4.17.21",
"moment": "2.30.1",
"mongo-uri-builder": "^4.0.0",
+ "parse-strings-in-object": "2.0.0",
"rc": "1.2.8",
"require-glob": "^4.1.0"
},
@@ -122,19 +127,21 @@
"mysql": "2.18.1"
},
"devDependencies": {
+ "@types/mock-knex": "0.4.8",
"async-retry": "1.3.3",
- "audit-ci": "^7.0.1",
+ "audit-ci": "^7.1.0",
"get-port": "5.1.1",
- "jsdoc": "4.0.3",
+ "jsdoc": "4.0.4",
"jsonpath": "1.1.1",
- "nodemon": "3.1.3",
- "npm-check-updates": "16.14.20",
- "nyc": "17.0.0",
+ "mock-knex": "0.4.13",
+ "nodemon": "3.1.9",
+ "npm-check-updates": "17.1.11",
+ "nyc": "17.1.0",
"pre-commit": "1.2.2",
"proxyquire": "2.1.3",
"replace": "^1.2.2",
"sinon": "17.0.0",
- "standard": "17.1.0",
+ "standard": "17.1.2",
"standard-version": "^9.5.0",
"tap-spec": "^5.0.0",
"tap-xunit": "2.4.1",
diff --git a/seeds/endpointType.js b/seeds/endpointType.js
index 6ac12d99c..96ea38060 100644
--- a/seeds/endpointType.js
+++ b/seeds/endpointType.js
@@ -25,6 +25,8 @@
'use strict'
+const { FspEndpointTypes } = require('@mojaloop/central-services-shared').Enum.EndPoints
+
const endpointTypes = [
{
name: 'ALARM_NOTIFICATION_URL',
@@ -46,6 +48,22 @@ const endpointTypes = [
name: 'FSPIOP_CALLBACK_URL_TRANSFER_ERROR',
description: 'Participant callback URL to which transfer error notifications can be sent'
},
+ {
+ name: FspEndpointTypes.FSPIOP_CALLBACK_URL_FX_QUOTES,
+ description: 'Participant callback URL to which FX quote requests can be sent'
+ },
+ {
+ name: FspEndpointTypes.FSPIOP_CALLBACK_URL_FX_TRANSFER_POST,
+ description: 'Participant callback URL to which FX transfer post can be sent'
+ },
+ {
+ name: FspEndpointTypes.FSPIOP_CALLBACK_URL_FX_TRANSFER_PUT,
+ description: 'Participant callback URL to which FX transfer put can be sent'
+ },
+ {
+ name: FspEndpointTypes.FSPIOP_CALLBACK_URL_FX_TRANSFER_ERROR,
+ description: 'Participant callback URL to which FX transfer error notifications can be sent'
+ },
{
name: 'NET_DEBIT_CAP_THRESHOLD_BREACH_EMAIL',
description: 'Participant/Hub operator email address to which the net debit cap breach e-mail notification can be sent'
diff --git a/seeds/fxParticipantCurrencyType.js b/seeds/fxParticipantCurrencyType.js
new file mode 100644
index 000000000..ae4c8557c
--- /dev/null
+++ b/seeds/fxParticipantCurrencyType.js
@@ -0,0 +1,45 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+const fxParticipantCurrencyTypes = [
+ {
+ name: 'SOURCE',
+ description: 'The participant currency is the source of the currency conversion'
+ },
+ {
+ name: 'TARGET',
+ description: 'The participant currency is the target of the currency conversion'
+ }
+]
+
+exports.seed = async function (knex) {
+ try {
+ return await knex('fxParticipantCurrencyType').insert(fxParticipantCurrencyTypes).onConflict('name').ignore()
+ } catch (err) {
+ console.log(`Uploading seeds for fxParticipantCurrencyType has failed with the following error: ${err}`)
+ return -1000
+ }
+}
diff --git a/seeds/fxTransferType.js b/seeds/fxTransferType.js
new file mode 100644
index 000000000..47d7625bb
--- /dev/null
+++ b/seeds/fxTransferType.js
@@ -0,0 +1,45 @@
+/*****
+ License
+ --------------
+ Copyright © 2017 Bill & Melinda Gates Foundation
+ The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Gates Foundation organization for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+const fxTransferTypes = [
+ {
+ name: 'PAYER_CONVERSION',
+ description: 'Payer side currency conversion'
+ },
+ {
+ name: 'PAYEE_CONVERSION',
+ description: 'Payee side currency conversion'
+ }
+]
+
+exports.seed = async function (knex) {
+ try {
+ return await knex('fxTransferType').insert(fxTransferTypes).onConflict('name').ignore()
+ } catch (err) {
+ console.log(`Uploading seeds for fxTransferType has failed with the following error: ${err}`)
+ return -1000
+ }
+}
diff --git a/seeds/participant.js b/seeds/participant.js
index 2eff87278..19885f24d 100644
--- a/seeds/participant.js
+++ b/seeds/participant.js
@@ -28,6 +28,7 @@ const Config = require('../src/lib/config')
const participant = [
{
+ participantId: Config.HUB_ID,
name: Config.HUB_NAME,
description: 'Hub Operator',
createdBy: 'seeds'
@@ -36,7 +37,7 @@ const participant = [
exports.seed = async function (knex) {
try {
- return await knex('participant').insert(participant).onConflict('name').ignore()
+ return await knex('participant').insert(participant).onConflict('id').merge()
} catch (err) {
console.log(`Uploading seeds for participant has failed with the following error: ${err}`)
return -1000
diff --git a/seeds/transferParticipantRoleType.js b/seeds/transferParticipantRoleType.js
index 296493bc5..c260f0240 100644
--- a/seeds/transferParticipantRoleType.js
+++ b/seeds/transferParticipantRoleType.js
@@ -20,6 +20,7 @@
* Georgi Georgiev
* Shashikant Hirugade
+ * Vijay Kumar Guthi
--------------
******/
@@ -45,6 +46,14 @@ const transferParticipantRoleTypes = [
{
name: 'DFSP_POSITION',
description: 'Indicates the position account'
+ },
+ {
+ name: 'INITIATING_FSP',
+ description: 'Identifier for the FSP who is requesting a currency conversion'
+ },
+ {
+ name: 'COUNTER_PARTY_FSP',
+ description: 'Identifier for the FXP who is performing the currency conversion'
}
]
diff --git a/seeds/transferState.js b/seeds/transferState.js
index 8736b6c6c..4135ae33b 100644
--- a/seeds/transferState.js
+++ b/seeds/transferState.js
@@ -41,6 +41,11 @@ const transferStates = [
enumeration: 'RESERVED',
description: 'The switch has reserved the transfer, and has been assigned to a settlement window.'
},
+ {
+ transferStateId: 'RECEIVED_FULFIL_DEPENDENT',
+ enumeration: 'RESERVED',
+ description: 'The switch has reserved the fxTransfer fulfilment.'
+ },
{
transferStateId: 'COMMITTED',
enumeration: 'COMMITTED',
@@ -95,6 +100,11 @@ const transferStates = [
transferStateId: 'SETTLED',
enumeration: 'SETTLED',
description: 'The switch has settled the transfer.'
+ },
+ {
+ transferStateId: 'RESERVED_FORWARDED',
+ enumeration: 'RESERVED',
+ description: 'The switch has forwarded the transfer to a proxy participant'
}
]
diff --git a/src/api/interface/swagger.json b/src/api/interface/swagger.json
index cb4616082..aadb3ee69 100644
--- a/src/api/interface/swagger.json
+++ b/src/api/interface/swagger.json
@@ -66,6 +66,25 @@
"tags": [
"participants"
],
+ "parameters": [
+ {
+ "type": ["string", "boolean", "integer", "null"],
+ "enum": [
+ false,
+ "0",
+ "false",
+ "",
+ true,
+ "1",
+ "true",
+ null
+ ],
+ "description": "Filter by if participant is a proxy",
+ "name": "isProxy",
+ "in": "query",
+ "required": false
+ }
+ ],
"responses": {
"default": {
"schema": {
@@ -375,9 +394,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -404,9 +420,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -442,9 +455,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -663,9 +673,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -701,9 +708,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -917,9 +921,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -979,9 +980,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -1017,9 +1015,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -1062,9 +1057,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -1109,9 +1101,6 @@
"description": "Name of the participant",
"minLength": 2,
"maxLength": 30,
- "x-format": {
- "alphanum": true
- },
"name": "name",
"in": "path",
"required": true
@@ -1326,6 +1315,10 @@
"description": "Currency code",
"$ref" : "#/definitions/Currency"
+ },
+ "isProxy": {
+ "type": "boolean",
+ "description": "Is the participant a proxy"
}
},
"required": [
diff --git a/src/api/ledgerAccountTypes/handler.js b/src/api/ledgerAccountTypes/handler.js
index ef0d6fca2..6b7277863 100644
--- a/src/api/ledgerAccountTypes/handler.js
+++ b/src/api/ledgerAccountTypes/handler.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
diff --git a/src/api/ledgerAccountTypes/routes.js b/src/api/ledgerAccountTypes/routes.js
index 2ac6074eb..9d9b95f74 100644
--- a/src/api/ledgerAccountTypes/routes.js
+++ b/src/api/ledgerAccountTypes/routes.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
diff --git a/src/api/metrics/handler.js b/src/api/metrics/handler.js
index cf11c3f4d..5e6c7105a 100644
--- a/src/api/metrics/handler.js
+++ b/src/api/metrics/handler.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
diff --git a/src/api/metrics/plugin.js b/src/api/metrics/plugin.js
index 08f264dbe..4e60b97e3 100644
--- a/src/api/metrics/plugin.js
+++ b/src/api/metrics/plugin.js
@@ -1,8 +1,8 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
@@ -15,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
diff --git a/src/api/metrics/routes.js b/src/api/metrics/routes.js
index 861e09f29..11e6c0bd4 100644
--- a/src/api/metrics/routes.js
+++ b/src/api/metrics/routes.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
diff --git a/src/api/participants/handler.js b/src/api/participants/handler.js
index ad79e5ee2..72c8b79da 100644
--- a/src/api/participants/handler.js
+++ b/src/api/participants/handler.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
@@ -38,7 +42,7 @@ const LocalEnum = {
disabled: 'disabled'
}
-const entityItem = ({ name, createdDate, isActive, currencyList }, ledgerAccountIds) => {
+const entityItem = ({ name, createdDate, isActive, currencyList, isProxy }, ledgerAccountIds) => {
const link = UrlParser.toParticipantUri(name)
const accounts = currencyList.map((currentValue) => {
return {
@@ -58,7 +62,8 @@ const entityItem = ({ name, createdDate, isActive, currencyList }, ledgerAccount
links: {
self: link
},
- accounts
+ accounts,
+ isProxy
}
}
@@ -160,6 +165,9 @@ const getAll = async function (request) {
const results = await ParticipantService.getAll()
const ledgerAccountTypes = await Enums.getEnums('ledgerAccountType')
const ledgerAccountIds = Util.transpose(ledgerAccountTypes)
+ if (request.query.isProxy) {
+ return results.map(record => entityItem(record, ledgerAccountIds)).filter(record => record.isProxy)
+ }
return results.map(record => entityItem(record, ledgerAccountIds))
}
diff --git a/src/api/participants/routes.js b/src/api/participants/routes.js
index 868b29769..9bce3187e 100644
--- a/src/api/participants/routes.js
+++ b/src/api/participants/routes.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
@@ -29,7 +33,7 @@ const Joi = require('joi')
const currencyList = require('../../../seeds/currency.js').currencyList
const tags = ['api', 'participants']
-const nameValidator = Joi.string().alphanum().min(2).max(30).required().description('Name of the participant')
+const nameValidator = Joi.string().min(2).max(30).required().description('Name of the participant')
const currencyValidator = Joi.string().valid(...currencyList).description('Currency code')
module.exports = [
@@ -49,7 +53,7 @@ module.exports = [
tags,
validate: {
params: Joi.object({
- name: Joi.string().required().description('Participant name')
+ name: nameValidator
})
}
}
@@ -68,7 +72,8 @@ module.exports = [
payload: Joi.object({
name: nameValidator,
// password: passwordValidator,
- currency: currencyValidator // ,
+ currency: currencyValidator,
+ isProxy: Joi.boolean().falsy(0, '0', '').truthy(1, '1').allow(true, false, 0, 1, '0', '1', null)
// emailAddress: Joi.string().email().required()
})
}
@@ -89,7 +94,7 @@ module.exports = [
isActive: Joi.boolean().required().description('Participant isActive boolean')
}),
params: Joi.object({
- name: Joi.string().required().description('Participant name')
+ name: nameValidator
})
}
}
@@ -239,7 +244,7 @@ module.exports = [
type: Joi.string().required().description('Account type') // Needs a validator here
}),
params: Joi.object({
- name: Joi.string().required().description('Participant name') // nameValidator
+ name: nameValidator // nameValidator
})
}
}
@@ -306,7 +311,7 @@ module.exports = [
description: 'Record Funds In or Out of participant account',
validate: {
payload: Joi.object({
- transferId: Joi.string().guid().required(),
+ transferId: Joi.string().pattern(/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]}$|^[0-9A-HJKMNP-TV-Z]{26}$6})$/).required(),
externalReference: Joi.string().required(),
action: Joi.string().required().valid('recordFundsIn', 'recordFundsOutPrepareReserve').label('action is missing or not supported'),
reason: Joi.string().required(),
@@ -344,7 +349,7 @@ module.exports = [
params: Joi.object({
name: nameValidator,
id: Joi.number().integer().positive(),
- transferId: Joi.string().guid().required()
+ transferId: Joi.string().pattern(/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]}$|^[0-9A-HJKMNP-TV-Z]{26}$6})$/).required()
})
}
}
diff --git a/src/api/root/handler.js b/src/api/root/handler.js
index 17cdc6d67..c7de5483a 100644
--- a/src/api/root/handler.js
+++ b/src/api/root/handler.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
@@ -30,13 +34,23 @@ const { defaultHealthHandler } = require('@mojaloop/central-services-health')
const packageJson = require('../../../package.json')
const {
getSubServiceHealthDatastore,
- getSubServiceHealthBroker
+ getSubServiceHealthBroker,
+ getSubServiceHealthProxyCache
} = require('../../lib/healthCheck/subServiceHealth')
+const Config = require('../../lib/config')
-const healthCheck = new HealthCheck(packageJson, [
- getSubServiceHealthDatastore,
- getSubServiceHealthBroker
-])
+const subServiceChecks = Config.PROXY_CACHE_CONFIG?.enabled
+ ? [
+ getSubServiceHealthDatastore,
+ getSubServiceHealthBroker,
+ getSubServiceHealthProxyCache
+ ]
+ : [
+ getSubServiceHealthDatastore,
+ getSubServiceHealthBroker
+ ]
+
+const healthCheck = new HealthCheck(packageJson, subServiceChecks)
/**
* @function getHealth
diff --git a/src/api/root/routes.js b/src/api/root/routes.js
index 4278fbd39..34e39b72b 100644
--- a/src/api/root/routes.js
+++ b/src/api/root/routes.js
@@ -1,8 +1,8 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
@@ -15,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
diff --git a/src/api/settlementModels/handler.js b/src/api/settlementModels/handler.js
index 22cc958c5..869aaa2a3 100644
--- a/src/api/settlementModels/handler.js
+++ b/src/api/settlementModels/handler.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,9 +15,10 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
+
* Gates Foundation
- Name Surname
diff --git a/src/api/settlementModels/routes.js b/src/api/settlementModels/routes.js
index 89cf7f2f9..65e4b526f 100644
--- a/src/api/settlementModels/routes.js
+++ b/src/api/settlementModels/routes.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
* Gates Foundation
diff --git a/src/api/transactions/handler.js b/src/api/transactions/handler.js
index b65e172ca..75d95de42 100644
--- a/src/api/transactions/handler.js
+++ b/src/api/transactions/handler.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
* Gates Foundation
diff --git a/src/api/transactions/routes.js b/src/api/transactions/routes.js
index a26c01b67..0712f4595 100644
--- a/src/api/transactions/routes.js
+++ b/src/api/transactions/routes.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
* Gates Foundation
diff --git a/src/domain/bulkTransfer/index.js b/src/domain/bulkTransfer/index.js
index b46c76f65..6456673ff 100644
--- a/src/domain/bulkTransfer/index.js
+++ b/src/domain/bulkTransfer/index.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
* Gates Foundation
diff --git a/src/domain/fx/cyril.js b/src/domain/fx/cyril.js
new file mode 100644
index 000000000..e797c2100
--- /dev/null
+++ b/src/domain/fx/cyril.js
@@ -0,0 +1,462 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+ * Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+const Metrics = require('@mojaloop/central-services-metrics')
+const { Enum } = require('@mojaloop/central-services-shared')
+const TransferModel = require('../../models/transfer/transfer')
+const TransferFacade = require('../../models/transfer/facade')
+const ParticipantPositionChangesModel = require('../../models/position/participantPositionChanges')
+const { fxTransfer, watchList } = require('../../models/fxTransfer')
+const Config = require('../../lib/config')
+const ProxyCache = require('../../lib/proxyCache')
+
+const checkIfDeterminingTransferExistsForTransferMessage = async (payload, proxyObligation) => {
+ // Does this determining transfer ID appear on the watch list?
+ const watchListRecords = await watchList.getItemsInWatchListByDeterminingTransferId(payload.transferId)
+ const determiningTransferExistsInWatchList = (watchListRecords !== null && watchListRecords.length > 0)
+ // Create a list of participants and currencies to validate against
+ const participantCurrencyValidationList = []
+ if (determiningTransferExistsInWatchList) {
+ // If there's a currency conversion before the transfer is requested, it must be the debtor who did it.
+ if (!proxyObligation.isCounterPartyFspProxy) {
+ participantCurrencyValidationList.push({
+ participantName: payload.payeeFsp,
+ currencyId: payload.amount.currency
+ })
+ }
+ } else {
+ // Normal transfer request or payee side currency conversion
+ if (!proxyObligation.isInitiatingFspProxy) {
+ participantCurrencyValidationList.push({
+ participantName: payload.payerFsp,
+ currencyId: payload.amount.currency
+ })
+ }
+ // If it is a normal transfer, we need to validate payeeFsp against the currency of the transfer.
+ // But its tricky to differentiate between normal transfer and payee side currency conversion.
+ if (Config.PAYEE_PARTICIPANT_CURRENCY_VALIDATION_ENABLED) {
+ if (!proxyObligation.isCounterPartyFspProxy) {
+ participantCurrencyValidationList.push({
+ participantName: payload.payeeFsp,
+ currencyId: payload.amount.currency
+ })
+ }
+ }
+ }
+ return {
+ determiningTransferExistsInWatchList,
+ watchListRecords,
+ participantCurrencyValidationList
+ }
+}
+
+const checkIfDeterminingTransferExistsForFxTransferMessage = async (payload, proxyObligation) => {
+ // Does this determining transfer ID appear on the transfer list?
+ const transferRecord = await TransferModel.getById(payload.determiningTransferId)
+ const determiningTransferExistsInTransferList = (transferRecord !== null)
+ // We need to validate counterPartyFsp (FXP) against both source and target currencies anyway
+ const participantCurrencyValidationList = [
+ {
+ participantName: payload.counterPartyFsp,
+ currencyId: payload.sourceAmount.currency
+ }
+ ]
+ // If a proxy is representing a FXP in a jurisdictional scenario,
+ // they would not hold a position account for the `targetAmount` currency
+ // for a /fxTransfer. So we skip adding this to accounts to be validated.
+ if (!proxyObligation.isCounterPartyFspProxy) {
+ participantCurrencyValidationList.push({
+ participantName: payload.counterPartyFsp,
+ currencyId: payload.targetAmount.currency
+ })
+ }
+ if (determiningTransferExistsInTransferList) {
+ // If there's a currency conversion which is not the first message, then it must be issued by the creditor party
+ participantCurrencyValidationList.push({
+ participantName: payload.initiatingFsp,
+ currencyId: payload.targetAmount.currency
+ })
+ } else {
+ // If there's a currency conversion before the transfer is requested, then it must be issued by the debtor party
+ participantCurrencyValidationList.push({
+ participantName: payload.initiatingFsp,
+ currencyId: payload.sourceAmount.currency
+ })
+ }
+ return {
+ determiningTransferExistsInTransferList,
+ transferRecord,
+ participantCurrencyValidationList
+ }
+}
+
+const getParticipantAndCurrencyForTransferMessage = async (payload, determiningTransferCheckResult, proxyObligation) => {
+ const histTimer = Metrics.getHistogram(
+ 'fx_domain_cyril_getParticipantAndCurrencyForTransferMessage',
+ 'fx_domain_cyril_getParticipantAndCurrencyForTransferMessage - Metrics for fx cyril',
+ ['success', 'determiningTransferExists']
+ ).startTimer()
+
+ let participantName, currencyId, amount
+
+ if (determiningTransferCheckResult.determiningTransferExistsInWatchList) {
+ // If there's a currency conversion before the transfer is requested, it must be the debtor who did it.
+ // Get the FX request corresponding to this transaction ID
+ let fxTransferRecord
+ if (proxyObligation.isCounterPartyFspProxy) {
+ // If a proxy is representing a FXP in a jurisdictional scenario,
+ // they would not hold a position account for the `targetAmount` currency
+ // for a /fxTransfer. So we skip adding this to accounts to be validated.
+ fxTransferRecord = await fxTransfer.getAllDetailsByCommitRequestIdForProxiedFxTransfer(determiningTransferCheckResult.watchListRecords[0].commitRequestId)
+ } else {
+ fxTransferRecord = await fxTransfer.getAllDetailsByCommitRequestId(determiningTransferCheckResult.watchListRecords[0].commitRequestId)
+ }
+
+ // Liquidity check and reserve funds against FXP in FX target currency
+ participantName = fxTransferRecord.counterPartyFspName
+ currencyId = fxTransferRecord.targetCurrency
+ amount = fxTransferRecord.targetAmount
+ } else {
+ // Normal transfer request or payee side currency conversion
+ // Liquidity check and reserve against payer
+ participantName = payload.payerFsp
+ currencyId = payload.amount.currency
+ amount = payload.amount.amount
+ }
+
+ histTimer({ success: true, determiningTransferExists: determiningTransferCheckResult.determiningTransferExistsInWatchList })
+ return {
+ participantName,
+ currencyId,
+ amount
+ }
+}
+
+const getParticipantAndCurrencyForFxTransferMessage = async (payload, determiningTransferCheckResult) => {
+ const histTimer = Metrics.getHistogram(
+ 'fx_domain_cyril_getParticipantAndCurrencyForFxTransferMessage',
+ 'fx_domain_cyril_getParticipantAndCurrencyForFxTransferMessage - Metrics for fx cyril',
+ ['success', 'determiningTransferExists']
+ ).startTimer()
+
+ let participantName, currencyId, amount
+
+ if (determiningTransferCheckResult.determiningTransferExistsInTransferList) {
+ // If there's a currency conversion which is not the first message, then it must be issued by the creditor party
+ // Liquidity check and reserve funds against FXP in FX target currency
+ participantName = payload.counterPartyFsp
+ currencyId = payload.targetAmount.currency
+ amount = payload.targetAmount.amount
+ await watchList.addToWatchList({
+ commitRequestId: payload.commitRequestId,
+ determiningTransferId: payload.determiningTransferId,
+ fxTransferTypeId: Enum.Fx.FxTransferType.PAYEE_CONVERSION
+ })
+ } else {
+ // If there's a currency conversion before the transfer is requested, then it must be issued by the debtor party
+ // Liquidity check and reserve funds against requester in FX source currency
+ participantName = payload.initiatingFsp
+ currencyId = payload.sourceAmount.currency
+ amount = payload.sourceAmount.amount
+ await watchList.addToWatchList({
+ commitRequestId: payload.commitRequestId,
+ determiningTransferId: payload.determiningTransferId,
+ fxTransferTypeId: Enum.Fx.FxTransferType.PAYER_CONVERSION
+ })
+ }
+
+ histTimer({ success: true, determiningTransferExists: determiningTransferCheckResult.determiningTransferExistsInTransferList })
+ return {
+ participantName,
+ currencyId,
+ amount
+ }
+}
+
+const processFxFulfilMessage = async (commitRequestId) => {
+ const histTimer = Metrics.getHistogram(
+ 'fx_domain_cyril_processFxFulfilMessage',
+ 'fx_domain_cyril_processFxFulfilMessage - Metrics for fx cyril',
+ ['success']
+ ).startTimer()
+ // Does this commitRequestId appear on the watch list?
+ const watchListRecord = await watchList.getItemInWatchListByCommitRequestId(commitRequestId)
+ if (!watchListRecord) {
+ throw new Error(`Commit request ID ${commitRequestId} not found in watch list`)
+ }
+
+ histTimer({ success: true })
+ return true
+}
+
+/**
+ * @typedef {Object} PositionChangeItem
+ *
+ * @property {boolean} isFxTransferStateChange - Indicates whether the position change is related to an FX transfer.
+ * @property {string} [commitRequestId] - commitRequestId for the position change (only for FX transfers).
+ * @property {string} [transferId] - transferId for the position change (only for normal transfers).
+ * @property {string} notifyTo - The FSP to notify about the position change.
+ * @property {number} participantCurrencyId - The ID of the participant's currency involved in the position change.
+ * @property {number} amount - The amount of the position change, represented as a negative value.
+ */
+/**
+ * Retrieves position changes based on a list of commitRequestIds and transferIds.
+ *
+ * @param {Array} commitRequestIdList - List of commit request IDs to retrieve FX-related position changes.
+ * @param {Array} transferIdList - List of transfer IDs to retrieve regular transfer-related position changes.
+ * @returns {Promise} - A promise that resolves to an array of position change objects.
+ */
+const _getPositionChanges = async (commitRequestIdList, transferIdList) => {
+ const positionChanges = []
+ for (const commitRequestId of commitRequestIdList) {
+ const fxRecord = await fxTransfer.getAllDetailsByCommitRequestIdForProxiedFxTransfer(commitRequestId)
+ const fxPositionChanges = await ParticipantPositionChangesModel.getReservedPositionChangesByCommitRequestId(commitRequestId)
+ fxPositionChanges.forEach((fxPositionChange) => {
+ positionChanges.push({
+ isFxTransferStateChange: true,
+ commitRequestId,
+ notifyTo: fxRecord.externalInitiatingFspName || fxRecord.initiatingFspName,
+ participantCurrencyId: fxPositionChange.participantCurrencyId,
+ amount: -fxPositionChange.change
+ })
+ })
+ }
+
+ for (const transferId of transferIdList) {
+ const transferRecord = await TransferFacade.getById(transferId)
+ const transferPositionChanges = await ParticipantPositionChangesModel.getReservedPositionChangesByTransferId(transferId)
+ transferPositionChanges.forEach((transferPositionChange) => {
+ positionChanges.push({
+ isFxTransferStateChange: false,
+ transferId,
+ notifyTo: transferRecord.externalPayerName || transferRecord.payerFsp,
+ participantCurrencyId: transferPositionChange.participantCurrencyId,
+ amount: -transferPositionChange.change
+ })
+ })
+ }
+
+ return positionChanges
+}
+
+/**
+ * @returns {Promise<{positionChanges: PositionChangeItem[]}>}
+ */
+const processFxAbortMessage = async (commitRequestId) => {
+ const histTimer = Metrics.getHistogram(
+ 'fx_domain_cyril_processFxAbortMessage',
+ 'fx_domain_cyril_processFxAbortMessage - Metrics for fx cyril',
+ ['success']
+ ).startTimer()
+
+ // Get the fxTransfer record
+ const fxTransferRecord = await fxTransfer.getByCommitRequestId(commitRequestId)
+ // const fxTransferRecord = await fxTransfer.getAllDetailsByCommitRequestId(commitRequestId)
+ // In case of reference currency, there might be multiple fxTransfers associated with a transfer.
+ const relatedFxTransferRecords = await fxTransfer.getByDeterminingTransferId(fxTransferRecord.determiningTransferId)
+
+ // Get position changes
+ const positionChanges = await _getPositionChanges(relatedFxTransferRecords.map(item => item.commitRequestId), [fxTransferRecord.determiningTransferId])
+
+ histTimer({ success: true })
+ return {
+ positionChanges
+ }
+}
+
+const processAbortMessage = async (transferId) => {
+ const histTimer = Metrics.getHistogram(
+ 'fx_domain_cyril_processAbortMessage',
+ 'fx_domain_cyril_processAbortMessage - Metrics for fx cyril',
+ ['success']
+ ).startTimer()
+
+ // Get all related fxTransfers
+ const relatedFxTransferRecords = await fxTransfer.getByDeterminingTransferId(transferId)
+
+ // Get position changes
+ const positionChanges = await _getPositionChanges(relatedFxTransferRecords.map(item => item.commitRequestId), [transferId])
+
+ histTimer({ success: true })
+ return {
+ positionChanges
+ }
+}
+
+const processFulfilMessage = async (transferId, payload, transfer) => {
+ const histTimer = Metrics.getHistogram(
+ 'fx_domain_cyril_processFulfilMessage',
+ 'fx_domain_cyril_processFulfilMessage - Metrics for fx cyril',
+ ['success']
+ ).startTimer()
+ // Let's define a format for the function result
+ const result = {
+ isFx: false,
+ positionChanges: [],
+ patchNotifications: []
+ }
+
+ // Does this transferId appear on the watch list?
+ const watchListRecords = await watchList.getItemsInWatchListByDeterminingTransferId(transferId)
+ if (watchListRecords && watchListRecords.length > 0) {
+ result.isFx = true
+
+ // Loop around watch list
+ let sendingFxpExists = false
+ let receivingFxpExists = false
+ let sendingFxpRecord = null
+ let receivingFxpRecord = null
+ for (const watchListRecord of watchListRecords) {
+ const fxTransferRecord = await fxTransfer.getAllDetailsByCommitRequestIdForProxiedFxTransfer(watchListRecord.commitRequestId)
+ // Original Plan: If the reservation is against the FXP, then this is a conversion at the creditor. Mark FXP as receiving FXP
+ // The above condition is not required as we are setting the fxTransferType in the watchList beforehand
+ if (watchListRecord.fxTransferTypeId === Enum.Fx.FxTransferType.PAYEE_CONVERSION) {
+ receivingFxpExists = true
+ receivingFxpRecord = fxTransferRecord
+ // Create obligation between FXP and FX requesting party in currency of reservation
+ // Find out the participantCurrencyId of the initiatingFsp
+ // The following is hardcoded for Payer side conversion with SEND amountType.
+ const proxyParticipantAccountDetails = await ProxyCache.getProxyParticipantAccountDetails(fxTransferRecord.initiatingFspName, fxTransferRecord.targetCurrency)
+ if (proxyParticipantAccountDetails.participantCurrencyId) {
+ result.positionChanges.push({
+ isFxTransferStateChange: false,
+ transferId,
+ participantCurrencyId: proxyParticipantAccountDetails.participantCurrencyId,
+ amount: -fxTransferRecord.targetAmount
+ })
+ }
+ }
+
+ // Original Plan: If the reservation is against the DFSP, then this is a conversion at the debtor. Mark FXP as sending FXP
+ // The above condition is not required as we are setting the fxTransferType in the watchList beforehand
+ if (watchListRecord.fxTransferTypeId === Enum.Fx.FxTransferType.PAYER_CONVERSION) {
+ sendingFxpExists = true
+ sendingFxpRecord = fxTransferRecord
+ // Create obligation between FX requesting party and FXP in currency of reservation
+ const proxyParticipantAccountDetails = await ProxyCache.getProxyParticipantAccountDetails(fxTransferRecord.counterPartyFspName, fxTransferRecord.sourceCurrency)
+ if (proxyParticipantAccountDetails.participantCurrencyId) {
+ result.positionChanges.push({
+ isFxTransferStateChange: true,
+ commitRequestId: fxTransferRecord.commitRequestId,
+ participantCurrencyId: proxyParticipantAccountDetails.participantCurrencyId,
+ amount: -fxTransferRecord.sourceAmount
+ })
+ }
+ result.patchNotifications.push({
+ commitRequestId: watchListRecord.commitRequestId,
+ fxpName: fxTransferRecord.counterPartyFspName,
+ fulfilment: fxTransferRecord.fulfilment,
+ completedTimestamp: fxTransferRecord.completedTimestamp
+ })
+ }
+ }
+
+ if (!sendingFxpExists && !receivingFxpExists) {
+ // If there are no sending and receiving fxp, throw an error
+ throw new Error(`Required records not found in watch list for transfer ID ${transferId}`)
+ }
+
+ if (sendingFxpExists && receivingFxpExists) {
+ // If we have both a sending and a receiving FXP, Create obligation between sending and receiving FXP in currency of transfer.
+ const proxyParticipantAccountDetails = await ProxyCache.getProxyParticipantAccountDetails(receivingFxpRecord.counterPartyFspName, receivingFxpRecord.sourceCurrency)
+ if (proxyParticipantAccountDetails.participantCurrencyId) {
+ result.positionChanges.push({
+ isFxTransferStateChange: true,
+ commitRequestId: receivingFxpRecord.commitRequestId,
+ participantCurrencyId: proxyParticipantAccountDetails.participantCurrencyId,
+ amount: -receivingFxpRecord.sourceAmount
+ })
+ }
+ } else if (sendingFxpExists) {
+ // If we have a sending FXP, Create obligation between FXP and creditor party to the transfer in currency of FX transfer
+ // Get participantCurrencyId for transfer.payeeParticipantId/transfer.payeeFsp and sendingFxpRecord.targetCurrency
+ const proxyParticipantAccountDetails = await ProxyCache.getProxyParticipantAccountDetails(transfer.payeeFsp, sendingFxpRecord.targetCurrency)
+ if (proxyParticipantAccountDetails.participantCurrencyId) {
+ let isPositionChange = false
+ if (proxyParticipantAccountDetails.inScheme) {
+ isPositionChange = true
+ } else {
+ // We are not expecting this. Payee participant is a proxy and have an account in the targetCurrency.
+ // In this case we need to check if FXP is also a proxy and have the same account as payee.
+ const proxyParticipantAccountDetails2 = await ProxyCache.getProxyParticipantAccountDetails(sendingFxpRecord.counterPartyFspName, sendingFxpRecord.targetCurrency)
+ if (!proxyParticipantAccountDetails2.inScheme && (proxyParticipantAccountDetails.participantCurrencyId !== proxyParticipantAccountDetails2.participantCurrencyId)) {
+ isPositionChange = true
+ }
+ }
+ if (isPositionChange) {
+ result.positionChanges.push({
+ isFxTransferStateChange: false,
+ transferId,
+ participantCurrencyId: proxyParticipantAccountDetails.participantCurrencyId,
+ amount: -sendingFxpRecord.targetAmount
+ })
+ }
+ }
+ } else if (receivingFxpExists) {
+ // If we have a receiving FXP, Create obligation between debtor party to the transfer and FXP in currency of transfer
+ const proxyParticipantAccountDetails = await ProxyCache.getProxyParticipantAccountDetails(receivingFxpRecord.counterPartyFspName, receivingFxpRecord.sourceCurrency)
+ if (proxyParticipantAccountDetails.participantCurrencyId) {
+ let isPositionChange = false
+ if (proxyParticipantAccountDetails.inScheme) {
+ isPositionChange = true
+ } else {
+ // We are not expecting this. FXP participant is a proxy and have an account in the sourceCurrency.
+ // In this case we need to check if Payer is also a proxy and have the same account as FXP.
+ const proxyParticipantAccountDetails2 = await ProxyCache.getProxyParticipantAccountDetails(transfer.payerFsp, receivingFxpRecord.sourceCurrency)
+ if (!proxyParticipantAccountDetails2.inScheme && (proxyParticipantAccountDetails.participantCurrencyId !== proxyParticipantAccountDetails2.participantCurrencyId)) {
+ isPositionChange = true
+ }
+ }
+ if (isPositionChange) {
+ result.positionChanges.push({
+ isFxTransferStateChange: true,
+ commitRequestId: receivingFxpRecord.commitRequestId,
+ participantCurrencyId: proxyParticipantAccountDetails.participantCurrencyId,
+ amount: -receivingFxpRecord.sourceAmount
+ })
+ }
+ }
+ }
+ } else {
+ // Normal transfer request, just return isFx = false
+ }
+
+ histTimer({ success: true })
+ return result
+}
+
+module.exports = {
+ getParticipantAndCurrencyForTransferMessage,
+ getParticipantAndCurrencyForFxTransferMessage,
+ processFxFulfilMessage,
+ processFxAbortMessage,
+ processFulfilMessage,
+ processAbortMessage,
+ checkIfDeterminingTransferExistsForTransferMessage,
+ checkIfDeterminingTransferExistsForFxTransferMessage
+}
diff --git a/src/domain/fx/index.js b/src/domain/fx/index.js
new file mode 100644
index 000000000..e94626711
--- /dev/null
+++ b/src/domain/fx/index.js
@@ -0,0 +1,81 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+ * Gates Foundation
+ - Name Surname
+
+ * Vijay Kumar Guthi
+ --------------
+ ******/
+
+'use strict'
+
+/**
+ * @module src/domain/transfer/
+ */
+
+const ErrorHandler = require('@mojaloop/central-services-error-handling')
+const Metrics = require('@mojaloop/central-services-metrics')
+const FxTransferModel = require('../../models/fxTransfer')
+// const TransferObjectTransform = require('./transform')
+const Cyril = require('./cyril')
+
+const handleFulfilResponse = async (transferId, payload, action, fspiopError) => {
+ const histTimerTransferServiceHandlePayeeResponseEnd = Metrics.getHistogram(
+ 'fx_domain_transfer',
+ 'prepare - Metrics for fx transfer domain',
+ ['success', 'funcName']
+ ).startTimer()
+
+ try {
+ await FxTransferModel.fxTransfer.saveFxFulfilResponse(transferId, payload, action, fspiopError)
+ const result = {}
+ histTimerTransferServiceHandlePayeeResponseEnd({ success: true, funcName: 'handleFulfilResponse' })
+ return result
+ } catch (err) {
+ histTimerTransferServiceHandlePayeeResponseEnd({ success: false, funcName: 'handleFulfilResponse' })
+ throw ErrorHandler.Factory.reformatFSPIOPError(err)
+ }
+}
+
+const forwardedFxPrepare = async (commitRequestId) => {
+ const histTimerTransferServicePrepareEnd = Metrics.getHistogram(
+ 'fx_domain_transfer',
+ 'prepare - Metrics for fx transfer domain',
+ ['success', 'funcName']
+ ).startTimer()
+ try {
+ const result = await FxTransferModel.fxTransfer.updateFxPrepareReservedForwarded(commitRequestId)
+ histTimerTransferServicePrepareEnd({ success: true, funcName: 'forwardedFxPrepare' })
+ return result
+ } catch (err) {
+ histTimerTransferServicePrepareEnd({ success: false, funcName: 'forwardedFxPrepare' })
+ throw ErrorHandler.Factory.reformatFSPIOPError(err)
+ }
+}
+
+const TransferService = {
+ handleFulfilResponse,
+ forwardedFxPrepare,
+ getByIdLight: FxTransferModel.fxTransfer.getByIdLight,
+ Cyril
+}
+
+module.exports = TransferService
diff --git a/src/domain/ledgerAccountTypes/index.js b/src/domain/ledgerAccountTypes/index.js
index 2535fafc5..3ad90c1c6 100644
--- a/src/domain/ledgerAccountTypes/index.js
+++ b/src/domain/ledgerAccountTypes/index.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
* Gates Foundation
diff --git a/src/domain/participant/index.js b/src/domain/participant/index.js
index bbeb0cd39..e975f3027 100644
--- a/src/domain/participant/index.js
+++ b/src/domain/participant/index.js
@@ -1,10 +1,13 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
http://www.apache.org/licenses/LICENSE-2.0
+
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
@@ -12,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
* Gates Foundation
@@ -42,6 +45,7 @@ const KafkaProducer = require('@mojaloop/central-services-stream').Util.Producer
const { randomUUID } = require('crypto')
const Enum = require('@mojaloop/central-services-shared').Enum
const Enums = require('../../lib/enumCached')
+const { logger } = require('../../shared/logger')
// Alphabetically ordered list of error texts used below
const AccountInactiveErrorText = 'Account is currently set inactive'
@@ -58,9 +62,12 @@ const ErrorHandler = require('@mojaloop/central-services-error-handling')
const { destroyParticipantEndpointByParticipantId } = require('../../models/participant/participant')
const create = async (payload) => {
+ const log = logger.child({ payload })
try {
- return ParticipantModel.create({ name: payload.name })
+ log.info('creating participant with payload')
+ return ParticipantModel.create({ name: payload.name, isProxy: !!payload.isProxy })
} catch (err) {
+ log.error('error creating participant', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -71,13 +78,16 @@ const getAll = async () => {
await Promise.all(all.map(async (participant) => {
participant.currencyList = await ParticipantCurrencyModel.getByParticipantId(participant.participantId)
}))
+ logger.debug('getAll participants', { participants: all })
return all
} catch (err) {
+ logger.error('error getting all participants', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const getById = async (id) => {
+ logger.debug('getting participant by id', { id })
const participant = await ParticipantModel.getById(id)
if (participant) {
participant.currencyList = await ParticipantCurrencyModel.getByParticipantId(participant.participantId)
@@ -86,6 +96,7 @@ const getById = async (id) => {
}
const getByName = async (name) => {
+ logger.debug('getting participant by name', { name })
const participant = await ParticipantModel.getByName(name)
if (participant) {
participant.currencyList = await ParticipantCurrencyModel.getByParticipantId(participant.participantId)
@@ -94,17 +105,23 @@ const getByName = async (name) => {
}
const participantExists = (participant, checkIsActive = false) => {
+ const log = logger.child({ participant, checkIsActive })
+ log.debug('checking if participant exists')
if (participant) {
if (!checkIsActive || participant.isActive) {
return participant
}
+ log.warn('participant is inactive')
throw ErrorHandler.Factory.createInternalServerFSPIOPError(ParticipantInactiveText)
}
+ log.warn('participant not found')
throw ErrorHandler.Factory.createInternalServerFSPIOPError(ParticipantNotFoundText)
}
const update = async (name, payload) => {
+ const log = logger.child({ name, payload })
try {
+ log.info('updating participant')
const participant = await ParticipantModel.getByName(name)
participantExists(participant)
await ParticipantModel.update(participant, payload.isActive)
@@ -112,38 +129,50 @@ const update = async (name, payload) => {
participant.currencyList = await ParticipantCurrencyModel.getByParticipantId(participant.participantId)
return participant
} catch (err) {
+ log.error('error updating participant', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const createParticipantCurrency = async (participantId, currencyId, ledgerAccountTypeId, isActive = true) => {
+ const log = logger.child({ participantId, currencyId, ledgerAccountTypeId, isActive })
try {
+ log.info('creating participant currency')
const participantCurrency = await ParticipantCurrencyModel.create(participantId, currencyId, ledgerAccountTypeId, isActive)
return participantCurrency
} catch (err) {
+ log.error('error creating participant currency', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const createHubAccount = async (participantId, currencyId, ledgerAccountTypeId) => {
+ const log = logger.child({ participantId, currencyId, ledgerAccountTypeId })
try {
+ log.info('creating hub account')
const participantCurrency = await ParticipantFacade.addHubAccountAndInitPosition(participantId, currencyId, ledgerAccountTypeId)
return participantCurrency
} catch (err) {
+ log.error('error creating hub account', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const getParticipantCurrencyById = async (participantCurrencyId) => {
+ const log = logger.child({ participantCurrencyId })
try {
+ log.debug('getting participant currency by id')
return await ParticipantCurrencyModel.getById(participantCurrencyId)
} catch (err) {
+ log.error('error getting participant currency by id', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const destroyByName = async (name) => {
+ const log = logger.child({ name })
try {
+ log.debug('destroying participant by name')
const participant = await ParticipantModel.getByName(name)
await ParticipantLimitModel.destroyByParticipantId(participant.participantId)
await ParticipantPositionModel.destroyByParticipantId(participant.participantId)
@@ -151,6 +180,7 @@ const destroyByName = async (name) => {
await destroyParticipantEndpointByParticipantId(participant.participantId)
return await ParticipantModel.destroyByName(name)
} catch (err) {
+ log.error('error destroying participant by name', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -174,11 +204,15 @@ const destroyByName = async (name) => {
*/
const addEndpoint = async (name, payload) => {
+ const log = logger.child({ name, payload })
try {
+ log.info('adding endpoint')
const participant = await ParticipantModel.getByName(name)
participantExists(participant)
+ log.info('adding endpoint for participant', { participant })
return ParticipantFacade.addEndpoint(participant.participantId, payload)
} catch (err) {
+ log.error('error adding endpoint', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -199,11 +233,15 @@ const addEndpoint = async (name, payload) => {
*/
const getEndpoint = async (name, type) => {
+ const log = logger.child({ name, type })
try {
+ log.debug('getting endpoint')
const participant = await ParticipantModel.getByName(name)
participantExists(participant)
+ log.debug('getting endpoint for participant', { participant })
return ParticipantFacade.getEndpoint(participant.participantId, type)
} catch (err) {
+ log.error('error getting endpoint', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -223,11 +261,15 @@ const getEndpoint = async (name, type) => {
*/
const getAllEndpoints = async (name) => {
+ const log = logger.child({ name })
try {
+ log.debug('getting all endpoints for participant name')
const participant = await ParticipantModel.getByName(name)
participantExists(participant)
+ log.debug('getting all endpoints for participant', { participant })
return ParticipantFacade.getAllEndpoints(participant.participantId)
} catch (err) {
+ log.error('error getting all endpoints', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -245,11 +287,15 @@ const getAllEndpoints = async (name) => {
*/
const destroyParticipantEndpointByName = async (name) => {
+ const log = logger.child({ name })
try {
+ log.debug('destroying participant endpoint by name')
const participant = await ParticipantModel.getByName(name)
participantExists(participant)
+ log.debug('destroying participant endpoint for participant', { participant })
return ParticipantModel.destroyParticipantEndpointByParticipantId(participant.participantId)
} catch (err) {
+ log.error('error destroying participant endpoint by name', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -278,14 +324,18 @@ const destroyParticipantEndpointByName = async (name) => {
*/
const addLimitAndInitialPosition = async (participantName, limitAndInitialPositionObj) => {
+ const log = logger.child({ participantName, limitAndInitialPositionObj })
try {
+ log.debug('adding limit and initial position', { participantName, limitAndInitialPositionObj })
const participant = await ParticipantFacade.getByNameAndCurrency(participantName, limitAndInitialPositionObj.currency, Enum.Accounts.LedgerAccountType.POSITION)
participantExists(participant)
+ log.debug('adding limit and initial position for participant', { participant })
const settlementAccount = await ParticipantFacade.getByNameAndCurrency(participantName, limitAndInitialPositionObj.currency, Enum.Accounts.LedgerAccountType.SETTLEMENT)
const existingLimit = await ParticipantLimitModel.getByParticipantCurrencyId(participant.participantCurrencyId)
const existingPosition = await ParticipantPositionModel.getByParticipantCurrencyId(participant.participantCurrencyId)
const existingSettlementPosition = await ParticipantPositionModel.getByParticipantCurrencyId(settlementAccount.participantCurrencyId)
if (existingLimit || existingPosition || existingSettlementPosition) {
+ log.warn('participant limit or initial position already set')
throw ErrorHandler.Factory.createInternalServerFSPIOPError(ParticipantInitialPositionExistsText)
}
const limitAndInitialPosition = Object.assign({}, limitAndInitialPositionObj, { name: participantName })
@@ -296,6 +346,7 @@ const addLimitAndInitialPosition = async (participantName, limitAndInitialPositi
await Kafka.produceGeneralMessage(Config.KAFKA_CONFIG, KafkaProducer, Enum.Events.Event.Type.NOTIFICATION, Enum.Transfers.AdminNotificationActions.LIMIT_ADJUSTMENT, createLimitAdjustmentMessageProtocol(payload), Enum.Events.EventStatus.SUCCESS)
return ParticipantFacade.addLimitAndInitialPosition(participant.participantCurrencyId, settlementAccount.participantCurrencyId, limitAndInitialPosition, true)
} catch (err) {
+ log.error('error adding limit and initial position', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -313,9 +364,12 @@ const addLimitAndInitialPosition = async (participantName, limitAndInitialPositi
*/
const getPositionByParticipantCurrencyId = async (participantCurrencyId) => {
+ const log = logger.child({ participantCurrencyId })
try {
+ log.debug('getting position by participant currency id')
return ParticipantPositionModel.getByParticipantCurrencyId(participantCurrencyId)
} catch (err) {
+ log.error('error getting position by participant currency id', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -333,9 +387,12 @@ const getPositionByParticipantCurrencyId = async (participantCurrencyId) => {
*/
const getPositionChangeByParticipantPositionId = async (participantPositionId) => {
+ const log = logger.child({ participantPositionId })
try {
+ log.debug('getting position change by participant position id')
return ParticipantPositionChangeModel.getByParticipantPositionId(participantPositionId)
} catch (err) {
+ log.error('error getting position change by participant position id', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -353,11 +410,15 @@ const getPositionChangeByParticipantPositionId = async (participantPositionId) =
*/
const destroyParticipantPositionByNameAndCurrency = async (name, currencyId) => {
+ const log = logger.child({ name, currencyId })
try {
+ log.debug('destroying participant position by participant name and currency')
const participant = await ParticipantFacade.getByNameAndCurrency(name, currencyId, Enum.Accounts.LedgerAccountType.POSITION)
+ log.debug('destroying participant position for participant', { participant })
participantExists(participant)
return ParticipantPositionModel.destroyByParticipantCurrencyId(participant.participantCurrencyId)
} catch (err) {
+ log.error('error destroying participant position by name and currency', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -376,11 +437,15 @@ const destroyParticipantPositionByNameAndCurrency = async (name, currencyId) =>
*/
const destroyParticipantLimitByNameAndCurrency = async (name, currencyId) => {
+ const log = logger.child({ name, currencyId })
try {
+ log.debug('destroying participant limit by participant name and currency')
const participant = await ParticipantFacade.getByNameAndCurrency(name, currencyId, Enum.Accounts.LedgerAccountType.POSITION)
+ log.debug('destroying participant limit for participant', { participant })
participantExists(participant)
return ParticipantLimitModel.destroyByParticipantCurrencyId(participant.participantCurrencyId)
} catch (err) {
+ log.error('error destroying participant limit by name and currency', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -403,18 +468,24 @@ const destroyParticipantLimitByNameAndCurrency = async (name, currencyId) => {
*/
const getLimits = async (name, { currency = null, type = null }) => {
+ const log = logger.child({ name, currency, type })
try {
let participant
if (currency != null) {
+ log.debug('getting limits by name and currency')
participant = await ParticipantFacade.getByNameAndCurrency(name, currency, Enum.Accounts.LedgerAccountType.POSITION)
+ log.debug('getting limits for participant', { participant })
participantExists(participant)
return ParticipantFacade.getParticipantLimitsByCurrencyId(participant.participantCurrencyId, type)
} else {
+ log.debug('getting limits by name')
participant = await ParticipantModel.getByName(name)
+ log.debug('getting limits for participant', { participant })
participantExists(participant)
return ParticipantFacade.getParticipantLimitsByParticipantId(participant.participantId, type, Enum.Accounts.LedgerAccountType.POSITION)
}
} catch (err) {
+ log.error('error getting limits', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -434,9 +505,12 @@ const getLimits = async (name, { currency = null, type = null }) => {
*/
const getLimitsForAllParticipants = async ({ currency = null, type = null }) => {
+ const log = logger.child({ currency, type })
try {
+ log.debug('getting limits for all participants', { currency, type })
return ParticipantFacade.getLimitsForAllParticipants(currency, type, Enum.Accounts.LedgerAccountType.POSITION)
} catch (err) {
+ log.error('error getting limits for all participants', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -465,15 +539,19 @@ const getLimitsForAllParticipants = async ({ currency = null, type = null }) =>
*/
const adjustLimits = async (name, payload) => {
+ const log = logger.child({ name, payload })
try {
+ log.debug('adjusting limits')
const { limit, currency } = payload
const participant = await ParticipantFacade.getByNameAndCurrency(name, currency, Enum.Accounts.LedgerAccountType.POSITION)
+ log.debug('adjusting limits for participant', { participant })
participantExists(participant)
const result = await ParticipantFacade.adjustLimits(participant.participantCurrencyId, limit)
payload.name = name
await Kafka.produceGeneralMessage(Config.KAFKA_CONFIG, KafkaProducer, Enum.Events.Event.Type.NOTIFICATION, Enum.Transfers.AdminNotificationActions.LIMIT_ADJUSTMENT, createLimitAdjustmentMessageProtocol(payload), Enum.Events.EventStatus.SUCCESS)
return result
} catch (err) {
+ log.error('error adjusting limits', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -546,9 +624,12 @@ const createLimitAdjustmentMessageProtocol = (payload, action = Enum.Transfers.A
*/
const getPositions = async (name, query) => {
+ const log = logger.child({ name, query })
try {
+ log.debug('getting positions')
if (query.currency) {
const participant = await ParticipantFacade.getByNameAndCurrency(name, query.currency, Enum.Accounts.LedgerAccountType.POSITION)
+ log.debug('getting positions for participant', { participant })
participantExists(participant)
const result = await PositionFacade.getByNameAndCurrency(name, Enum.Accounts.LedgerAccountType.POSITION, query.currency) // TODO this function only takes a max of 3 params, this has 4
let position = {}
@@ -559,9 +640,11 @@ const getPositions = async (name, query) => {
changedDate: result[0].changedDate
}
}
+ log.debug('found positions for participant', { participant, position })
return position
} else {
const participant = await ParticipantModel.getByName(name)
+ log.debug('getting positions for participant', { participant })
participantExists(participant)
const result = await await PositionFacade.getByNameAndCurrency(name, Enum.Accounts.LedgerAccountType.POSITION)
const positions = []
@@ -574,16 +657,21 @@ const getPositions = async (name, query) => {
})
})
}
+ log.debug('found positions for participant', { participant, positions })
return positions
}
} catch (err) {
+ log.error('error getting positions', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const getAccounts = async (name, query) => {
+ const log = logger.child({ name, query })
try {
+ log.debug('getting accounts')
const participant = await ParticipantModel.getByName(name)
+ log.debug('getting accounts for participant', { participant })
participantExists(participant)
const result = await PositionFacade.getAllByNameAndCurrency(name, query.currency)
const positions = []
@@ -600,18 +688,24 @@ const getAccounts = async (name, query) => {
})
})
}
+ log.debug('found accounts for participant', { participant, positions })
return positions
} catch (err) {
+ log.error('error getting accounts', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const updateAccount = async (payload, params, enums) => {
+ const log = logger.child({ payload, params, enums })
try {
+ log.debug('updating account')
const { name, id } = params
const participant = await ParticipantModel.getByName(name)
+ log.debug('updating account for participant', { participant })
participantExists(participant)
const account = await ParticipantCurrencyModel.getById(id)
+ log.debug('updating account for participant', { participant, account })
if (!account) {
throw ErrorHandler.Factory.createInternalServerFSPIOPError(AccountNotFoundErrorText)
} else if (account.participantId !== participant.participantId) {
@@ -621,22 +715,29 @@ const updateAccount = async (payload, params, enums) => {
}
return await ParticipantCurrencyModel.update(id, payload.isActive)
} catch (err) {
+ log.error('error updating account', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const getLedgerAccountTypeName = async (name) => {
+ const log = logger.child({ name })
try {
+ log.debug('getting ledger account type by name')
return await LedgerAccountTypeModel.getLedgerAccountByName(name)
} catch (err) {
+ log.error('error getting ledger account type by name', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
const getParticipantAccount = async (accountParams) => {
+ const log = logger.child({ accountParams })
try {
+ log.debug('getting participant account by params')
return await ParticipantCurrencyModel.findOneByParams(accountParams)
} catch (err) {
+ log.error('error getting participant account by params', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -690,7 +791,9 @@ const setPayerPayeeFundsInOut = (fspName, payload, enums) => {
}
const recordFundsInOut = async (payload, params, enums) => {
+ const log = logger.child({ payload, params, enums })
try {
+ log.debug('recording funds in/out')
const { name, id, transferId } = params
const participant = await ParticipantModel.getByName(name)
const currency = (payload.amount && payload.amount.currency) || null
@@ -699,6 +802,7 @@ const recordFundsInOut = async (payload, params, enums) => {
participantExists(participant, checkIsActive)
const accounts = await ParticipantFacade.getAllAccountsByNameAndCurrency(name, currency, isAccountActive)
const accountMatched = accounts[accounts.map(account => account.participantCurrencyId).findIndex(i => i === id)]
+ log.debug('recording funds in/out for participant account', { participant, accountMatched })
if (!accountMatched) {
throw ErrorHandler.Factory.createInternalServerFSPIOPError(ParticipantAccountCurrencyMismatchText)
} else if (!accountMatched.accountIsActive) {
@@ -714,6 +818,7 @@ const recordFundsInOut = async (payload, params, enums) => {
}
return await Kafka.produceGeneralMessage(Config.KAFKA_CONFIG, KafkaProducer, Enum.Events.Event.Type.ADMIN, Enum.Events.Event.Action.TRANSFER, messageProtocol, Enum.Events.EventStatus.SUCCESS)
} catch (err) {
+ log.error('error recording funds in/out', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
@@ -722,17 +827,21 @@ const validateHubAccounts = async (currency) => {
const ledgerAccountTypes = await Enums.getEnums('ledgerAccountType')
const hubReconciliationAccountExists = await ParticipantCurrencyModel.hubAccountExists(currency, ledgerAccountTypes.HUB_RECONCILIATION)
if (!hubReconciliationAccountExists) {
+ logger.error('Hub reconciliation account for the specified currency does not exist')
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, 'Hub reconciliation account for the specified currency does not exist')
}
const hubMlnsAccountExists = await ParticipantCurrencyModel.hubAccountExists(currency, ledgerAccountTypes.HUB_MULTILATERAL_SETTLEMENT)
if (!hubMlnsAccountExists) {
+ logger.error('Hub multilateral net settlement account for the specified currency does not exist')
throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.ADD_PARTY_INFO_ERROR, 'Hub multilateral net settlement account for the specified currency does not exist')
}
return true
}
const createAssociatedParticipantAccounts = async (currency, ledgerAccountTypeId, trx) => {
+ const log = logger.child({ currency, ledgerAccountTypeId })
try {
+ log.info('creating associated participant accounts')
const nonHubParticipantWithCurrencies = await ParticipantFacade.getAllNonHubParticipantsWithCurrencies(trx)
const participantCurrencies = nonHubParticipantWithCurrencies.map(item => ({
@@ -760,6 +869,7 @@ const createAssociatedParticipantAccounts = async (currency, ledgerAccountTypeId
}
await ParticipantPositionModel.createParticipantPositionRecords(participantPositionRecords, trx)
} catch (err) {
+ log.error('error creating associated participant accounts', err)
throw ErrorHandler.Factory.reformatFSPIOPError(err)
}
}
diff --git a/src/domain/position/abort.js b/src/domain/position/abort.js
new file mode 100644
index 000000000..9489a4f67
--- /dev/null
+++ b/src/domain/position/abort.js
@@ -0,0 +1,249 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+const { Enum } = require('@mojaloop/central-services-shared')
+const ErrorHandler = require('@mojaloop/central-services-error-handling')
+const Config = require('../../lib/config')
+const Utility = require('@mojaloop/central-services-shared').Util
+const MLNumber = require('@mojaloop/ml-number')
+const Logger = require('@mojaloop/central-services-logger')
+
+/**
+ * @function processPositionAbortBin
+ *
+ * @async
+ * @description This is the domain function to process a bin of abort / fx-abort messages of a single participant account.
+ *
+ * @param {array} abortBins - an array containing abort / fx-abort action bins
+ * @param {object} options
+ * @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
+ * @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
+ * @param {object} accumulatedTransferStates - object with transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
+ * @param {object} transferInfoList - object with transfer id keys and transfer info values. Used to pass transfer info to domain function.
+ * @param {boolean} changePositions - whether to change positions or not
+ * @returns {object} - Returns an object containing accumulatedPositionValue, accumulatedPositionReservedValue, accumulatedTransferStateChanges, accumulatedTransferStates, resultMessages, limitAlarms or throws an error if failed
+ */
+const processPositionAbortBin = async (
+ abortBins,
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedTransferStates,
+ accumulatedFxTransferStates,
+ isFx,
+ changePositions = true
+ }
+) => {
+ const transferStateChanges = []
+ const participantPositionChanges = []
+ const resultMessages = []
+ const followupMessages = []
+ const fxTransferStateChanges = []
+ const accumulatedTransferStatesCopy = Object.assign({}, accumulatedTransferStates)
+ const accumulatedFxTransferStatesCopy = Object.assign({}, accumulatedFxTransferStates)
+ let runningPosition = new MLNumber(accumulatedPositionValue)
+
+ if (abortBins && abortBins.length > 0) {
+ for (const binItem of abortBins) {
+ Logger.isDebugEnabled && Logger.debug(`processPositionAbortBin::binItem: ${JSON.stringify(binItem.message.value)}`)
+ if (isFx) {
+ // If the transfer is not in `RECEIVED_ERROR`, a position fx-abort message was incorrectly published.
+ // i.e Something has gone extremely wrong.
+ if (accumulatedFxTransferStates[binItem.message.value.content.uriParams.id] !== Enum.Transfers.TransferInternalState.RECEIVED_ERROR) {
+ throw ErrorHandler.Factory.createInternalServerFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR.message)
+ }
+ } else {
+ // If the transfer is not in `RECEIVED_ERROR`, a position abort message was incorrectly published.
+ // i.e Something has gone extremely wrong.
+ if (accumulatedTransferStates[binItem.message.value.content.uriParams.id] !== Enum.Transfers.TransferInternalState.RECEIVED_ERROR) {
+ throw ErrorHandler.Factory.createInternalServerFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR.message)
+ }
+ }
+
+ const cyrilResult = binItem.message.value.content.context?.cyrilResult
+ if (!cyrilResult || !cyrilResult.positionChanges || cyrilResult.positionChanges.length === 0) {
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR)
+ }
+
+ // Handle position movements
+ // Iterate through positionChanges and handle each position movement, mark as done and publish a position-commit kafka message again for the next item
+ // Find out the first item to be processed
+ const positionChangeIndex = cyrilResult.positionChanges.findIndex(positionChange => !positionChange.isDone)
+ const positionChangeToBeProcessed = cyrilResult.positionChanges[positionChangeIndex]
+ if (positionChangeToBeProcessed.isFxTransferStateChange) {
+ const { participantPositionChange, fxTransferStateChange, transferStateId, updatedRunningPosition } =
+ _handleParticipantPositionChangeFx(runningPosition, positionChangeToBeProcessed.amount, positionChangeToBeProcessed.commitRequestId, accumulatedPositionReservedValue)
+ runningPosition = updatedRunningPosition
+ participantPositionChanges.push(participantPositionChange)
+ fxTransferStateChanges.push(fxTransferStateChange)
+ accumulatedFxTransferStatesCopy[positionChangeToBeProcessed.commitRequestId] = transferStateId
+ } else {
+ const { participantPositionChange, transferStateChange, transferStateId, updatedRunningPosition } =
+ _handleParticipantPositionChange(runningPosition, positionChangeToBeProcessed.amount, positionChangeToBeProcessed.transferId, accumulatedPositionReservedValue)
+ runningPosition = updatedRunningPosition
+ participantPositionChanges.push(participantPositionChange)
+ transferStateChanges.push(transferStateChange)
+ accumulatedTransferStatesCopy[positionChangeToBeProcessed.transferId] = transferStateId
+ }
+ binItem.result = { success: true }
+ const from = binItem.message.value.from
+ cyrilResult.positionChanges[positionChangeIndex].isDone = true
+ const nextIndex = cyrilResult.positionChanges.findIndex(positionChange => !positionChange.isDone)
+ if (nextIndex === -1) {
+ // All position changes are done, we need to inform all the participants about the abort
+ // Construct a list of messages excluding the original message as it will notified anyway
+ for (const positionChange of cyrilResult.positionChanges) {
+ if (positionChange.isFxTransferStateChange) {
+ // Construct notification message for fx transfer state change
+ const resultMessage = _constructAbortResultMessage(binItem, positionChange.commitRequestId, from, positionChange.notifyTo)
+ resultMessages.push({ binItem, message: resultMessage })
+ } else {
+ // Construct notification message for transfer state change
+ const resultMessage = _constructAbortResultMessage(binItem, positionChange.transferId, from, positionChange.notifyTo)
+ resultMessages.push({ binItem, message: resultMessage })
+ }
+ }
+ } else {
+ // There are still position changes to be processed
+ // Send position-commit kafka message again for the next item
+ const participantCurrencyId = cyrilResult.positionChanges[nextIndex].participantCurrencyId
+ // const followupMessage = _constructTransferAbortFollowupMessage(binItem, transferId, payerFsp, payeeFsp, transfer)
+ // Pass down the context to the followup message with mutated cyrilResult
+ const followupMessage = { ...binItem.message.value }
+ // followupMessage.content.context = binItem.message.value.content.context
+ followupMessages.push({ binItem, messageKey: participantCurrencyId.toString(), message: followupMessage })
+ }
+ }
+ }
+
+ return {
+ accumulatedPositionValue: changePositions ? runningPosition.toNumber() : accumulatedPositionValue,
+ accumulatedTransferStates: accumulatedTransferStatesCopy, // finalized transfer state after fulfil processing
+ accumulatedPositionReservedValue, // not used but kept for consistency
+ accumulatedTransferStateChanges: transferStateChanges, // transfer state changes to be persisted in order
+ accumulatedFxTransferStates: accumulatedFxTransferStatesCopy, // finalized fx transfer state after fulfil processing
+ accumulatedFxTransferStateChanges: fxTransferStateChanges, // fx transfer state changes to be persisted in order
+ accumulatedPositionChanges: changePositions ? participantPositionChanges : [], // participant position changes to be persisted in order
+ notifyMessages: resultMessages, // array of objects containing bin item and result message. {binItem, message}
+ followupMessages // array of objects containing bin item, message key and followup message. {binItem, messageKey, message}
+ }
+}
+
+const _constructAbortResultMessage = (binItem, id, from, notifyTo) => {
+ let apiErrorCode = ErrorHandler.Enums.FSPIOPErrorCodes.PAYEE_REJECTION
+ let fromCalculated = from
+ if (binItem.message?.value.metadata.event.action === Enum.Events.Event.Action.FX_ABORT_VALIDATION || binItem.message?.value.metadata.event.action === Enum.Events.Event.Action.ABORT_VALIDATION) {
+ fromCalculated = Config.HUB_NAME
+ apiErrorCode = ErrorHandler.Enums.FSPIOPErrorCodes.VALIDATION_ERROR
+ }
+ const fspiopError = ErrorHandler.Factory.createFSPIOPError(
+ apiErrorCode,
+ null,
+ null,
+ null,
+ null
+ ).toApiErrorObject(Config.ERROR_HANDLING)
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.FAILURE.status,
+ fspiopError.errorInformation.errorCode,
+ fspiopError.errorInformation.errorDescription
+ )
+
+ // Create metadata for the message
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ id,
+ Enum.Kafka.Topics.POSITION,
+ binItem.message?.value.metadata.event.action, // This will be replaced anyway in Kafka.produceGeneralMessage function
+ state
+ )
+ const resultMessage = Utility.StreamingProtocol.createMessage(
+ id,
+ notifyTo,
+ fromCalculated,
+ metadata,
+ binItem.message.value.content.headers, // Headers don't really matter here. ml-api-adapter will ignore them and create their own.
+ fspiopError,
+ { id },
+ 'application/json'
+ )
+
+ return resultMessage
+}
+
+const _handleParticipantPositionChange = (runningPosition, transferAmount, transferId, accumulatedPositionReservedValue) => {
+ const transferStateId = Enum.Transfers.TransferInternalState.ABORTED_ERROR
+ const updatedRunningPosition = new MLNumber(runningPosition.add(transferAmount).toFixed(Config.AMOUNT.SCALE))
+
+ const participantPositionChange = {
+ transferId, // Need to delete this in bin processor while updating transferStateChangeId
+ transferStateChangeId: null, // Need to update this in bin processor while executing queries
+ value: updatedRunningPosition.toNumber(),
+ change: transferAmount,
+ reservedValue: accumulatedPositionReservedValue
+ }
+
+ // Construct transfer state change object
+ const transferStateChange = {
+ transferId,
+ transferStateId,
+ reason: null
+ }
+ return { participantPositionChange, transferStateChange, transferStateId, updatedRunningPosition }
+}
+
+const _handleParticipantPositionChangeFx = (runningPosition, transferAmount, commitRequestId, accumulatedPositionReservedValue) => {
+ const transferStateId = Enum.Transfers.TransferInternalState.ABORTED_ERROR
+ // Amounts in `transferParticipant` for the payee are stored as negative values
+ const updatedRunningPosition = new MLNumber(runningPosition.add(transferAmount).toFixed(Config.AMOUNT.SCALE))
+
+ const participantPositionChange = {
+ commitRequestId, // Need to delete this in bin processor while updating fxTransferStateChangeId
+ fxTransferStateChangeId: null, // Need to update this in bin processor while executing queries
+ value: updatedRunningPosition.toNumber(),
+ change: transferAmount,
+ reservedValue: accumulatedPositionReservedValue
+ }
+
+ const fxTransferStateChange = {
+ commitRequestId,
+ transferStateId,
+ reason: null
+ }
+ return { participantPositionChange, fxTransferStateChange, transferStateId, updatedRunningPosition }
+}
+
+module.exports = {
+ processPositionAbortBin
+}
diff --git a/src/domain/position/binProcessor.js b/src/domain/position/binProcessor.js
index 39816764b..1b16d6ff6 100644
--- a/src/domain/position/binProcessor.js
+++ b/src/domain/position/binProcessor.js
@@ -1,8 +1,8 @@
/*****
License
--------------
- Copyright © 2017 Bill & Melinda Gates Foundation
- The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
@@ -15,7 +15,7 @@
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
- Gates Foundation organization for an example). Those individuals should have
+ Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets .
@@ -24,7 +24,6 @@
* INFITX
- Vijay Kumar Guthi
- - Steven Oderayi
--------------
******/
@@ -34,7 +33,12 @@ const Logger = require('@mojaloop/central-services-logger')
const BatchPositionModel = require('../../models/position/batch')
const BatchPositionModelCached = require('../../models/position/batchCached')
const PositionPrepareDomain = require('./prepare')
+const PositionFxPrepareDomain = require('./fx-prepare')
const PositionFulfilDomain = require('./fulfil')
+const PositionFxFulfilDomain = require('./fx-fulfil')
+const PositionTimeoutReservedDomain = require('./timeout-reserved')
+const PositionFxTimeoutReservedDomain = require('./fx-timeout-reserved')
+const PositionAbortDomain = require('./abort')
const SettlementModelCached = require('../../models/settlement/settlementModelCached')
const Enum = require('@mojaloop/central-services-shared').Enum
const ErrorHandler = require('@mojaloop/central-services-error-handling')
@@ -52,75 +56,29 @@ const participantFacade = require('../../models/participant/facade')
* @returns {results} - Returns a list of bins with results or throws an error if failed
*/
const processBins = async (bins, trx) => {
- const transferIdList = []
- const reservedActionTransferIdList = []
- await iterateThroughBins(bins, (_accountID, action, item) => {
- if (item.decodedPayload?.transferId) {
- transferIdList.push(item.decodedPayload.transferId)
- // get transferId from uriParams for fulfil messages
- } else if (item.message?.value?.content?.uriParams?.id) {
- transferIdList.push(item.message.value.content.uriParams.id)
- if (action === Enum.Events.Event.Action.RESERVE) {
- reservedActionTransferIdList.push(item.message.value.content.uriParams.id)
- }
- }
- })
+ let notifyMessages = []
+ let followupMessages = []
+ let limitAlarms = []
+
+ // Get transferIdList, reservedActionTransferIdList and commitRequestId for actions PREPARE, FX_PREPARE, FX_RESERVE, COMMIT and RESERVE
+ const { transferIdList, reservedActionTransferIdList, commitRequestIdList } = await _getTransferIdList(bins)
+
// Pre fetch latest transferStates for all the transferIds in the account-bin
- const latestTransferStateChanges = await BatchPositionModel.getLatestTransferStateChangesByTransferIdList(trx, transferIdList)
- const latestTransferStates = {}
- for (const key in latestTransferStateChanges) {
- latestTransferStates[key] = latestTransferStateChanges[key].transferStateId
- }
+ const latestTransferStates = await _fetchLatestTransferStates(trx, transferIdList)
- const accountIds = Object.keys(bins)
+ // Pre fetch latest fxTransferStates for all the commitRequestIds in the account-bin
+ const latestFxTransferStates = await _fetchLatestFxTransferStates(trx, commitRequestIdList)
- // Pre fetch all settlement accounts corresponding to the position accounts
- // Get all participantIdMap for the accountIds
- const participantCurrencyIds = await BatchPositionModelCached.getParticipantCurrencyByIds(trx, accountIds)
+ const accountIds = [...Object.keys(bins).filter(accountId => accountId !== '0')]
- // Validate that participantCurrencyIds exist for each of the accountIds
- // i.e every unique accountId has a corresponding entry in participantCurrencyIds
- const participantIdsHavingCurrencyIdsList = [...new Set(participantCurrencyIds.map(item => item.participantCurrencyId))]
- const allAccountIdsHaveParticipantCurrencyIds = accountIds.every(accountId => {
- return participantIdsHavingCurrencyIdsList.includes(Number(accountId))
- })
- if (!allAccountIdsHaveParticipantCurrencyIds) {
- throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR, 'Not all accountIds have corresponding participantCurrencyIds')
- }
+ // Get all participantIdMap for the accountIds
+ const participantCurrencyIds = await _getParticipantCurrencyIds(trx, accountIds)
+ // Pre fetch all settlement accounts corresponding to the position accounts
const allSettlementModels = await SettlementModelCached.getAll()
// Construct objects participantIdMap, accountIdMap and currencyIdMap
- const participantIdMap = {}
- const accountIdMap = {}
- const currencyIdMap = {}
- for (const item of participantCurrencyIds) {
- const { participantId, currencyId, participantCurrencyId } = item
- if (!participantIdMap[participantId]) {
- participantIdMap[participantId] = {}
- }
- if (!currencyIdMap[currencyId]) {
- currencyIdMap[currencyId] = {
- settlementModel: _getSettlementModelForCurrency(currencyId, allSettlementModels)
- }
- }
- participantIdMap[participantId][currencyId] = participantCurrencyId
- accountIdMap[participantCurrencyId] = { participantId, currencyId }
- }
-
- // Get all participantCurrencyIds for the participantIdMap
- const allParticipantCurrencyIds = await BatchPositionModelCached.getParticipantCurrencyByParticipantIds(trx, Object.keys(participantIdMap))
- const settlementCurrencyIds = []
- for (const pc of allParticipantCurrencyIds) {
- const correspondingParticipantCurrencyId = participantIdMap[pc.participantId][pc.currencyId]
- if (correspondingParticipantCurrencyId) {
- const settlementModel = currencyIdMap[pc.currencyId].settlementModel
- if (pc.ledgerAccountTypeId === settlementModel.settlementAccountTypeId) {
- settlementCurrencyIds.push(pc)
- accountIdMap[correspondingParticipantCurrencyId].settlementCurrencyId = pc.participantCurrencyId
- }
- }
- }
+ const { settlementCurrencyIds, accountIdMap } = await _constructRequiredMaps(participantCurrencyIds, allSettlementModels, trx)
// Pre fetch all position account balances for the account-bin and acquire lock on position
const positions = await BatchPositionModel.getPositionsByAccountIdsForUpdate(trx, [
@@ -135,15 +93,21 @@ const processBins = async (bins, trx) => {
Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE
)
+ // Fetch all RESERVED participantPositionChanges associated with a commitRequestId
+ // These will contain the value that was reserved for the fxTransfer
+ // We will use these values to revert the position on timeouts
+ const fetchedReservedPositionChangesByCommitRequestIds =
+ await BatchPositionModel.getReservedPositionChangesByCommitRequestIds(
+ trx,
+ commitRequestIdList
+ )
+
// Pre fetch transfers for all reserve action fulfils
const reservedActionTransfers = await BatchPositionModel.getTransferByIdsForReserve(
trx,
reservedActionTransferIdList
)
- let notifyMessages = []
- let limitAlarms = []
-
// For each account-bin in the list
for (const accountID in bins) {
const accountBin = bins[accountID]
@@ -152,57 +116,211 @@ const processBins = async (bins, trx) => {
array2.every((element) => array1.includes(element))
// If non-prepare/non-commit action found, log error
// We need to remove this once we implement all the actions
- if (!isSubset(['prepare', 'commit', 'reserve'], actions)) {
- Logger.isErrorEnabled && Logger.error('Only prepare/commit actions are allowed in a batch')
- // throw new Error('Only prepare action is allowed in a batch')
+ const allowedActions = [
+ Enum.Events.Event.Action.PREPARE,
+ Enum.Events.Event.Action.FX_PREPARE,
+ Enum.Events.Event.Action.COMMIT,
+ Enum.Events.Event.Action.RESERVE,
+ Enum.Events.Event.Action.FX_RESERVE,
+ Enum.Events.Event.Action.TIMEOUT_RESERVED,
+ Enum.Events.Event.Action.FX_TIMEOUT_RESERVED,
+ Enum.Events.Event.Action.ABORT,
+ Enum.Events.Event.Action.FX_ABORT,
+ Enum.Events.Event.Action.ABORT_VALIDATION,
+ Enum.Events.Event.Action.FX_ABORT_VALIDATION
+ ]
+ if (!isSubset(allowedActions, actions)) {
+ Logger.isErrorEnabled && Logger.error(`Only ${allowedActions.join()} are allowed in a batch`)
}
- const settlementParticipantPosition = positions[accountIdMap[accountID].settlementCurrencyId].value
- const settlementModel = currencyIdMap[accountIdMap[accountID].currencyId].settlementModel
+ let settlementParticipantPosition = 0
+ let participantLimit = null
- // Story #3657: The following SQL query/lookup can be optimized for performance
- const participantLimit = await participantFacade.getParticipantLimitByParticipantCurrencyLimit(
- accountIdMap[accountID].participantId,
- accountIdMap[accountID].currencyId,
- Enum.Accounts.LedgerAccountType.POSITION,
- Enum.Accounts.ParticipantLimitType.NET_DEBIT_CAP
- )
// Initialize accumulated values
// These values will be passed across various actions in the bin
- let accumulatedPositionValue = positions[accountID].value
- let accumulatedPositionReservedValue = positions[accountID].reservedValue
+ let accumulatedPositionValue = 0
+ let accumulatedPositionReservedValue = 0
let accumulatedTransferStates = latestTransferStates
+ let accumulatedFxTransferStates = latestFxTransferStates
let accumulatedTransferStateChanges = []
+ let accumulatedFxTransferStateChanges = []
let accumulatedPositionChanges = []
+ let changePositions = false
+
+ if (accountID !== '0') {
+ settlementParticipantPosition = positions[accountIdMap[accountID].settlementCurrencyId].value
+
+ // Story #3657: The following SQL query/lookup can be optimized for performance
+ participantLimit = await participantFacade.getParticipantLimitByParticipantCurrencyLimit(
+ accountIdMap[accountID].participantId,
+ accountIdMap[accountID].currencyId,
+ Enum.Accounts.LedgerAccountType.POSITION,
+ Enum.Accounts.ParticipantLimitType.NET_DEBIT_CAP
+ )
+ accumulatedPositionValue = positions[accountID].value
+ accumulatedPositionReservedValue = positions[accountID].reservedValue
+
+ changePositions = true
+ }
+
+ // ========== FX_FULFIL ==========
+ // If fulfil action found then call processPositionPrepareBin function
+ // We don't need to change the position for FX transfers. All the position changes happen when actual transfer is done
+ const fxFulfilActionResult = await PositionFxFulfilDomain.processPositionFxFulfilBin(
+ accountBin[Enum.Events.Event.Action.FX_RESERVE],
+ {
+ accumulatedFxTransferStates
+ }
+ )
+
+ // ========== FX_TIMEOUT ==========
+ // If fx-timeout-reserved action found then call processPositionTimeoutReserveBin function
+ const fxTimeoutReservedActionResult = await PositionFxTimeoutReservedDomain.processPositionFxTimeoutReservedBin(
+ accountBin[Enum.Events.Event.Action.FX_TIMEOUT_RESERVED],
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedFxTransferStates,
+ fetchedReservedPositionChangesByCommitRequestIds,
+ changePositions
+ }
+ )
+
+ // Update accumulated values
+ accumulatedPositionValue = fxTimeoutReservedActionResult.accumulatedPositionValue
+ accumulatedPositionReservedValue = fxTimeoutReservedActionResult.accumulatedPositionReservedValue
+ accumulatedFxTransferStates = fxTimeoutReservedActionResult.accumulatedFxTransferStates
+ // Append accumulated arrays
+ accumulatedFxTransferStateChanges = accumulatedFxTransferStateChanges.concat(fxTimeoutReservedActionResult.accumulatedFxTransferStateChanges)
+ accumulatedPositionChanges = accumulatedPositionChanges.concat(fxTimeoutReservedActionResult.accumulatedPositionChanges)
+ notifyMessages = notifyMessages.concat(fxTimeoutReservedActionResult.notifyMessages)
+
+ // Update accumulated values
+ accumulatedFxTransferStates = fxFulfilActionResult.accumulatedFxTransferStates
+ // Append accumulated arrays
+ accumulatedFxTransferStateChanges = accumulatedFxTransferStateChanges.concat(fxFulfilActionResult.accumulatedFxTransferStateChanges)
+ notifyMessages = notifyMessages.concat(fxFulfilActionResult.notifyMessages)
+
+ // ========== FULFIL ==========
// If fulfil action found then call processPositionPrepareBin function
const fulfilActionResult = await PositionFulfilDomain.processPositionFulfilBin(
[accountBin.commit, accountBin.reserve],
- accumulatedPositionValue,
- accumulatedPositionReservedValue,
- accumulatedTransferStates,
- latestTransferInfoByTransferId,
- reservedActionTransfers
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedTransferStates,
+ accumulatedFxTransferStates,
+ transferInfoList: latestTransferInfoByTransferId,
+ reservedActionTransfers,
+ changePositions
+ }
)
// Update accumulated values
accumulatedPositionValue = fulfilActionResult.accumulatedPositionValue
accumulatedPositionReservedValue = fulfilActionResult.accumulatedPositionReservedValue
accumulatedTransferStates = fulfilActionResult.accumulatedTransferStates
+ accumulatedFxTransferStates = fulfilActionResult.accumulatedFxTransferStates
// Append accumulated arrays
accumulatedTransferStateChanges = accumulatedTransferStateChanges.concat(fulfilActionResult.accumulatedTransferStateChanges)
+ accumulatedFxTransferStateChanges = accumulatedFxTransferStateChanges.concat(fulfilActionResult.accumulatedFxTransferStateChanges)
accumulatedPositionChanges = accumulatedPositionChanges.concat(fulfilActionResult.accumulatedPositionChanges)
notifyMessages = notifyMessages.concat(fulfilActionResult.notifyMessages)
+ followupMessages = followupMessages.concat(fulfilActionResult.followupMessages)
+
+ // ========== ABORT ==========
+ // If abort action found then call processPositionAbortBin function
+ const abortReservedActionResult = await PositionAbortDomain.processPositionAbortBin(
+ [
+ ...(accountBin[Enum.Events.Event.Action.ABORT] || []),
+ ...(accountBin[Enum.Events.Event.Action.ABORT_VALIDATION] || [])
+ ],
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedTransferStates,
+ accumulatedFxTransferStates,
+ isFx: false,
+ changePositions
+ }
+ )
+
+ // Update accumulated values
+ accumulatedPositionValue = abortReservedActionResult.accumulatedPositionValue
+ accumulatedPositionReservedValue = abortReservedActionResult.accumulatedPositionReservedValue
+ accumulatedTransferStates = abortReservedActionResult.accumulatedTransferStates
+ accumulatedFxTransferStates = abortReservedActionResult.accumulatedFxTransferStates
+ // Append accumulated arrays
+ accumulatedTransferStateChanges = accumulatedTransferStateChanges.concat(abortReservedActionResult.accumulatedTransferStateChanges)
+ accumulatedFxTransferStateChanges = accumulatedFxTransferStateChanges.concat(abortReservedActionResult.accumulatedFxTransferStateChanges)
+ accumulatedPositionChanges = accumulatedPositionChanges.concat(abortReservedActionResult.accumulatedPositionChanges)
+ notifyMessages = notifyMessages.concat(abortReservedActionResult.notifyMessages)
+ followupMessages = followupMessages.concat(abortReservedActionResult.followupMessages)
+
+ // ========== FX_ABORT ==========
+ // If abort action found then call processPositionAbortBin function
+ const fxAbortReservedActionResult = await PositionAbortDomain.processPositionAbortBin(
+ [
+ ...(accountBin[Enum.Events.Event.Action.FX_ABORT] || []),
+ ...(accountBin[Enum.Events.Event.Action.FX_ABORT_VALIDATION] || [])
+ ],
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedTransferStates,
+ accumulatedFxTransferStates,
+ isFx: true,
+ changePositions
+ }
+ )
+
+ // Update accumulated values
+ accumulatedPositionValue = fxAbortReservedActionResult.accumulatedPositionValue
+ accumulatedPositionReservedValue = fxAbortReservedActionResult.accumulatedPositionReservedValue
+ accumulatedTransferStates = fxAbortReservedActionResult.accumulatedTransferStates
+ accumulatedFxTransferStates = fxAbortReservedActionResult.accumulatedFxTransferStates
+ // Append accumulated arrays
+ accumulatedTransferStateChanges = accumulatedTransferStateChanges.concat(fxAbortReservedActionResult.accumulatedTransferStateChanges)
+ accumulatedFxTransferStateChanges = accumulatedFxTransferStateChanges.concat(fxAbortReservedActionResult.accumulatedFxTransferStateChanges)
+ accumulatedPositionChanges = accumulatedPositionChanges.concat(fxAbortReservedActionResult.accumulatedPositionChanges)
+ notifyMessages = notifyMessages.concat(fxAbortReservedActionResult.notifyMessages)
+ followupMessages = followupMessages.concat(fxAbortReservedActionResult.followupMessages)
+
+ // ========== TIMEOUT_RESERVED ==========
+ // If timeout-reserved action found then call processPositionTimeoutReserveBin function
+ const timeoutReservedActionResult = await PositionTimeoutReservedDomain.processPositionTimeoutReservedBin(
+ accountBin[Enum.Events.Event.Action.TIMEOUT_RESERVED],
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedTransferStates,
+ transferInfoList: latestTransferInfoByTransferId,
+ changePositions
+ }
+ )
+
+ // Update accumulated values
+ accumulatedPositionValue = timeoutReservedActionResult.accumulatedPositionValue
+ accumulatedPositionReservedValue = timeoutReservedActionResult.accumulatedPositionReservedValue
+ accumulatedTransferStates = timeoutReservedActionResult.accumulatedTransferStates
+ // Append accumulated arrays
+ accumulatedTransferStateChanges = accumulatedTransferStateChanges.concat(timeoutReservedActionResult.accumulatedTransferStateChanges)
+ accumulatedPositionChanges = accumulatedPositionChanges.concat(timeoutReservedActionResult.accumulatedPositionChanges)
+ notifyMessages = notifyMessages.concat(timeoutReservedActionResult.notifyMessages)
+ // ========== PREPARE ==========
// If prepare action found then call processPositionPrepareBin function
const prepareActionResult = await PositionPrepareDomain.processPositionPrepareBin(
accountBin.prepare,
- accumulatedPositionValue,
- accumulatedPositionReservedValue,
- accumulatedTransferStates,
- settlementParticipantPosition,
- settlementModel,
- participantLimit
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedTransferStates,
+ settlementParticipantPosition,
+ participantLimit,
+ changePositions
+ }
)
// Update accumulated values
@@ -214,22 +332,63 @@ const processBins = async (bins, trx) => {
accumulatedPositionChanges = accumulatedPositionChanges.concat(prepareActionResult.accumulatedPositionChanges)
notifyMessages = notifyMessages.concat(prepareActionResult.notifyMessages)
- // Update accumulated position values by calling a facade function
- await BatchPositionModel.updateParticipantPosition(trx, positions[accountID].participantPositionId, accumulatedPositionValue, accumulatedPositionReservedValue)
+ // ========== FX_PREPARE ==========
+ // If fx-prepare action found then call processPositionFxPrepareBin function
+ const fxPrepareActionResult = await PositionFxPrepareDomain.processFxPositionPrepareBin(
+ accountBin[Enum.Events.Event.Action.FX_PREPARE],
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedFxTransferStates,
+ settlementParticipantPosition,
+ participantLimit,
+ changePositions
+ }
+ )
+
+ // Update accumulated values
+ accumulatedPositionValue = fxPrepareActionResult.accumulatedPositionValue
+ accumulatedPositionReservedValue = fxPrepareActionResult.accumulatedPositionReservedValue
+ accumulatedFxTransferStates = fxPrepareActionResult.accumulatedFxTransferStates
+ // Append accumulated arrays
+ accumulatedFxTransferStateChanges = accumulatedFxTransferStateChanges.concat(fxPrepareActionResult.accumulatedFxTransferStateChanges)
+ accumulatedPositionChanges = accumulatedPositionChanges.concat(fxPrepareActionResult.accumulatedPositionChanges)
+ notifyMessages = notifyMessages.concat(fxPrepareActionResult.notifyMessages)
+
+ // ========== CONSOLIDATION ==========
+
+ if (changePositions) {
+ // Update accumulated position values by calling a facade function
+ await BatchPositionModel.updateParticipantPosition(trx, positions[accountID].participantPositionId, accumulatedPositionValue, accumulatedPositionReservedValue)
+ }
// Bulk insert accumulated transferStateChanges by calling a facade function
await BatchPositionModel.bulkInsertTransferStateChanges(trx, accumulatedTransferStateChanges)
+ // Bulk insert accumulated fxTransferStateChanges by calling a facade function
+ await BatchPositionModel.bulkInsertFxTransferStateChanges(trx, accumulatedFxTransferStateChanges)
// Bulk get the transferStateChangeIds for transferids using select whereIn
const fetchedTransferStateChanges = await BatchPositionModel.getLatestTransferStateChangesByTransferIdList(trx, accumulatedTransferStateChanges.map(item => item.transferId))
- // Mutate accumulated positionChanges with transferStateChangeIds
- for (const positionChange of accumulatedPositionChanges) {
- positionChange.transferStateChangeId = fetchedTransferStateChanges[positionChange.transferId].transferStateChangeId
- positionChange.participantPositionId = positions[accountID].participantPositionId
- delete positionChange.transferId
+ // Bulk get the fxTransferStateChangeIds for commitRequestId using select whereIn
+ const fetchedFxTransferStateChanges = await BatchPositionModel.getLatestFxTransferStateChangesByCommitRequestIdList(trx, accumulatedFxTransferStateChanges.map(item => item.commitRequestId))
+
+ if (changePositions) {
+ // Mutate accumulated positionChanges with transferStateChangeIds and fxTransferStateChangeIds
+ for (const positionChange of accumulatedPositionChanges) {
+ if (positionChange.transferId) {
+ positionChange.transferStateChangeId = fetchedTransferStateChanges[positionChange.transferId].transferStateChangeId
+ delete positionChange.transferId
+ } else if (positionChange.commitRequestId) {
+ positionChange.fxTransferStateChangeId = fetchedFxTransferStateChanges[positionChange.commitRequestId].fxTransferStateChangeId
+ delete positionChange.commitRequestId
+ }
+ positionChange.participantPositionId = positions[accountID].participantPositionId
+ positionChange.participantCurrencyId = accountID
+ }
+
+ // Bulk insert accumulated positionChanges by calling a facade function
+ await BatchPositionModel.bulkInsertParticipantPositionChanges(trx, accumulatedPositionChanges)
}
- // Bulk insert accumulated positionChanges by calling a facade function
- await BatchPositionModel.bulkInsertParticipantPositionChanges(trx, accumulatedPositionChanges)
limitAlarms = limitAlarms.concat(prepareActionResult.limitAlarms)
}
@@ -237,6 +396,7 @@ const processBins = async (bins, trx) => {
// Return results
return {
notifyMessages,
+ followupMessages,
limitAlarms
}
}
@@ -285,6 +445,108 @@ const _getSettlementModelForCurrency = (currencyId, allSettlementModels) => {
return settlementModels.find(sm => sm.ledgerAccountTypeId === Enum.Accounts.LedgerAccountType.POSITION)
}
+const _getTransferIdList = async (bins) => {
+ const transferIdList = []
+ const reservedActionTransferIdList = []
+ const commitRequestIdList = []
+ await iterateThroughBins(bins, (_accountID, action, item) => {
+ if (action === Enum.Events.Event.Action.PREPARE) {
+ transferIdList.push(item.decodedPayload.transferId)
+ } else if (action === Enum.Events.Event.Action.FULFIL) {
+ transferIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.COMMIT) {
+ transferIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.RESERVE) {
+ transferIdList.push(item.message.value.content.uriParams.id)
+ reservedActionTransferIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.TIMEOUT_RESERVED) {
+ transferIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.FX_PREPARE) {
+ commitRequestIdList.push(item.decodedPayload.commitRequestId)
+ } else if (action === Enum.Events.Event.Action.FX_RESERVE) {
+ commitRequestIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.FX_TIMEOUT_RESERVED) {
+ commitRequestIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.ABORT) {
+ transferIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.FX_ABORT) {
+ commitRequestIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.ABORT_VALIDATION) {
+ transferIdList.push(item.message.value.content.uriParams.id)
+ } else if (action === Enum.Events.Event.Action.FX_ABORT_VALIDATION) {
+ commitRequestIdList.push(item.message.value.content.uriParams.id)
+ }
+ })
+ return { transferIdList, reservedActionTransferIdList, commitRequestIdList }
+}
+
+const _fetchLatestTransferStates = async (trx, transferIdList) => {
+ const latestTransferStateChanges = await BatchPositionModel.getLatestTransferStateChangesByTransferIdList(trx, transferIdList)
+ const latestTransferStates = {}
+ for (const key in latestTransferStateChanges) {
+ latestTransferStates[key] = latestTransferStateChanges[key].transferStateId
+ }
+ return latestTransferStates
+}
+
+const _fetchLatestFxTransferStates = async (trx, commitRequestIdList) => {
+ const latestFxTransferStateChanges = await BatchPositionModel.getLatestFxTransferStateChangesByCommitRequestIdList(trx, commitRequestIdList)
+ const latestFxTransferStates = {}
+ for (const key in latestFxTransferStateChanges) {
+ latestFxTransferStates[key] = latestFxTransferStateChanges[key].transferStateId
+ }
+ return latestFxTransferStates
+}
+
+const _getParticipantCurrencyIds = async (trx, accountIds) => {
+ const participantCurrencyIds = await BatchPositionModelCached.getParticipantCurrencyByIds(trx, accountIds)
+
+ // Validate that participantCurrencyIds exist for each of the accountIds
+ // i.e every unique accountId has a corresponding entry in participantCurrencyIds
+ const participantIdsHavingCurrencyIdsList = [...new Set(participantCurrencyIds.map(item => item.participantCurrencyId))]
+ const allAccountIdsHaveParticipantCurrencyIds = accountIds.every(accountId => {
+ return participantIdsHavingCurrencyIdsList.includes(Number(accountId))
+ })
+ if (!allAccountIdsHaveParticipantCurrencyIds) {
+ throw ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR, 'Not all accountIds have corresponding participantCurrencyIds')
+ }
+ return participantCurrencyIds
+}
+
+const _constructRequiredMaps = async (participantCurrencyIds, allSettlementModels, trx) => {
+ const participantIdMap = {}
+ const accountIdMap = {}
+ const currencyIdMap = {}
+ for (const item of participantCurrencyIds) {
+ const { participantId, currencyId, participantCurrencyId } = item
+ if (!participantIdMap[participantId]) {
+ participantIdMap[participantId] = {}
+ }
+ if (!currencyIdMap[currencyId]) {
+ currencyIdMap[currencyId] = {
+ settlementModel: _getSettlementModelForCurrency(currencyId, allSettlementModels)
+ }
+ }
+ participantIdMap[participantId][currencyId] = participantCurrencyId
+ accountIdMap[participantCurrencyId] = { participantId, currencyId }
+ }
+
+ // Get all participantCurrencyIds for the participantIdMap
+ const allParticipantCurrencyIds = await BatchPositionModelCached.getParticipantCurrencyByParticipantIds(trx, Object.keys(participantIdMap))
+ const settlementCurrencyIds = []
+ for (const pc of allParticipantCurrencyIds) {
+ const correspondingParticipantCurrencyId = participantIdMap[pc.participantId][pc.currencyId]
+ if (correspondingParticipantCurrencyId) {
+ const settlementModel = currencyIdMap[pc.currencyId].settlementModel
+ if (pc.ledgerAccountTypeId === settlementModel.settlementAccountTypeId) {
+ settlementCurrencyIds.push(pc)
+ accountIdMap[correspondingParticipantCurrencyId].settlementCurrencyId = pc.participantCurrencyId
+ }
+ }
+ }
+ return { settlementCurrencyIds, accountIdMap, currencyIdMap }
+}
+
module.exports = {
processBins,
iterateThroughBins
diff --git a/src/domain/position/fulfil.js b/src/domain/position/fulfil.js
index 6877eaf93..59a87b18a 100644
--- a/src/domain/position/fulfil.js
+++ b/src/domain/position/fulfil.js
@@ -1,3 +1,38 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+
const { Enum } = require('@mojaloop/central-services-shared')
const ErrorHandler = require('@mojaloop/central-services-error-handling')
const Config = require('../../lib/config')
@@ -13,149 +48,290 @@ const TransferObjectTransform = require('../../domain/transfer/transform')
* @description This is the domain function to process a bin of position-fulfil messages of a single participant account.
*
* @param {array} commitReserveFulfilBins - an array containing commit and reserve action bins
- * @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
- * @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
- * @param {object} accumulatedTransferStates - object with transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
- * @param {object} transferInfoList - object with transfer id keys and transfer info values. Used to pass transfer info to domain function.
+ * @param {object} options
+ * @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
+ * @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
+ * @param {object} accumulatedTransferStates - object with transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
+ * @param {object} transferInfoList - object with transfer id keys and transfer info values. Used to pass transfer info to domain function.
+ * @param {boolean} changePositions - whether to change positions or not
* @returns {object} - Returns an object containing accumulatedPositionValue, accumulatedPositionReservedValue, accumulatedTransferStateChanges, accumulatedTransferStates, resultMessages, limitAlarms or throws an error if failed
*/
const processPositionFulfilBin = async (
commitReserveFulfilBins,
- accumulatedPositionValue,
- accumulatedPositionReservedValue,
- accumulatedTransferStates,
- transferInfoList,
- reservedActionTransfers
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedTransferStates,
+ accumulatedFxTransferStates,
+ transferInfoList,
+ reservedActionTransfers,
+ changePositions = true
+ }
) => {
const transferStateChanges = []
+ const fxTransferStateChanges = []
const participantPositionChanges = []
const resultMessages = []
+ const followupMessages = []
const accumulatedTransferStatesCopy = Object.assign({}, accumulatedTransferStates)
+ const accumulatedFxTransferStatesCopy = Object.assign({}, accumulatedFxTransferStates)
let runningPosition = new MLNumber(accumulatedPositionValue)
for (const binItems of commitReserveFulfilBins) {
if (binItems && binItems.length > 0) {
for (const binItem of binItems) {
- let transferStateId
- let reason
- let resultMessage
const transferId = binItem.message.value.content.uriParams.id
const payeeFsp = binItem.message.value.from
const payerFsp = binItem.message.value.to
const transfer = binItem.decodedPayload
- Logger.isDebugEnabled && Logger.debug(`processPositionFulfilBin::transfer:processingMessage: ${JSON.stringify(transfer)}`)
- Logger.isDebugEnabled && Logger.debug(`accumulatedTransferStates: ${JSON.stringify(accumulatedTransferStates)}`)
+
// Inform payee dfsp if transfer is not in RECEIVED_FULFIL state, skip making any transfer state changes
if (accumulatedTransferStates[transferId] !== Enum.Transfers.TransferInternalState.RECEIVED_FULFIL) {
- // forward same headers from the prepare message, except the content-length header
- // set destination to payeefsp and source to switch
- const headers = { ...binItem.message.value.content.headers }
- headers[Enum.Http.Headers.FSPIOP.DESTINATION] = payeeFsp
- headers[Enum.Http.Headers.FSPIOP.SOURCE] = Enum.Http.Headers.FSPIOP.SWITCH.value
- delete headers['content-length']
-
- const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError(
- `Invalid State: ${accumulatedTransferStates[transferId]} - expected: ${Enum.Transfers.TransferInternalState.RECEIVED_FULFIL}`
- ).toApiErrorObject(Config.ERROR_HANDLING)
- const state = Utility.StreamingProtocol.createEventState(
- Enum.Events.EventStatus.FAILURE.status,
- fspiopError.errorInformation.errorCode,
- fspiopError.errorInformation.errorDescription
- )
-
- const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
- transferId,
- Enum.Kafka.Topics.NOTIFICATION,
- Enum.Events.Event.Action.FULFIL,
- state
- )
-
- resultMessage = Utility.StreamingProtocol.createMessage(
- transferId,
- payeeFsp,
- Enum.Http.Headers.FSPIOP.SWITCH.value,
- metadata,
- headers,
- fspiopError,
- { id: transferId },
- 'application/json'
- )
+ const resultMessage = _handleIncorrectTransferState(binItem, payeeFsp, transferId, accumulatedTransferStates)
+ resultMessages.push({ binItem, message: resultMessage })
} else {
- const transferInfo = transferInfoList[transferId]
-
- // forward same headers from the prepare message, except the content-length header
- const headers = { ...binItem.message.value.content.headers }
- delete headers['content-length']
-
- const state = Utility.StreamingProtocol.createEventState(
- Enum.Events.EventStatus.SUCCESS.status,
- null,
- null
- )
- const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
- transferId,
- Enum.Kafka.Topics.TRANSFER,
- Enum.Events.Event.Action.COMMIT,
- state
- )
-
- resultMessage = Utility.StreamingProtocol.createMessage(
- transferId,
- payerFsp,
- payeeFsp,
- metadata,
- headers,
- transfer,
- { id: transferId },
- 'application/json'
- )
-
- if (binItem.message.value.metadata.event.action === Enum.Events.Event.Action.RESERVE) {
- resultMessage.content.payload = TransferObjectTransform.toFulfil(
- reservedActionTransfers[transferId]
- )
- }
-
- transferStateId = Enum.Transfers.TransferState.COMMITTED
- // Amounts in `transferParticipant` for the payee are stored as negative values
- runningPosition = new MLNumber(runningPosition.add(transferInfo.amount).toFixed(Config.AMOUNT.SCALE))
-
- const participantPositionChange = {
- transferId, // Need to delete this in bin processor while updating transferStateChangeId
- transferStateChangeId: null, // Need to update this in bin processor while executing queries
- value: runningPosition.toNumber(),
- reservedValue: accumulatedPositionReservedValue
+ Logger.isDebugEnabled && Logger.debug(`processPositionFulfilBin::transfer:processingMessage: ${JSON.stringify(transfer)}`)
+ Logger.isDebugEnabled && Logger.debug(`accumulatedTransferStates: ${JSON.stringify(accumulatedTransferStates)}`)
+ const cyrilResult = binItem.message.value.content.context?.cyrilResult
+ if (cyrilResult && cyrilResult.isFx) {
+ // This is FX transfer
+ // Handle position movements
+ // Iterate through positionChanges and handle each position movement, mark as done and publish a position-commit kafka message again for the next item
+ // Find out the first item to be processed
+ const positionChangeIndex = cyrilResult.positionChanges.findIndex(positionChange => !positionChange.isDone)
+ const positionChangeToBeProcessed = cyrilResult.positionChanges[positionChangeIndex]
+ let transferStateIdCopy
+ if (positionChangeToBeProcessed.isFxTransferStateChange) {
+ const { participantPositionChange, fxTransferStateChange, transferStateId, updatedRunningPosition } =
+ _handleParticipantPositionChangeFx(runningPosition, positionChangeToBeProcessed.amount, positionChangeToBeProcessed.commitRequestId, accumulatedPositionReservedValue)
+ transferStateIdCopy = transferStateId
+ runningPosition = updatedRunningPosition
+ participantPositionChanges.push(participantPositionChange)
+ fxTransferStateChanges.push(fxTransferStateChange)
+ accumulatedFxTransferStatesCopy[positionChangeToBeProcessed.commitRequestId] = transferStateId
+ const patchMessages = _constructPatchNotificationResultMessage(
+ binItem,
+ cyrilResult
+ )
+ for (const patchMessage of patchMessages) {
+ resultMessages.push({ binItem, message: patchMessage })
+ }
+ } else {
+ const { participantPositionChange, transferStateChange, transferStateId, updatedRunningPosition } =
+ _handleParticipantPositionChange(runningPosition, positionChangeToBeProcessed.amount, positionChangeToBeProcessed.transferId, accumulatedPositionReservedValue)
+ transferStateIdCopy = transferStateId
+ runningPosition = updatedRunningPosition
+ participantPositionChanges.push(participantPositionChange)
+ transferStateChanges.push(transferStateChange)
+ accumulatedTransferStatesCopy[positionChangeToBeProcessed.transferId] = transferStateId
+ }
+ binItem.result = { success: true }
+ cyrilResult.positionChanges[positionChangeIndex].isDone = true
+ const nextIndex = cyrilResult.positionChanges.findIndex(positionChange => !positionChange.isDone)
+ if (nextIndex === -1) {
+ // All position changes are done
+ const resultMessage = _constructTransferFulfilResultMessage(binItem, transferId, payerFsp, payeeFsp, transfer, reservedActionTransfers, transferStateIdCopy)
+ resultMessages.push({ binItem, message: resultMessage })
+ } else {
+ // There are still position changes to be processed
+ // Send position-commit kafka message again for the next item
+ const participantCurrencyId = cyrilResult.positionChanges[nextIndex].participantCurrencyId
+ const followupMessage = _constructTransferFulfilResultMessage(binItem, transferId, payerFsp, payeeFsp, transfer, reservedActionTransfers, transferStateIdCopy)
+ // Pass down the context to the followup message with mutated cyrilResult
+ followupMessage.content.context = binItem.message.value.content.context
+ followupMessages.push({ binItem, messageKey: participantCurrencyId.toString(), message: followupMessage })
+ }
+ } else {
+ const transferAmount = transferInfoList[transferId].amount
+ const { participantPositionChange, transferStateChange, transferStateId, updatedRunningPosition } =
+ _handleParticipantPositionChange(runningPosition, transferAmount, transferId, accumulatedPositionReservedValue)
+ runningPosition = updatedRunningPosition
+ binItem.result = { success: true }
+ participantPositionChanges.push(participantPositionChange)
+ transferStateChanges.push(transferStateChange)
+ accumulatedTransferStatesCopy[transferId] = transferStateId
+ const resultMessage = _constructTransferFulfilResultMessage(binItem, transferId, payerFsp, payeeFsp, transfer, reservedActionTransfers, transferStateId)
+ resultMessages.push({ binItem, message: resultMessage })
}
- participantPositionChanges.push(participantPositionChange)
- binItem.result = { success: true }
- }
-
- resultMessages.push({ binItem, message: resultMessage })
-
- if (transferStateId) {
- const transferStateChange = {
- transferId,
- transferStateId,
- reason
- }
- transferStateChanges.push(transferStateChange)
- Logger.isDebugEnabled && Logger.debug(`processPositionFulfilBin::transferStateChange: ${JSON.stringify(transferStateChange)}`)
-
- accumulatedTransferStatesCopy[transferId] = transferStateId
- Logger.isDebugEnabled && Logger.debug(`processPositionFulfilBin::accumulatedTransferStatesCopy:finalizedTransferState ${JSON.stringify(transferStateId)}`)
}
}
}
}
return {
- accumulatedPositionValue: runningPosition.toNumber(),
+ accumulatedPositionValue: changePositions ? runningPosition.toNumber() : accumulatedPositionValue,
accumulatedTransferStates: accumulatedTransferStatesCopy, // finalized transfer state after fulfil processing
+ accumulatedFxTransferStates: accumulatedFxTransferStatesCopy, // finalized transfer state after fx fulfil processing
accumulatedPositionReservedValue, // not used but kept for consistency
accumulatedTransferStateChanges: transferStateChanges, // transfer state changes to be persisted in order
- accumulatedPositionChanges: participantPositionChanges, // participant position changes to be persisted in order
- notifyMessages: resultMessages // array of objects containing bin item and result message. {binItem, message}
+ accumulatedFxTransferStateChanges: fxTransferStateChanges, // fx-transfer state changes to be persisted in order
+ accumulatedPositionChanges: changePositions ? participantPositionChanges : [], // participant position changes to be persisted in order
+ notifyMessages: resultMessages, // array of objects containing bin item and result message. {binItem, message}
+ followupMessages // array of objects containing bin item, message key and followup message. {binItem, messageKey, message}
+ }
+}
+
+const _handleIncorrectTransferState = (binItem, payeeFsp, transferId, accumulatedTransferStates) => {
+ // forward same headers from the prepare message, except the content-length header
+ // set destination to payeefsp and source to switch
+ const headers = { ...binItem.message.value.content.headers }
+ headers[Enum.Http.Headers.FSPIOP.DESTINATION] = payeeFsp
+ headers[Enum.Http.Headers.FSPIOP.SOURCE] = Config.HUB_NAME
+ delete headers['content-length']
+
+ const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError(
+ `Invalid State: ${accumulatedTransferStates[transferId]} - expected: ${Enum.Transfers.TransferInternalState.RECEIVED_FULFIL}`
+ ).toApiErrorObject(Config.ERROR_HANDLING)
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.FAILURE.status,
+ fspiopError.errorInformation.errorCode,
+ fspiopError.errorInformation.errorDescription
+ )
+
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ transferId,
+ Enum.Kafka.Topics.NOTIFICATION,
+ Enum.Events.Event.Action.FULFIL,
+ state
+ )
+
+ return Utility.StreamingProtocol.createMessage(
+ transferId,
+ payeeFsp,
+ Config.HUB_NAME,
+ metadata,
+ headers,
+ fspiopError,
+ { id: transferId },
+ 'application/json'
+ )
+}
+
+const _constructTransferFulfilResultMessage = (binItem, transferId, payerFsp, payeeFsp, transfer, reservedActionTransfers, transferStateId) => {
+ // forward same headers from the prepare message, except the content-length header
+ const headers = { ...binItem.message.value.content.headers }
+ delete headers['content-length']
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.SUCCESS.status,
+ null,
+ null
+ )
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ transferId,
+ Enum.Kafka.Topics.TRANSFER,
+ Enum.Events.Event.Action.COMMIT,
+ state
+ )
+
+ const resultMessage = Utility.StreamingProtocol.createMessage(
+ transferId,
+ payerFsp,
+ payeeFsp,
+ metadata,
+ headers,
+ transfer,
+ { id: transferId },
+ 'application/json'
+ )
+
+ if (binItem.message.value.metadata.event.action === Enum.Events.Event.Action.RESERVE) {
+ resultMessage.content.payload = TransferObjectTransform.toFulfil(
+ reservedActionTransfers[transferId]
+ )
+ resultMessage.content.payload.transferState = transferStateId
+ }
+ return resultMessage
+}
+
+const _constructPatchNotificationResultMessage = (binItem, cyrilResult) => {
+ const messages = []
+ const patchNotifications = cyrilResult.patchNotifications
+ for (const patchNotification of patchNotifications) {
+ const commitRequestId = patchNotification.commitRequestId
+ const fxpName = patchNotification.fxpName
+ const fulfilment = patchNotification.fulfilment
+ const completedTimestamp = patchNotification.completedTimestamp
+ const headers = {
+ ...binItem.message.value.content.headers,
+ 'fspiop-source': Config.HUB_NAME,
+ 'fspiop-destination': fxpName
+ }
+
+ const fulfil = {
+ conversionState: Enum.Transfers.TransferState.COMMITTED,
+ fulfilment,
+ completedTimestamp
+ }
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.SUCCESS.status,
+ null,
+ null
+ )
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ commitRequestId,
+ Enum.Kafka.Topics.TRANSFER,
+ Enum.Events.Event.Action.FX_NOTIFY,
+ state
+ )
+
+ const resultMessage = Utility.StreamingProtocol.createMessage(
+ commitRequestId,
+ fxpName,
+ Config.HUB_NAME,
+ metadata,
+ headers,
+ fulfil,
+ { id: commitRequestId },
+ 'application/json'
+ )
+
+ messages.push(resultMessage)
+ }
+ return messages
+}
+
+const _handleParticipantPositionChange = (runningPosition, transferAmount, transferId, accumulatedPositionReservedValue) => {
+ const transferStateId = Enum.Transfers.TransferState.COMMITTED
+ // Amounts in `transferParticipant` for the payee are stored as negative values
+ const updatedRunningPosition = new MLNumber(runningPosition.add(transferAmount).toFixed(Config.AMOUNT.SCALE))
+
+ const participantPositionChange = {
+ transferId, // Need to delete this in bin processor while updating transferStateChangeId
+ transferStateChangeId: null, // Need to update this in bin processor while executing queries
+ value: updatedRunningPosition.toNumber(),
+ change: transferAmount,
+ reservedValue: accumulatedPositionReservedValue
+ }
+
+ const transferStateChange = {
+ transferId,
+ transferStateId,
+ reason: undefined
+ }
+ return { participantPositionChange, transferStateChange, transferStateId, updatedRunningPosition }
+}
+
+const _handleParticipantPositionChangeFx = (runningPosition, transferAmount, commitRequestId, accumulatedPositionReservedValue) => {
+ const transferStateId = Enum.Transfers.TransferState.COMMITTED
+ // Amounts in `transferParticipant` for the payee are stored as negative values
+ const updatedRunningPosition = new MLNumber(runningPosition.add(transferAmount).toFixed(Config.AMOUNT.SCALE))
+
+ const participantPositionChange = {
+ commitRequestId, // Need to delete this in bin processor while updating fxTransferStateChangeId
+ fxTransferStateChangeId: null, // Need to update this in bin processor while executing queries
+ value: updatedRunningPosition.toNumber(),
+ change: transferAmount,
+ reservedValue: accumulatedPositionReservedValue
+ }
+
+ const fxTransferStateChange = {
+ commitRequestId,
+ transferStateId,
+ reason: null
}
+ return { participantPositionChange, fxTransferStateChange, transferStateId, updatedRunningPosition }
}
module.exports = {
diff --git a/src/domain/position/fx-fulfil.js b/src/domain/position/fx-fulfil.js
new file mode 100644
index 000000000..5c9226822
--- /dev/null
+++ b/src/domain/position/fx-fulfil.js
@@ -0,0 +1,173 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+
+const { Enum } = require('@mojaloop/central-services-shared')
+const ErrorHandler = require('@mojaloop/central-services-error-handling')
+const Config = require('../../lib/config')
+const Utility = require('@mojaloop/central-services-shared').Util
+const Logger = require('@mojaloop/central-services-logger')
+
+/**
+ * @function processPositionFxFulfilBin
+ *
+ * @async
+ * @description This is the domain function to process a bin of position-fx-fulfil messages of a single participant account.
+ *
+ * @param {array} binItems - an array of objects that contain a position fx reserve message and its span. {message, span}
+ * @param {object} options
+ * @param {object} accumulatedFxTransferStates - object with fx transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
+ * @returns {object} - Returns an object containing accumulatedFxTransferStateChanges, accumulatedFxTransferStates, resultMessages, limitAlarms or throws an error if failed
+ */
+const processPositionFxFulfilBin = async (
+ binItems,
+ {
+ accumulatedFxTransferStates
+ }
+) => {
+ const fxTransferStateChanges = []
+ const resultMessages = []
+ const accumulatedFxTransferStatesCopy = Object.assign({}, accumulatedFxTransferStates)
+
+ if (binItems && binItems.length > 0) {
+ for (const binItem of binItems) {
+ let transferStateId
+ let reason
+ let resultMessage
+ const commitRequestId = binItem.message.value.content.uriParams.id
+ const counterPartyFsp = binItem.message.value.from
+ const initiatingFsp = binItem.message.value.to
+ const fxTransfer = binItem.decodedPayload
+ Logger.isDebugEnabled && Logger.debug(`processPositionFxFulfilBin::fxTransfer:processingMessage: ${JSON.stringify(fxTransfer)}`)
+ Logger.isDebugEnabled && Logger.debug(`accumulatedFxTransferStates: ${JSON.stringify(accumulatedFxTransferStates)}`)
+ Logger.isDebugEnabled && Logger.debug(`accumulatedFxTransferStates[commitRequestId]: ${accumulatedFxTransferStates[commitRequestId]}`)
+ // Inform sender if transfer is not in RECEIVED_FULFIL_DEPENDENT state, skip making any transfer state changes
+ if (accumulatedFxTransferStates[commitRequestId] !== Enum.Transfers.TransferInternalState.RECEIVED_FULFIL_DEPENDENT) {
+ // forward same headers from the request, except the content-length header
+ // set destination to counterPartyFsp and source to switch
+ const headers = { ...binItem.message.value.content.headers }
+ headers[Enum.Http.Headers.FSPIOP.DESTINATION] = counterPartyFsp
+ headers[Enum.Http.Headers.FSPIOP.SOURCE] = Config.HUB_NAME
+ delete headers['content-length']
+
+ // There is no such logic in the fulfil handler.
+ transferStateId = Enum.Transfers.TransferInternalState.ABORTED_REJECTED
+ reason = 'FxFulfil in incorrect state'
+
+ const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError(
+ `Invalid State: ${accumulatedFxTransferStates[commitRequestId]} - expected: ${Enum.Transfers.TransferInternalState.RECEIVED_FULFIL_DEPENDENT}`
+ ).toApiErrorObject(Config.ERROR_HANDLING)
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.FAILURE.status,
+ fspiopError.errorInformation.errorCode,
+ fspiopError.errorInformation.errorDescription
+ )
+
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ commitRequestId,
+ Enum.Kafka.Topics.NOTIFICATION,
+ Enum.Events.Event.Action.FX_FULFIL,
+ state
+ )
+
+ resultMessage = Utility.StreamingProtocol.createMessage(
+ commitRequestId,
+ counterPartyFsp,
+ Config.HUB_NAME,
+ metadata,
+ headers,
+ fspiopError,
+ { id: commitRequestId },
+ 'application/json'
+ )
+ } else {
+ // forward same headers from the prepare message, except the content-length header
+ const headers = { ...binItem.message.value.content.headers }
+ delete headers['content-length']
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.SUCCESS.status,
+ null,
+ null
+ )
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ commitRequestId,
+ Enum.Kafka.Topics.TRANSFER,
+ Enum.Events.Event.Action.COMMIT,
+ state
+ )
+
+ resultMessage = Utility.StreamingProtocol.createMessage(
+ commitRequestId,
+ initiatingFsp,
+ counterPartyFsp,
+ metadata,
+ headers,
+ fxTransfer,
+ { id: commitRequestId },
+ 'application/json'
+ )
+
+ // No need to change the transfer state here for success case.
+
+ binItem.result = { success: true }
+ }
+
+ resultMessages.push({ binItem, message: resultMessage })
+
+ if (transferStateId) {
+ const fxTransferStateChange = {
+ commitRequestId,
+ transferStateId,
+ reason
+ }
+ fxTransferStateChanges.push(fxTransferStateChange)
+ Logger.isDebugEnabled && Logger.debug(`processPositionFxFulfilBin::fxTransferStateChange: ${JSON.stringify(fxTransferStateChange)}`)
+
+ accumulatedFxTransferStatesCopy[commitRequestId] = transferStateId
+ Logger.isDebugEnabled && Logger.debug(`processPositionFxFulfilBin::accumulatedTransferStatesCopy:finalizedFxTransferState ${JSON.stringify(transferStateId)}`)
+ }
+ }
+ }
+
+ return {
+ accumulatedFxTransferStates: accumulatedFxTransferStatesCopy, // finalized fx transfer state after fx-fulfil processing
+ accumulatedFxTransferStateChanges: fxTransferStateChanges, // fx transfer state changes to be persisted in order
+ notifyMessages: resultMessages // array of objects containing bin item and result message. {binItem, message}
+ }
+}
+
+module.exports = {
+ processPositionFxFulfilBin
+}
diff --git a/src/domain/position/fx-prepare.js b/src/domain/position/fx-prepare.js
new file mode 100644
index 000000000..f5741f5ba
--- /dev/null
+++ b/src/domain/position/fx-prepare.js
@@ -0,0 +1,315 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev
+ - Steven Oderayi
+ - Eugen Klymniuk
+
+ --------------
+
+ ******/
+
+const { Enum } = require('@mojaloop/central-services-shared')
+const ErrorHandler = require('@mojaloop/central-services-error-handling')
+const Config = require('../../lib/config')
+const Utility = require('@mojaloop/central-services-shared').Util
+const MLNumber = require('@mojaloop/ml-number')
+const Logger = require('@mojaloop/central-services-logger')
+
+/**
+ * @function processFxPositionPrepareBin
+ *
+ * @async
+ * @description This is the domain function to process a bin of position-prepare messages of a single participant account.
+ *
+ * @param {array} binItems - an array of objects that contain a position prepare message and its span. {message, decodedPayload, span}
+ * @param {object} options
+ * @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
+ * @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
+ * @param {object} accumulatedFxTransferStates - object with fx commit request id keys and fx transfer state id values. Used to check if fx transfer is in correct state for processing. Clone and update states for output.
+ * @param {number} settlementParticipantPosition - position value of the participants settlement account
+ * @param {object} participantLimit - participant limit object for the currency
+ * @param {boolean} changePositions - whether to change positions or not
+ * @returns {object} - Returns an object containing accumulatedPositionValue, accumulatedPositionReservedValue, accumulatedFxTransferStateChanges, accumulatedTransferStates, resultMessages, limitAlarms or throws an error if failed
+ */
+const processFxPositionPrepareBin = async (
+ binItems,
+ {
+ accumulatedPositionValue,
+ accumulatedPositionReservedValue,
+ accumulatedFxTransferStates,
+ settlementParticipantPosition,
+ participantLimit,
+ changePositions = true
+ }
+) => {
+ const fxTransferStateChanges = []
+ const participantPositionChanges = []
+ const resultMessages = []
+ const limitAlarms = []
+ const accumulatedFxTransferStatesCopy = Object.assign({}, accumulatedFxTransferStates)
+
+ let currentPosition = new MLNumber(accumulatedPositionValue)
+ let liquidityCover = 0
+ let availablePositionBasedOnLiquidityCover = 0
+ let availablePositionBasedOnPayerLimit = 0
+
+ if (changePositions) {
+ const reservedPosition = new MLNumber(accumulatedPositionReservedValue)
+ const effectivePosition = new MLNumber(currentPosition.add(reservedPosition).toFixed(Config.AMOUNT.SCALE))
+ const payerLimit = new MLNumber(participantLimit.value)
+ liquidityCover = new MLNumber(settlementParticipantPosition).multiply(-1)
+ availablePositionBasedOnLiquidityCover = new MLNumber(liquidityCover.subtract(effectivePosition).toFixed(Config.AMOUNT.SCALE))
+ Logger.isInfoEnabled && Logger.info(`processFxPositionPrepareBin::availablePositionBasedOnLiquidityCover: ${availablePositionBasedOnLiquidityCover}`)
+ availablePositionBasedOnPayerLimit = new MLNumber(payerLimit.subtract(effectivePosition).toFixed(Config.AMOUNT.SCALE))
+ Logger.isDebugEnabled && Logger.debug(`processFxPositionPrepareBin::availablePositionBasedOnPayerLimit: ${availablePositionBasedOnPayerLimit}`)
+ }
+
+ if (binItems && binItems.length > 0) {
+ for (const binItem of binItems) {
+ let transferStateId
+ let reason
+ let resultMessage
+ const fxTransfer = binItem.decodedPayload
+ const cyrilResult = binItem.message.value.content.context.cyrilResult
+ const transferAmount = fxTransfer.targetAmount.currency === cyrilResult.currencyId ? fxTransfer.targetAmount.amount : fxTransfer.sourceAmount.amount
+
+ Logger.isDebugEnabled && Logger.debug(`processFxPositionPrepareBin::transfer:processingMessage: ${JSON.stringify(fxTransfer)}`)
+
+ // Check if fxTransfer is in correct state for processing, produce an internal error message
+ if (accumulatedFxTransferStates[fxTransfer.commitRequestId] !== Enum.Transfers.TransferInternalState.RECEIVED_PREPARE) {
+ Logger.isDebugEnabled && Logger.debug(`processFxPositionPrepareBin::transferState: ${accumulatedFxTransferStates[fxTransfer.commitRequestId]} !== ${Enum.Transfers.TransferInternalState.RECEIVED_PREPARE}`)
+
+ transferStateId = Enum.Transfers.TransferInternalState.ABORTED_REJECTED
+ reason = 'FxTransfer in incorrect state'
+
+ // forward same headers from the prepare message, except the content-length header
+ // set destination to initiatingFsp and source to switch
+ const headers = { ...binItem.message.value.content.headers }
+ headers[Enum.Http.Headers.FSPIOP.DESTINATION] = fxTransfer.initiatingFsp
+ headers[Enum.Http.Headers.FSPIOP.SOURCE] = Config.HUB_NAME
+ delete headers['content-length']
+
+ const fspiopError = ErrorHandler.Factory.createFSPIOPError(
+ ErrorHandler.Enums.FSPIOPErrorCodes.INTERNAL_SERVER_ERROR
+ ).toApiErrorObject(Config.ERROR_HANDLING)
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.FAILURE.status,
+ fspiopError.errorInformation.errorCode,
+ fspiopError.errorInformation.errorDescription
+ )
+
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ fxTransfer.commitRequestId,
+ Enum.Kafka.Topics.NOTIFICATION,
+ Enum.Events.Event.Action.FX_PREPARE,
+ state
+ )
+
+ resultMessage = Utility.StreamingProtocol.createMessage(
+ fxTransfer.commitRequestId,
+ fxTransfer.initiatingFsp,
+ Config.HUB_NAME,
+ metadata,
+ headers,
+ fspiopError,
+ { id: fxTransfer.commitRequestId },
+ 'application/json'
+ )
+
+ binItem.result = { success: false }
+
+ // Check if payer has insufficient liquidity, produce an error message and abort transfer
+ } else if (changePositions && availablePositionBasedOnLiquidityCover.toNumber() < transferAmount) {
+ transferStateId = Enum.Transfers.TransferInternalState.ABORTED_REJECTED
+ reason = ErrorHandler.Enums.FSPIOPErrorCodes.PAYER_FSP_INSUFFICIENT_LIQUIDITY.message
+
+ // forward same headers from the prepare message, except the content-length header
+ // set destination to payerfsp and source to switch
+ const headers = { ...binItem.message.value.content.headers }
+ headers[Enum.Http.Headers.FSPIOP.DESTINATION] = fxTransfer.initiatingFsp
+ headers[Enum.Http.Headers.FSPIOP.SOURCE] = Config.HUB_NAME
+ delete headers['content-length']
+
+ const fspiopError = ErrorHandler.Factory.createFSPIOPError(
+ ErrorHandler.Enums.FSPIOPErrorCodes.PAYER_FSP_INSUFFICIENT_LIQUIDITY
+ ).toApiErrorObject(Config.ERROR_HANDLING)
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.FAILURE.status,
+ fspiopError.errorInformation.errorCode,
+ fspiopError.errorInformation.errorDescription
+ )
+
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ fxTransfer.commitRequestId,
+ Enum.Kafka.Topics.NOTIFICATION,
+ Enum.Events.Event.Action.FX_PREPARE,
+ state
+ )
+
+ resultMessage = Utility.StreamingProtocol.createMessage(
+ fxTransfer.commitRequestId,
+ fxTransfer.initiatingFsp,
+ Config.HUB_NAME,
+ metadata,
+ headers,
+ fspiopError,
+ { id: fxTransfer.commitRequestId },
+ 'application/json'
+ )
+
+ binItem.result = { success: false }
+
+ // Check if payer has surpassed their limit, produce an error message and abort transfer
+ } else if (changePositions && availablePositionBasedOnPayerLimit.toNumber() < transferAmount) {
+ transferStateId = Enum.Transfers.TransferInternalState.ABORTED_REJECTED
+ reason = ErrorHandler.Enums.FSPIOPErrorCodes.PAYER_LIMIT_ERROR.message
+
+ // forward same headers from the prepare message, except the content-length header
+ // set destination to payerfsp and source to switch
+ const headers = { ...binItem.message.value.content.headers }
+ headers[Enum.Http.Headers.FSPIOP.DESTINATION] = fxTransfer.initiatingFsp
+ headers[Enum.Http.Headers.FSPIOP.SOURCE] = Config.HUB_NAME
+ delete headers['content-length']
+
+ const fspiopError = ErrorHandler.Factory.createFSPIOPError(
+ ErrorHandler.Enums.FSPIOPErrorCodes.PAYER_LIMIT_ERROR
+ ).toApiErrorObject(Config.ERROR_HANDLING)
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.FAILURE.status,
+ fspiopError.errorInformation.errorCode,
+ fspiopError.errorInformation.errorDescription
+ )
+
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ fxTransfer.commitRequestId,
+ Enum.Kafka.Topics.NOTIFICATION,
+ Enum.Events.Event.Action.FX_PREPARE,
+ state
+ )
+
+ resultMessage = Utility.StreamingProtocol.createMessage(
+ fxTransfer.commitRequestId,
+ fxTransfer.initiatingFsp,
+ Config.HUB_NAME,
+ metadata,
+ headers,
+ fspiopError,
+ { id: fxTransfer.commitRequestId },
+ 'application/json'
+ )
+
+ binItem.result = { success: false }
+
+ // Payer has sufficient liquidity and limit
+ } else {
+ transferStateId = Enum.Transfers.TransferInternalState.RESERVED
+
+ if (changePositions) {
+ currentPosition = currentPosition.add(transferAmount)
+ availablePositionBasedOnLiquidityCover = availablePositionBasedOnLiquidityCover.add(transferAmount)
+ availablePositionBasedOnPayerLimit = availablePositionBasedOnPayerLimit.add(transferAmount)
+ const participantPositionChange = {
+ commitRequestId: fxTransfer.commitRequestId, // Need to delete this in bin processor while updating fxTransferStateChangeId
+ fxTransferStateChangeId: null, // Need to update this in bin processor while executing queries
+ value: currentPosition.toNumber(),
+ change: transferAmount,
+ reservedValue: accumulatedPositionReservedValue
+ }
+ participantPositionChanges.push(participantPositionChange)
+ Logger.isDebugEnabled && Logger.debug(`processFxPositionPrepareBin::participantPositionChange: ${JSON.stringify(participantPositionChange)}`)
+ }
+
+ // forward same headers from the prepare message, except the content-length header
+ const headers = { ...binItem.message.value.content.headers }
+ delete headers['content-length']
+
+ const state = Utility.StreamingProtocol.createEventState(
+ Enum.Events.EventStatus.SUCCESS.status,
+ null,
+ null
+ )
+ const metadata = Utility.StreamingProtocol.createMetadataWithCorrelatedEvent(
+ fxTransfer.commitRequestId,
+ Enum.Kafka.Topics.TRANSFER,
+ Enum.Events.Event.Action.FX_PREPARE,
+ state
+ )
+
+ resultMessage = Utility.StreamingProtocol.createMessage(
+ fxTransfer.commitRequestId,
+ fxTransfer.counterPartyFsp,
+ fxTransfer.initiatingFsp,
+ metadata,
+ headers,
+ fxTransfer,
+ {},
+ 'application/json'
+ )
+
+ binItem.result = { success: true }
+ }
+
+ resultMessages.push({ binItem, message: resultMessage })
+
+ if (changePositions) {
+ Logger.isDebugEnabled && Logger.debug(`processFxPositionPrepareBin::limitAlarm: ${currentPosition.toNumber()} > ${liquidityCover.multiply(participantLimit.thresholdAlarmPercentage)}`)
+ if (currentPosition.toNumber() > liquidityCover.multiply(participantLimit.thresholdAlarmPercentage).toNumber()) {
+ limitAlarms.push(participantLimit)
+ }
+ }
+
+ const fxTransferStateChange = {
+ commitRequestId: fxTransfer.commitRequestId,
+ transferStateId,
+ reason
+ }
+ fxTransferStateChanges.push(fxTransferStateChange)
+ Logger.isDebugEnabled && Logger.debug(`processFxPositionPrepareBin::fxTransferStateChange: ${JSON.stringify(fxTransferStateChange)}`)
+
+ accumulatedFxTransferStatesCopy[fxTransfer.commitRequestId] = transferStateId
+ Logger.isDebugEnabled && Logger.debug(`processFxPositionPrepareBin::accumulatedTransferStatesCopy:finalizedTransferState ${JSON.stringify(transferStateId)}`)
+ }
+ }
+
+ return {
+ accumulatedPositionValue: changePositions ? currentPosition.toNumber() : accumulatedPositionValue,
+ accumulatedFxTransferStates: accumulatedFxTransferStatesCopy, // finalized transfer state after prepare processing
+ accumulatedPositionReservedValue, // not used but kept for consistency
+ accumulatedFxTransferStateChanges: fxTransferStateChanges, // fx-transfer state changes to be persisted in order
+ limitAlarms, // array of participant limits that have been breached
+ accumulatedPositionChanges: changePositions ? participantPositionChanges : [], // participant position changes to be persisted in order
+ notifyMessages: resultMessages // array of objects containing bin item and result message. {binItem, message}
+ }
+}
+
+module.exports = {
+ processFxPositionPrepareBin
+}
diff --git a/src/domain/position/fx-timeout-reserved.js b/src/domain/position/fx-timeout-reserved.js
new file mode 100644
index 000000000..e6b854158
--- /dev/null
+++ b/src/domain/position/fx-timeout-reserved.js
@@ -0,0 +1,194 @@
+/*****
+ License
+ --------------
+ Copyright © 2020-2024 Mojaloop Foundation
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+ Contributors
+ --------------
+ This is the official list of the Mojaloop project contributors for this file.
+ Names of the original copyright holders (individuals or organizations)
+ should be listed with a '*' in the first column. People who have
+ contributed from an organization can be listed under the organization
+ that actually holds the copyright for their contributions (see the
+ Mojaloop Foundation for an example). Those individuals should have
+ their names indented and be marked with a '-'. Email address can be added
+ optionally within square brackets .
+
+ * Mojaloop Foundation
+ - Name Surname
+
+ * Infitx
+ - Vijay Kumar Guthi
+ - Kevin Leyow
+ - Kalin Krustev