diff --git a/.circleci/config.yml b/.circleci/config.yml index f9bba816..a634f6f7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,7 +43,7 @@ jobs: name: Deploy command: > helm upgrade - lecoffre-back devops/ -i -f devops/<>.values.yaml + lecoffre-back devops/ -i -f devops/values.yaml -n lecoffre --create-namespace --set lecoffreBack.image.repository='rg.fr-par.scw.cloud/lecoffre/back' diff --git a/.env.test b/.env.test new file mode 100644 index 00000000..01e23bcd --- /dev/null +++ b/.env.test @@ -0,0 +1,7 @@ +DATABASE_URL="postgresql://prisma:prisma@localhost:5433/tests" +DATABASE_PORT="5433" +DATABASE_USER="prisma" +DATABASE_PASSWORD="prisma" +DATABASE_NAME="tests" +DATABASE_HOSTNAME="localhost" +DEV_PRISMA_STUDIO_DB_URL="postgresql://prisma:prisma@localhost:5433/tests" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 390a4ec7..178e062e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,6 @@ COPY --from=deps leCoffre/package.json package.json COPY tsconfig.json tsconfig.json COPY src src -COPY src/common/databases/schema.prisma ./src/common/databases/schema.prisma RUN npx prisma generate RUN npm run build @@ -39,8 +38,9 @@ RUN adduser -D lecoffreuser --uid 10000 && chown -R lecoffreuser . COPY --from=builder --chown=lecoffreuser leCoffre/node_modules ./node_modules COPY --from=builder --chown=lecoffreuser leCoffre/dist dist COPY --from=builder --chown=lecoffreuser leCoffre/package.json ./package.json +COPY --from=builder --chown=lecoffreuser leCoffre/src/common/databases ./src/common/databases USER lecoffreuser -CMD ["npm", "run", "api:start"] +CMD ["npm", "run", "start"] EXPOSE 3001 \ No newline at end of file diff --git a/README.md b/README.md index f5a7b54b..98e7cf4a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ### A. Docker Launch application #### 1) Local RSA Key for docker build -1) Create a file named : `id_rsa` in /src +1) Create a file named : `id_rsa` in /src/.ssh 2) Get the RSA Private key on Keeper who is allowed to read the `leCoffre-ressources repo` 3) You can find Key on Keeper inside the folder **LeCoffre project > SSH Key** 4) Copy past in the `id_rsa` that you created step 1 @@ -16,15 +16,11 @@ #### 2) Build images ###### a- Back end -`docker build -t "le-coffre-back" -f Dockerfiles/Dockerfile.api .` +`docker build -t "le-coffre-back" -f Dockerfile .` ###### b- Front end -`docker build -t "le-coffre-front" -f Dockerfiles/Dockerfile.front .` +`docker build -t "le-coffre-front" -f Dockerfile .` -#### 3) Docker Run - -`docker run --env-file .env -p 3000:3000 le-coffre-back` - -#### 4) Docker Compose +#### 3) Docker Compose Docker compose allow to launch multiples images 1) **le-coffre-front** @@ -33,4 +29,6 @@ Docker compose allow to launch multiples images > Launch your docker container with following command : +`docker compose up` -> Logs in terminal + `docker compose up -d` \ No newline at end of file diff --git a/devops/Chart.yaml b/devops/Chart.yaml index 811868f9..208511fb 100644 --- a/devops/Chart.yaml +++ b/devops/Chart.yaml @@ -21,5 +21,5 @@ version: 0.0.1 # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: 0.4.4 +appVersion: 0.5.6 diff --git a/devops/values.yaml b/devops/values.yaml new file mode 100644 index 00000000..a286f980 --- /dev/null +++ b/devops/values.yaml @@ -0,0 +1,44 @@ +dockerPullSecret: secret/data/minteed-stg/config/dockerpullsecret + +namespace: lecoffre + +lecoffreBack: + serviceAccountName: lecoffre-back-sa + command: "'sh', '-c', '. /vault/secrets/envs-api && npm run api:start'" + vault: + role : custom_lecoffre-back_injector_rol + server: https://vault-stg.smart-chain.fr + annotations: + vault.hashicorp.com/agent-pre-populate-only: "true" + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/agent-inject-secret-envs-api: secret/data/lecoffre-back-stg/config/envs-api + vault.hashicorp.com/role: custom_lecoffre-back_injector_rol + vault.hashicorp.com/agent-inject-template-envs-api: | + {{ with secret "secret/data/lecoffre-back-stg/config/envs-api" }} + {{ range $k, $v := .Data.data }} + export {{ $k }}="{{ $v }}" + {{ end }} + {{ end }} + imagePullSecrets: + - name: docker-pull-secret + image: + pullPolicy: Always + repository: "rg.fr-par.scw.cloud/lecoffre/back" + resources: + requests: + cpu: 200m + memory: 1Gi + limits: + memory: 2Gi + ingress: + host: api.stg.lecoffre.smart-chain.fr + tls: + hosts: + - api.stg.lecoffre.smart-chain.fr + secretName: api-tls + annotations: + kubernetes.io/ingress.class: nginx + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/from-to-www-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + diff --git a/docker-compose-test.yml b/docker-compose-test.yml new file mode 100644 index 00000000..f5f56f3b --- /dev/null +++ b/docker-compose-test.yml @@ -0,0 +1,12 @@ +version: "3.8" +services: + db: + image: postgres:13 + restart: always + container_name: integration-tests-prisma + ports: + - '5433:5432' + environment: + POSTGRES_USER: prisma + POSTGRES_PASSWORD: prisma + POSTGRES_DB: tests \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 92f5eff6..800e53af 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,17 +7,27 @@ services: front-end: image: "le-coffre-front" ports: - - 3000:${FRONT_PORT} + - ${FRONT_PORT}:${FRONT_PORT} environment: - FRONT_PORT + - BACK_API_PROTOCOL + - BACK_API_HOST + - BACK_API_PORT + - BACK_API_ROOT_URL + - BACK_API_VERSION + - FRONT_APP_HOST + - FRONT_APP_PORT + - IDNOT_AUTHORIZE_ENDPOINT + - IDNOT_CLIENT_ID + backend: image: "le-coffre-back" ports: - - 3001:${APP_PORT} + - ${APP_PORT}:${APP_PORT} environment: - - DATABASE_HOSTNAME + - DATABASE_HOST - DATABASE_PORT - - DATABASE_USER + - DATABASE_USERNAME - DATABASE_PASSWORD - DATABASE_NAME - APP_LABEL @@ -25,17 +35,21 @@ services: - APP_ROOT_URL - API_ROOT_URL - DEV_PRISMA_STUDIO_DB_URL + - IDNOT_CONNEXION_URL + - IDNOT_CLIENT_ID + - IDNOT_CLIENT_SECRET + - IDNOT_REDIRECT_URL postgres: - image: postgres + image: postgres:11 restart: always environment: - - DATABASE_HOSTNAME - - DATABASE_PORT - - DATABASE_USER - - DATABASE_PASSWORD - - DATABASE_NAME + - POSTGRES_USER - POSTGRES_PASSWORD + - POSTGRES_DB + - DATABASE_USERNAME + - DATABASE_PASSWORD + - DATABASE_NAME=${DATABASE_NAME} ports: - ${DATABASE_PORT}:5432 volumes: @@ -43,7 +57,11 @@ services: - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh healthcheck: - test: ["CMD-SHELL", "pg_isready -h localhost -U ${DATABASE_USER} -d ${DATABASE_NAME}"] + test: + [ + "CMD-SHELL", + "pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}", + ] interval: 5s timeout: 5s retries: 10 \ No newline at end of file diff --git a/init-data.sh b/init-data.sh new file mode 100755 index 00000000..552a9078 --- /dev/null +++ b/init-data.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e; + +# Make sure this script doesn't encounter any errors while building the docker container for the first time +# Carriage returns might be a problem (the first line #!/bin/bash will create an error) +# On Windows Docker Desktop i had to use the following command (in linux env): +# $ sed -i -e 's/\r$//' init-data.sh + +if [ -n "${DATABASE_USERNAME:-}" ] && [ -n "${DATABASE_PASSWORD:-}" ]; then + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE USER ${DATABASE_USERNAME} WITH PASSWORD '${DATABASE_PASSWORD}'; + ALTER USER ${DATABASE_USERNAME} CREATEDB; + EOSQL +else + echo "SETUP INFO: No Environment variables given!" +fi \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..6784f0af --- /dev/null +++ b/jest.config.js @@ -0,0 +1,19 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + "moduleNameMapper": { + "@Services/(.*)": "/src/services/$1", + "@App/(.*)": "/src/app/$1", + "@Api/(.*)": "/src/app/api/$1", + "@Pages/(.*)": "/src/pages/$1", + "@Common/(.*)": "/src/common/$1", + "@Repositories/(.*)": "/src/common/repositories/$1", + "@Entries/(.*)": "/src/common/entries/$1", + "@Config/(.*)": "/src/common/config/$1", + "@Entities/(.*)": "/src/common/entities/$1", + "@System/(.*)": "/src/common/system/$1", + "@ControllerPattern/(.*)": "/src/common/system/controller-pattern/$1", + "@Test/(.*)": "/src/test/$1" + } +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1cd68512..2b3ba769 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "lecoffre-back", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,16 +9,17 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@prisma/client": "^4.9.0", - "axios": "^1.3.3", + "@pinata/sdk": "^2.1.0", + "@prisma/client": "^4.11.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "classnames": "^2.3.2", "cors": "^2.8.5", - "dotenv": "^16.0.3", "express": "^4.18.2", - "le-coffre-ressources": "github.com:smart-chain-fr/leCoffre-resources.git", + "jsonwebtoken": "^9.0.0", + "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.47", "module-alias": "^2.2.2", + "multer": "^1.4.5-lts.1", "next": "^13.1.5", "node-cache": "^5.1.2", "node-schedule": "^2.1.1", @@ -28,23 +29,648 @@ "tslib": "^2.4.1", "typedi": "^0.10.0", "typescript": "^4.9.4", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "uuidv4": "^6.2.13" }, "devDependencies": { "@types/cors": "^2.8.13", "@types/express": "^4.17.16", + "@types/jest": "^29.5.0", + "@types/jsonwebtoken": "^9.0.1", + "@types/multer": "^1.4.7", "@types/node": "^18.11.18", "@types/node-schedule": "^2.1.0", "@types/uuid": "^9.0.0", + "dotenv": "^16.0.3", + "jest": "^29.5.0", "nodemon": "^2.0.20", "prettier": "2.8.4", - "prisma": "^4.11.0" + "prisma": "^4.11.0", + "ts-jest": "^29.0.5" } }, - "github.com:smart-chain-fr/leCoffre-resources.git": {}, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", + "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", + "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helpers": "^7.21.5", + "@babel/parser": "^7.21.8", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@babel/generator": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz", + "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", + "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.21.5", + "@babel/helper-validator-option": "^7.21.0", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", + "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", + "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", + "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-module-imports": "^7.21.4", + "@babel/helper-simple-access": "^7.21.5", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", + "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", + "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", + "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz", + "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.21.4", + "@babel/generator": "^7.21.5", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.5", + "@babel/types": "^7.21.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@babel/types": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", + "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -52,35 +678,382 @@ "node": ">=12" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "dev": true, + "dependencies": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, "node_modules/@next/env": { - "version": "13.2.4", - "license": "MIT" + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.1.tgz", + "integrity": "sha512-eD6WCBMFjLFooLM19SIhSkWBHtaFrZFfg2Cxnyl3vS3DAdFRfnx5TY2RxlkuKXdIRCC0ySbtK9JXXt8qLCqzZg==" }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.2.4", + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.1.tgz", + "integrity": "sha512-eF8ARHtYfnoYtDa6xFHriUKA/Mfj/cCbmKb3NofeKhMccs65G6/loZ15a6wYCCx4rPAd6x4t1WmVYtri7EdeBg==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -89,12 +1062,144 @@ "node": ">= 10" } }, - "node_modules/@prisma/client": { - "version": "4.11.0", - "hasInstallScript": true, - "license": "Apache-2.0", + "node_modules/@next/swc-darwin-x64": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.1.tgz", + "integrity": "sha512-7cmDgF9tGWTgn5Gw+vP17miJbH4wcraMHDCOHTYWkO/VeKT73dUWG23TNRLfgtCNSPgH4V5B4uLHoZTanx9bAw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.1.tgz", + "integrity": "sha512-qwJqmCri2ie8aTtE5gjTSr8S6O8B67KCYgVZhv9gKH44yvc/zXbAY8u23QGULsYOyh1islWE5sWfQNLOj9iryg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.1.tgz", + "integrity": "sha512-qcC54tWNGDv/VVIFkazxhqH1Bnagjfs4enzELVRlUOoJPD2BGJTPI7z08pQPbbgxLtRiu8gl2mXvpB8WlOkMeA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.1.tgz", + "integrity": "sha512-9TeWFlpLsBosZ+tsm/rWBaMwt5It9tPH8m3nawZqFUUrZyGRfGcI67js774vtx0k3rL9qbyY6+3pw9BCVpaYUA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.1.tgz", + "integrity": "sha512-sNDGaWmSqTS4QRUzw61wl4mVPeSqNIr1OOjLlQTRuyInxMxtqImRqdvzDvFTlDfdeUMU/DZhWGYoHrXLlZXe6A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.1.tgz", + "integrity": "sha512-+CXZC7u1iXdLRudecoUYbhbsXpglYv8KFYsFxKBPn7kg+bk7eJo738wAA4jXIl8grTF2mPdmO93JOQym+BlYGA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.1.tgz", + "integrity": "sha512-vIoXVVc7UYO68VwVMDKwJC2+HqAZQtCYiVlApyKEeIPIQpz2gpufzGxk1z3/gwrJt/kJ5CDZjlhYDCzd3hdz+g==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.1.tgz", + "integrity": "sha512-n8V5ImLQZibKTu10UUdI3nIeTLkliEXe628qxqW9v8My3BAH2a7H0SaCqkV2OgqFnn8sG1wxKYw9/SNJ632kSA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@pinata/sdk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@pinata/sdk/-/sdk-2.1.0.tgz", + "integrity": "sha512-hkS0tcKtsjf9xhsEBs2Nbey5s+Db7x5rlOH9TaWHBXkJ7IwwOs2xnEDigNaxAHKjYAwcw+m2hzpO5QgOfeF7Zw==", "dependencies": { - "@prisma/engines-version": "4.11.0-57.8fde8fef4033376662cad983758335009d522acb" + "axios": "^0.21.1", + "form-data": "^2.3.3", + "is-ipfs": "^0.6.0", + "path": "^0.12.7" + } + }, + "node_modules/@prisma/client": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.14.0.tgz", + "integrity": "sha512-MK/XaA2sFdfaOa7I9MjNKz6dxeIEdeZlnpNRoF2w3JuRLlFJLkpp6cD3yaqw2nUUhbrn3Iqe3ZpVV+VuGGil7Q==", + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "4.14.0-67.d9a4c5988f480fa576d43970d5a23641aa77bc9c" }, "engines": { "node": ">=14.17" @@ -109,42 +1214,115 @@ } }, "node_modules/@prisma/engines": { - "version": "4.11.0", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.14.0.tgz", + "integrity": "sha512-PDNlhP/1vyTgmNyiucGqGCdXIp7HIkkvKO50si3y3PcceeHvqtiKPaH1iJdz63jCWMVMbj2MElSxXPOeBvEVIQ==", "devOptional": true, - "hasInstallScript": true, - "license": "Apache-2.0" + "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "4.11.0-57.8fde8fef4033376662cad983758335009d522acb", - "license": "Apache-2.0" + "version": "4.14.0-67.d9a4c5988f480fa576d43970d5a23641aa77bc9c", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.14.0-67.d9a4c5988f480fa576d43970d5a23641aa77bc9c.tgz", + "integrity": "sha512-3jum8/YSudeSN0zGW5qkpz+wAN2V/NYCQ+BPjvHYDfWatLWlQkqy99toX0GysDeaUoBIJg1vaz2yKqiA3CFcQw==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, + "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/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } }, "node_modules/@swc/helpers": { - "version": "0.4.14", - "license": "MIT", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", + "integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==", "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "node_modules/@tsconfig/node16": { "version": "1.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.5.tgz", + "integrity": "sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } }, "node_modules/@types/body-parser": { "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dev": true, - "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -152,24 +1330,27 @@ }, "node_modules/@types/connect": { "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/cors": { "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/express": { "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", "dev": true, - "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -178,68 +1359,178 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.33", + "version": "4.17.34", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.34.tgz", + "integrity": "sha512-fvr49XlCGoUj2Pp730AItckfjat4WNb0lb3kfrLWffd+RLeoGAMsq7UOy04PAPtoL01uKwcp6u8nhzpgpDYr3w==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/@types/mime": { - "version": "3.0.1", + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "18.15.3", - "license": "MIT" - }, - "node_modules/@types/node-schedule": { - "version": "2.1.0", - "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.1.tgz", + "integrity": "sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/multer": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz", + "integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/node": { + "version": "18.16.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.7.tgz", + "integrity": "sha512-MFg7ua/bRtnA1hYE3pVyWxGd/r7aMqjNOdHvlSsXV3n8iaeGKkOaPzpJh6/ovf4bEXWcojkeMJpTsq3mzXW4IQ==" + }, + "node_modules/@types/node-schedule": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/node-schedule/-/node-schedule-2.1.0.tgz", + "integrity": "sha512-NiTwl8YN3v/1YCKrDFSmCTkVxFDylueEqsOFdgF+vPsm+AlyJKGAo5yzX1FiOxPsZiN6/r8gJitYx2EaSuBmmg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, "node_modules/@types/qs": { "version": "6.9.7", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true }, "node_modules/@types/range-parser": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", "dev": true, - "license": "MIT" + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } }, "node_modules/@types/serve-static": { "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", + "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/mime": "*", "@types/node": "*" } }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, "node_modules/@types/uuid": { "version": "9.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==", + "dev": true }, "node_modules/@types/validator": { - "version": "13.7.14", - "license": "MIT" + "version": "13.7.17", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.17.tgz", + "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==" + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true }, "node_modules/abbrev": { "version": "1.1.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -250,7 +1541,8 @@ }, "node_modules/acorn": { "version": "8.8.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "bin": { "acorn": "bin/acorn" }, @@ -260,15 +1552,56 @@ }, "node_modules/acorn-walk": { "version": "8.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "engines": { "node": ">=0.4.0" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -277,43 +1610,180 @@ "node": ">= 8" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, "node_modules/arg": { "version": "4.1.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } }, "node_modules/array-flatten": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/asynckit": { "version": "0.4.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.3.4", - "license": "MIT", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.14.0" + } + }, + "node_modules/babel-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/body-parser": { "version": "1.20.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -335,8 +1805,9 @@ }, "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, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -344,8 +1815,9 @@ }, "node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -353,16 +1825,119 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } }, "node_modules/call-bind": { "version": "1.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -371,8 +1946,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001466", + "version": "1.0.30001486", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz", + "integrity": "sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg==", "funding": [ { "type": "opencollective", @@ -381,12 +1976,42 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { @@ -394,7 +2019,6 @@ "url": "https://paulmillr.com/funding/" } ], - "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -411,13 +2035,58 @@ "fsevents": "~2.3.2" } }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" + }, "node_modules/class-transformer": { "version": "0.5.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" }, "node_modules/class-validator": { "version": "0.14.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.0.tgz", + "integrity": "sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A==", "dependencies": { "@types/validator": "^13.7.10", "libphonenumber-js": "^1.10.14", @@ -426,11 +2095,27 @@ }, "node_modules/classnames": { "version": "2.3.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/client-only": { "version": "0.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } }, "node_modules/clone": { "version": "2.1.2", @@ -440,9 +2125,44 @@ "node": ">=0.8" } }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -452,12 +2172,28 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } }, "node_modules/content-disposition": { "version": "0.5.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dependencies": { "safe-buffer": "5.2.1" }, @@ -467,25 +2203,40 @@ }, "node_modules/content-type": { "version": "1.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/cookie": { "version": "0.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "license": "MIT" + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cors": { "version": "2.8.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -496,11 +2247,13 @@ }, "node_modules/create-require": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "node_modules/cron-parser": { "version": "4.8.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.8.1.tgz", + "integrity": "sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==", "dependencies": { "luxon": "^3.2.1" }, @@ -508,74 +2261,253 @@ "node": ">=12.0.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==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "2.6.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" } }, "node_modules/depd": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { "node": ">= 0.8" } }, "node_modules/destroy": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "4.0.2", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "engines": { "node": ">=0.3.1" } }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/dotenv": { "version": "16.0.3", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, "engines": { "node": ">=12" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.391", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.391.tgz", + "integrity": "sha512-GqydVV1+kUWY5qlEzaw34/hyWTApuQrHiGrcGA2Kk/56nEK44i+YUW45VH43JuZT0Oo7uY8aVtpPhBBZXEWtSA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, "node_modules/etag": { "version": "1.8.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/express": { "version": "4.18.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -613,10 +2545,26 @@ "node": ">= 0.10.0" } }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, "node_modules/fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -626,7 +2574,8 @@ }, "node_modules/finalhandler": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -640,15 +2589,29 @@ "node": ">= 0.8" } }, + "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/follow-redirects": { "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -659,35 +2622,46 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "license": "MIT", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 6" + "node": ">= 0.12" } }, "node_modules/forwarded": { "version": "0.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "0.5.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, "node_modules/fsevents": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -698,11 +2672,31 @@ }, "node_modules/function-bind": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, "node_modules/get-intrinsic": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -712,10 +2706,52 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -723,9 +2759,25 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dependencies": { "function-bind": "^1.1.1" }, @@ -734,16 +2786,18 @@ } }, "node_modules/has-flag": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-symbols": { "version": "1.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -751,9 +2805,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "node_modules/http-errors": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -765,9 +2826,19 @@ "node": ">= 0.8" } }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", - "license": "MIT", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -775,26 +2846,101 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore-by-default": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, - "license": "ISC" + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } }, "node_modules/inherits": { "version": "2.0.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "engines": { + "node": ">=8" + } }, "node_modules/ipaddr.js": { "version": "1.9.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "engines": { "node": ">= 0.10" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -802,18 +2948,50 @@ "node": ">=8" } }, + "node_modules/is-core-module": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", + "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -821,34 +2999,929 @@ "node": ">=0.10.0" } }, + "node_modules/is-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "dependencies": { + "ip-regex": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ipfs": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/is-ipfs/-/is-ipfs-0.6.3.tgz", + "integrity": "sha512-HyRot1dvLcxImtDqPxAaY1miO6WsiP/z7Yxpg2qpaLWv5UdhAPtLvHJ4kMLM0w8GSl8AFsVF23PHe1LzuWrUlQ==", + "dependencies": { + "bs58": "^4.0.1", + "cids": "~0.7.0", + "mafmt": "^7.0.0", + "multiaddr": "^7.2.1", + "multibase": "~0.6.0", + "multihashes": "~0.4.13" + } + }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", + "dev": true, + "dependencies": { + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", + "import-local": "^3.0.2", + "jest-cli": "^29.5.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/js-tokens": { "version": "4.0.0", - "license": "MIT", - "peer": true + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, - "node_modules/le-coffre-ressources": { - "resolved": "github.com:smart-chain-fr/leCoffre-resources.git", - "link": true + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "dependencies": { + "jws": "^3.2.2", + "lodash": "^4.17.21", + "ms": "^2.1.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/le-coffre-resources": { + "resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#467b34a484adbd6dfa3fd6082bb7677f6178da51", + "license": "MIT", + "dependencies": { + "class-transformer": "^0.5.1", + "class-validator": "^0.14.0", + "reflect-metadata": "^0.1.13" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } }, "node_modules/libphonenumber-js": { - "version": "1.10.24", - "license": "MIT" + "version": "1.10.30", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.30.tgz", + "integrity": "sha512-PLGc+xfrQrkya/YK2/5X+bPpxRmyJBHM+xxz9krUdSgk4Vs2ZwxX5/Ow0lv3r9PDlDtNWb4u+it8MY5rZ0IyGw==" + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true }, "node_modules/long-timeout": { "version": "0.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==" }, "node_modules/loose-envify": { "version": "1.4.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "peer": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -857,38 +3930,104 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, "node_modules/luxon": { "version": "3.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz", + "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==", "engines": { "node": ">=12" } }, + "node_modules/mafmt": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mafmt/-/mafmt-7.1.0.tgz", + "integrity": "sha512-vpeo9S+hepT3k2h5iFxzEHvvR0GPBx9uKaErmnRzYNcaKb03DgOArjEMlgG4a9LcuZZ89a3I8xbeto487n26eA==", + "dependencies": { + "multiaddr": "^7.3.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/make-error": { "version": "1.3.6", - "license": "ISC" + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } }, "node_modules/media-typer": { "version": "0.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } }, "node_modules/merge-descriptors": { "version": "1.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/methods": { "version": "1.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "bin": { "mime": "cli.js" }, @@ -898,14 +4037,16 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { "mime-db": "1.52.0" }, @@ -913,10 +4054,20 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -924,17 +4075,185 @@ "node": "*" } }, + "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/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/module-alias": { "version": "2.2.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" }, "node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/multiaddr": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-7.5.0.tgz", + "integrity": "sha512-GvhHsIGDULh06jyb6ev+VfREH9evJCFIRnh3jUt9iEZ6XDbyoisZRFEI9bMvK/AiR6y66y6P+eoBw9mBYMhMvw==", + "deprecated": "This module is deprecated, please upgrade to @multiformats/multiaddr", + "dependencies": { + "buffer": "^5.5.0", + "cids": "~0.8.0", + "class-is": "^1.1.0", + "is-ip": "^3.1.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/multiaddr/node_modules/cids": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.8.3.tgz", + "integrity": "sha512-yoXTbV3llpm+EBGWKeL9xKtksPE/s6DPoDSY4fn8I8TEW1zehWXPSB0pwAXVDlLaOlrw+sNynj995uD9abmPhA==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "buffer": "^5.6.0", + "class-is": "^1.1.0", + "multibase": "^1.0.0", + "multicodec": "^1.0.1", + "multihashes": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/multiaddr/node_modules/cids/node_modules/multibase": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz", + "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/multiaddr/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/multiaddr/node_modules/multihashes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-1.0.1.tgz", + "integrity": "sha512-S27Tepg4i8atNiFaU5ZOm3+gl3KQlUanLs/jWcBxQHFttgq+5x1OgbQmf2d8axJ/48zYGBd/wT9d723USMFduw==", + "dependencies": { + "buffer": "^5.6.0", + "multibase": "^1.0.1", + "varint": "^5.0.0" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/multiaddr/node_modules/multihashes/node_modules/multibase": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-1.0.1.tgz", + "integrity": "sha512-KcCxpBVY8fdVKu4dJMAahq4F/2Z/9xqEjIiR7PiMe7LRGeorFn2NLmicN6nLBCqQvft6MG2Lc9X5P0IdyvnxEw==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } }, "node_modules/nanoid": { - "version": "3.3.4", - "license": "MIT", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -942,46 +4261,52 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { "node": ">= 0.6" } }, "node_modules/next": { - "version": "13.2.4", - "license": "MIT", + "version": "13.4.1", + "resolved": "https://registry.npmjs.org/next/-/next-13.4.1.tgz", + "integrity": "sha512-JBw2kAIyhKDpjhEWvNVoFeIzNp9xNxg8wrthDOtMctfn3EpqGCmW0FSviNyGgOSOSn6zDaX48pmvbdf6X2W9xA==", "dependencies": { - "@next/env": "13.2.4", - "@swc/helpers": "0.4.14", + "@next/env": "13.4.1", + "@swc/helpers": "0.5.1", + "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", "postcss": "8.4.14", - "styled-jsx": "5.1.1" + "styled-jsx": "5.1.1", + "zod": "3.21.4" }, "bin": { "next": "dist/bin/next" }, "engines": { - "node": ">=14.6.0" + "node": ">=16.8.0" }, "optionalDependencies": { - "@next/swc-android-arm-eabi": "13.2.4", - "@next/swc-android-arm64": "13.2.4", - "@next/swc-darwin-arm64": "13.2.4", - "@next/swc-darwin-x64": "13.2.4", - "@next/swc-freebsd-x64": "13.2.4", - "@next/swc-linux-arm-gnueabihf": "13.2.4", - "@next/swc-linux-arm64-gnu": "13.2.4", - "@next/swc-linux-arm64-musl": "13.2.4", - "@next/swc-linux-x64-gnu": "13.2.4", - "@next/swc-linux-x64-musl": "13.2.4", - "@next/swc-win32-arm64-msvc": "13.2.4", - "@next/swc-win32-ia32-msvc": "13.2.4", - "@next/swc-win32-x64-msvc": "13.2.4" + "@next/swc-darwin-arm64": "13.4.1", + "@next/swc-darwin-x64": "13.4.1", + "@next/swc-linux-arm64-gnu": "13.4.1", + "@next/swc-linux-arm64-musl": "13.4.1", + "@next/swc-linux-x64-gnu": "13.4.1", + "@next/swc-linux-x64-musl": "13.4.1", + "@next/swc-win32-arm64-msvc": "13.4.1", + "@next/swc-win32-ia32-msvc": "13.4.1", + "@next/swc-win32-x64-msvc": "13.4.1" }, "peerDependencies": { - "@opentelemetry/api": "^1.4.0", + "@opentelemetry/api": "^1.1.0", "fibers": ">= 3.1.0", "node-sass": "^6.0.0 || ^7.0.0", "react": "^18.2.0", @@ -1014,9 +4339,22 @@ "node": ">= 8.0.0" } }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, "node_modules/node-schedule": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz", + "integrity": "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==", "dependencies": { "cron-parser": "^4.2.0", "long-timeout": "0.1.1", @@ -1027,9 +4365,10 @@ } }, "node_modules/nodemon": { - "version": "2.0.21", + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", "dev": true, - "license": "MIT", "dependencies": { "chokidar": "^3.5.2", "debug": "^3.2.7", @@ -1055,53 +4394,105 @@ }, "node_modules/nodemon/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/nodemon/node_modules/ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "license": "MIT" + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, "node_modules/nopt": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", "dev": true, - "license": "MIT", "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" } }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/object-assign": { "version": "4.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.12.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/on-finished": { "version": "2.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, @@ -1109,25 +4500,164 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "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", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parseurl": { "version": "1.3.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "engines": { "node": ">= 0.8" } }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, "node_modules/path-to-regexp": { "version": "0.1.7", - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/picocolors": { "version": "1.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1135,8 +4665,31 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/postcss": { "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", "funding": [ { "type": "opencollective", @@ -1147,7 +4700,6 @@ "url": "https://tidelift.com/funding/github/npm/postcss" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -1159,8 +4711,9 @@ }, "node_modules/prettier": { "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true, - "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -1171,13 +4724,40 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/prisma": { - "version": "4.11.0", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.14.0.tgz", + "integrity": "sha512-+5dMl1uxMQb4RepndY6AwR9xi1cDcaGFICu+ws6/Nmgt93mFPNj8tYxSfTdmfg+rkNrUId9rk/Ac2vTgLe/oXA==", "devOptional": true, "hasInstallScript": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/engines": "4.11.0" + "@prisma/engines": "4.14.0" }, "bin": { "prisma": "build/index.js", @@ -1189,11 +4769,39 @@ }, "node_modules/prisma-query": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/prisma-query/-/prisma-query-2.0.0.tgz", + "integrity": "sha512-+5eneJrgTFxW48j4JaWJ8iBwFSH+YQRtA1N+QEzqsREnTEAbs1Bq85xoZP7ZNEXDsoLOoIo4rYfCYRozuVOB9Q==" + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.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", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/proxy-addr": { "version": "2.0.7", - "license": "MIT", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -1202,18 +4810,32 @@ "node": ">= 0.10" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "license": "MIT" - }, "node_modules/pstree.remy": { "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", "dev": true, - "license": "MIT" + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] }, "node_modules/qs": { "version": "6.11.0", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { "side-channel": "^1.0.4" }, @@ -1226,14 +4848,16 @@ }, "node_modules/range-parser": { "version": "1.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -1246,7 +4870,8 @@ }, "node_modules/react": { "version": "18.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "peer": true, "dependencies": { "loose-envify": "^1.1.0" @@ -1257,7 +4882,8 @@ }, "node_modules/react-dom": { "version": "18.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "peer": true, "dependencies": { "loose-envify": "^1.1.0", @@ -1267,10 +4893,36 @@ "react": "^18.2.0" } }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -1280,10 +4932,69 @@ }, "node_modules/reflect-metadata": { "version": "0.1.13", - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -1297,32 +5008,35 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/safer-buffer": { "version": "2.1.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/scheduler": { "version": "0.23.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "peer": true, "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/semver": { - "version": "5.7.1", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "license": "ISC", "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/send": { "version": "0.18.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -1344,11 +5058,13 @@ }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/serve-static": { "version": "1.15.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -1361,11 +5077,34 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/side-channel": { "version": "1.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -1375,10 +5114,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/simple-update-notifier": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", "dev": true, - "license": "MIT", "dependencies": { "semver": "~7.0.0" }, @@ -1388,33 +5134,180 @@ }, "node_modules/simple-update-notifier/node_modules/semver": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, + "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", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/sorted-array-functions": { "version": "1.3.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", + "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==" }, - "node_modules/source-map-js": { - "version": "1.0.2", - "license": "BSD-3-Clause", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/statuses": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { "node": ">= 0.8" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", "dependencies": { "client-only": "0.0.1" }, @@ -1434,20 +5327,63 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -1457,15 +5393,17 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "engines": { "node": ">=0.6" } }, "node_modules/touch": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "dev": true, - "license": "ISC", "dependencies": { "nopt": "~1.0.10" }, @@ -1473,9 +5411,86 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/ts-jest": { + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", + "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/ts-node": { "version": "10.9.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -1516,11 +5531,34 @@ }, "node_modules/tslib": { "version": "2.5.0", - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/type-is": { "version": "1.6.18", - "license": "MIT", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -1529,13 +5567,20 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "node_modules/typedi": { "version": "0.10.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/typedi/-/typedi-0.10.0.tgz", + "integrity": "sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==" }, "node_modules/typescript": { "version": "4.9.5", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1546,972 +5591,287 @@ }, "node_modules/undefsafe": { "version": "2.0.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true }, "node_modules/unpipe": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, "node_modules/utils-merge": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "9.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uuidv4": { + "version": "6.2.13", + "resolved": "https://registry.npmjs.org/uuidv4/-/uuidv4-6.2.13.tgz", + "integrity": "sha512-AXyzMjazYB3ovL3q051VLH06Ixj//Knx7QnUSi1T//Ie3io6CpsPu9nVMOx5MoLWh6xV0B9J0hIaxungxXUbPQ==", + "dependencies": { + "@types/uuid": "8.3.4", + "uuid": "8.3.2" + } + }, + "node_modules/uuidv4/node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, + "node_modules/uuidv4/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "node_modules/validator": { "version": "13.9.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", "engines": { "node": ">= 0.10" } }, + "node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" + }, "node_modules/vary": { "version": "1.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/yn": { "version": "3.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "engines": { "node": ">=6" } - } - }, - "dependencies": { - "@cspotcode/source-map-support": { - "version": "0.8.1", - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } }, - "@jridgewell/resolve-uri": { - "version": "3.1.0" - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@next/env": { - "version": "13.2.4" - }, - "@next/swc-darwin-arm64": { - "version": "13.2.4", - "optional": true - }, - "@prisma/client": { - "version": "4.11.0", - "requires": { - "@prisma/engines-version": "4.11.0-57.8fde8fef4033376662cad983758335009d522acb" - } - }, - "@prisma/engines": { - "version": "4.11.0", - "devOptional": true - }, - "@prisma/engines-version": { - "version": "4.11.0-57.8fde8fef4033376662cad983758335009d522acb" - }, - "@swc/helpers": { - "version": "0.4.14", - "requires": { - "tslib": "^2.4.0" - } - }, - "@tsconfig/node10": { - "version": "1.0.9" - }, - "@tsconfig/node12": { - "version": "1.0.11" - }, - "@tsconfig/node14": { - "version": "1.0.3" - }, - "@tsconfig/node16": { - "version": "1.0.3" - }, - "@types/body-parser": { - "version": "1.19.2", + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/cors": { - "version": "2.8.13", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.17", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.33", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/mime": { - "version": "3.0.1", - "dev": true - }, - "@types/node": { - "version": "18.15.3" - }, - "@types/node-schedule": { - "version": "2.1.0", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.7", - "dev": true - }, - "@types/range-parser": { - "version": "1.2.4", - "dev": true - }, - "@types/serve-static": { - "version": "1.15.1", - "dev": true, - "requires": { - "@types/mime": "*", - "@types/node": "*" - } - }, - "@types/uuid": { - "version": "9.0.1", - "dev": true - }, - "@types/validator": { - "version": "13.7.14" - }, - "abbrev": { - "version": "1.1.1", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.8.2" - }, - "acorn-walk": { - "version": "8.2.0" - }, - "anymatch": { - "version": "3.1.3", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3" - }, - "array-flatten": { - "version": "1.1.1" - }, - "asynckit": { - "version": "0.4.0" - }, - "axios": { - "version": "1.3.4", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "dev": true - }, - "body-parser": { - "version": "1.20.1", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "bytes": { - "version": "3.1.2" - }, - "call-bind": { - "version": "1.0.2", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caniuse-lite": { - "version": "1.0.30001466" - }, - "chokidar": { - "version": "3.5.3", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "class-transformer": { - "version": "0.5.1" - }, - "class-validator": { - "version": "0.14.0", - "requires": { - "@types/validator": "^13.7.10", - "libphonenumber-js": "^1.10.14", - "validator": "^13.7.0" - } - }, - "classnames": { - "version": "2.3.2" - }, - "client-only": { - "version": "0.0.1" - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" - }, - "combined-stream": { - "version": "1.0.8", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "dev": true - }, - "content-disposition": { - "version": "0.5.4", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.5" - }, - "cookie": { - "version": "0.5.0" - }, - "cookie-signature": { - "version": "1.0.6" - }, - "cors": { - "version": "2.8.5", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-require": { - "version": "1.1.1" - }, - "cron-parser": { - "version": "4.8.1", - "requires": { - "luxon": "^3.2.1" - } - }, - "debug": { - "version": "2.6.9", - "requires": { - "ms": "2.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0" - }, - "depd": { - "version": "2.0.0" - }, - "destroy": { - "version": "1.2.0" - }, - "diff": { - "version": "4.0.2" - }, - "dotenv": { - "version": "16.0.3" - }, - "ee-first": { - "version": "1.1.1" - }, - "encodeurl": { - "version": "1.0.2" - }, - "escape-html": { - "version": "1.0.3" - }, - "etag": { - "version": "1.8.1" - }, - "express": { - "version": "4.18.2", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "fill-range": { - "version": "7.0.1", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.2.0", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "follow-redirects": { - "version": "1.15.2" - }, - "form-data": { - "version": "4.0.0", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0" - }, - "fresh": { - "version": "0.5.2" - }, - "fsevents": { - "version": "2.3.2", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1" - }, - "get-intrinsic": { - "version": "1.2.0", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "glob-parent": { - "version": "5.1.2", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "has": { - "version": "1.0.3", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "dev": true - }, - "has-symbols": { - "version": "1.0.3" - }, - "http-errors": { - "version": "2.0.0", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.24", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-by-default": { - "version": "1.0.1", - "dev": true - }, - "inherits": { - "version": "2.0.4" - }, - "ipaddr.js": { - "version": "1.9.1" - }, - "is-binary-path": { - "version": "2.1.0", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "peer": true - }, - "le-coffre-ressources": { - "version": "file:github.com:smart-chain-fr/leCoffre-resources.git" - }, - "libphonenumber-js": { - "version": "1.10.24" - }, - "long-timeout": { - "version": "0.1.1" - }, - "loose-envify": { - "version": "1.4.0", - "peer": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "luxon": { - "version": "3.3.0" - }, - "make-error": { - "version": "1.3.6" - }, - "media-typer": { - "version": "0.3.0" - }, - "merge-descriptors": { - "version": "1.0.1" - }, - "methods": { - "version": "1.1.2" - }, - "mime": { - "version": "1.6.0" - }, - "mime-db": { - "version": "1.52.0" - }, - "mime-types": { - "version": "2.1.35", - "requires": { - "mime-db": "1.52.0" - } - }, - "minimatch": { - "version": "3.1.2", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "module-alias": { - "version": "2.2.2" - }, - "ms": { - "version": "2.0.0" - }, - "nanoid": { - "version": "3.3.4" - }, - "negotiator": { - "version": "0.6.3" - }, - "next": { - "version": "13.2.4", - "requires": { - "@next/env": "13.2.4", - "@next/swc-android-arm-eabi": "13.2.4", - "@next/swc-android-arm64": "13.2.4", - "@next/swc-darwin-arm64": "13.2.4", - "@next/swc-darwin-x64": "13.2.4", - "@next/swc-freebsd-x64": "13.2.4", - "@next/swc-linux-arm-gnueabihf": "13.2.4", - "@next/swc-linux-arm64-gnu": "13.2.4", - "@next/swc-linux-arm64-musl": "13.2.4", - "@next/swc-linux-x64-gnu": "13.2.4", - "@next/swc-linux-x64-musl": "13.2.4", - "@next/swc-win32-arm64-msvc": "13.2.4", - "@next/swc-win32-ia32-msvc": "13.2.4", - "@next/swc-win32-x64-msvc": "13.2.4", - "@swc/helpers": "0.4.14", - "caniuse-lite": "^1.0.30001406", - "postcss": "8.4.14", - "styled-jsx": "5.1.1" - } - }, - "node-cache": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", - "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", - "requires": { - "clone": "2.x" - } - }, - "node-schedule": { - "version": "2.1.1", - "requires": { - "cron-parser": "^4.2.0", - "long-timeout": "0.1.1", - "sorted-array-functions": "^1.3.0" - } - }, - "nodemon": { - "version": "2.0.21", - "dev": true, - "requires": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" + "engines": { + "node": ">=10" }, - "dependencies": { - "debug": { - "version": "3.2.7", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "nopt": { - "version": "1.0.10", - "dev": true, - "requires": { - "abbrev": "1" + "node_modules/zod": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", + "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" } - }, - "normalize-path": { - "version": "3.0.0", - "dev": true - }, - "object-assign": { - "version": "4.1.1" - }, - "object-inspect": { - "version": "1.12.3" - }, - "on-finished": { - "version": "2.4.1", - "requires": { - "ee-first": "1.1.1" - } - }, - "parseurl": { - "version": "1.3.3" - }, - "path-to-regexp": { - "version": "0.1.7" - }, - "picocolors": { - "version": "1.0.0" - }, - "picomatch": { - "version": "2.3.1", - "dev": true - }, - "postcss": { - "version": "8.4.14", - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "prettier": { - "version": "2.8.4", - "dev": true - }, - "prisma": { - "version": "4.11.0", - "devOptional": true, - "requires": { - "@prisma/engines": "4.11.0" - } - }, - "prisma-query": { - "version": "2.0.0" - }, - "proxy-addr": { - "version": "2.0.7", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "proxy-from-env": { - "version": "1.1.0" - }, - "pstree.remy": { - "version": "1.1.8", - "dev": true - }, - "qs": { - "version": "6.11.0", - "requires": { - "side-channel": "^1.0.4" - } - }, - "range-parser": { - "version": "1.2.1" - }, - "raw-body": { - "version": "2.5.1", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "react": { - "version": "18.2.0", - "peer": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dom": { - "version": "18.2.0", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - } - }, - "readdirp": { - "version": "3.6.0", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "reflect-metadata": { - "version": "0.1.13" - }, - "safe-buffer": { - "version": "5.2.1" - }, - "safer-buffer": { - "version": "2.1.2" - }, - "scheduler": { - "version": "0.23.0", - "peer": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, - "semver": { - "version": "5.7.1", - "dev": true - }, - "send": { - "version": "0.18.0", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "ms": { - "version": "2.1.3" - } - } - }, - "serve-static": { - "version": "1.15.0", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0" - }, - "side-channel": { - "version": "1.0.4", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "simple-update-notifier": { - "version": "1.1.0", - "dev": true, - "requires": { - "semver": "~7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "dev": true - } - } - }, - "sorted-array-functions": { - "version": "1.3.0" - }, - "source-map-js": { - "version": "1.0.2" - }, - "statuses": { - "version": "2.0.1" - }, - "styled-jsx": { - "version": "5.1.1", - "requires": { - "client-only": "0.0.1" - } - }, - "supports-color": { - "version": "5.5.0", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1" - }, - "touch": { - "version": "3.1.0", - "dev": true, - "requires": { - "nopt": "~1.0.10" - } - }, - "ts-node": { - "version": "10.9.1", - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "tslib": { - "version": "2.5.0" - }, - "type-is": { - "version": "1.6.18", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedi": { - "version": "0.10.0" - }, - "typescript": { - "version": "4.9.5" - }, - "undefsafe": { - "version": "2.0.5", - "dev": true - }, - "unpipe": { - "version": "1.0.0" - }, - "utils-merge": { - "version": "1.0.1" - }, - "uuid": { - "version": "9.0.0" - }, - "v8-compile-cache-lib": { - "version": "3.0.1" - }, - "validator": { - "version": "13.9.0" - }, - "vary": { - "version": "1.1.2" - }, - "yn": { - "version": "3.1.1" } } } diff --git a/package.json b/package.json index bc3e47db..8f6c3f38 100644 --- a/package.json +++ b/package.json @@ -13,17 +13,21 @@ "@Config": "./dist/common/config", "@Entities": "./dist/common/entities", "@System": "./dist/common/system", - "@ControllerPattern": "./dist/common/system/controller-pattern" + "@ControllerPattern": "./dist/common/system/controller-pattern", + "@Test": "./dist/test" }, "scripts": { + "build-db": "npx prisma migrate dev", "build": "tsc", - "api:start": "npm run migrate && node ./dist/entries/App.js", - "start": "tsc && npm run api:start", + "start": "node ./dist/entries/App.js", + "api:start": "npm run migrate && npm run start", "dev": "nodemon -V", - "api:dev": "nodemon -V --exec 'tsc && npm run api:start'", - "build:test": "tsc && mocha ./dist/entries/Test.js", "format": "prettier --write src", - "migrate": "npx prisma migrate deploy" + "migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy", + "migrate": "npx prisma migrate deploy", + "docker:up:test": "docker-compose -f docker-compose-test.yml up -d", + "docker:down:test": "docker-compose down", + "test": "tsc && npm run docker:up:test && npm run migrate:test && dotenv -e .env.test -- jest -i --verbose ./dist/test/* && npm run docker:down:test" }, "repository": { "type": "git", @@ -36,16 +40,17 @@ }, "homepage": "https://github.com/smart-chain-fr/leCoffre-back#readme", "dependencies": { - "@prisma/client": "^4.9.0", - "axios": "^1.3.3", + "@pinata/sdk": "^2.1.0", + "@prisma/client": "^4.11.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "classnames": "^2.3.2", "cors": "^2.8.5", - "dotenv": "^16.0.3", "express": "^4.18.2", - "le-coffre-ressources": "github.com:smart-chain-fr/leCoffre-resources.git", + "jsonwebtoken": "^9.0.0", + "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.47", "module-alias": "^2.2.2", + "multer": "^1.4.5-lts.1", "next": "^13.1.5", "node-cache": "^5.1.2", "node-schedule": "^2.1.1", @@ -55,19 +60,27 @@ "tslib": "^2.4.1", "typedi": "^0.10.0", "typescript": "^4.9.4", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "uuidv4": "^6.2.13" }, "devDependencies": { "@types/cors": "^2.8.13", "@types/express": "^4.17.16", + "@types/jest": "^29.5.0", + "@types/jsonwebtoken": "^9.0.1", + "@types/multer": "^1.4.7", "@types/node": "^18.11.18", "@types/node-schedule": "^2.1.0", "@types/uuid": "^9.0.0", + "dotenv": "^16.0.3", + "jest": "^29.5.0", "nodemon": "^2.0.20", "prettier": "2.8.4", - "prisma": "^4.11.0" + "prisma": "^4.11.0", + "ts-jest": "^29.0.5" }, "prisma": { - "schema": "src/common/databases/schema.prisma" + "schema": "src/common/databases/schema.prisma", + "seed": "ts-node src/common/databases/seeders/seeder2.ts" } } diff --git a/src/app/HomeController.ts b/src/app/HomeController.ts index ae366a0f..2d84c394 100644 --- a/src/app/HomeController.ts +++ b/src/app/HomeController.ts @@ -6,12 +6,9 @@ import ApiController from "@Common/system/controller-pattern/ApiController"; @Controller() @Service() export default class HomeController extends ApiController { - @Get("/") protected async get(req: Request, res: Response) { - // const query = processFindManyQuery(req.query); this.httpSuccess(res, "Welcome to the home page!"); } } - diff --git a/src/app/api/CustomersController.ts b/src/app/api/CustomersController.ts deleted file mode 100644 index 89aa15e5..00000000 --- a/src/app/api/CustomersController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import CustomersService from "@Services/CustomersService/CustomersService"; -import { Service } from "typedi"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class CustomersController extends ApiController { - constructor(private customersService: CustomersService) { - super(); - } - - /** - * @description Get all customers - * @returns ICustomer[] list of customers - */ - @Get("/api/customers") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.customersService.get()); - } - - /** - * @description Create a new customer - * @returns ICustomer created - */ - @Post("/api/customers") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.customersService.create()); - } - - /** - * @description Modify a specific customer by uid - * @returns ICustomer modified - */ - @Put("/api/customers/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.customersService.put()); - } - - /** - * @description Get a specific customer by uid - * @returns ICustomer - */ - @Get("/api/customers/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.customersService.getByUid("uid")); - } -} diff --git a/src/app/api/DeedTypesController.ts b/src/app/api/DeedTypesController.ts deleted file mode 100644 index 400649fa..00000000 --- a/src/app/api/DeedTypesController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import { Service } from "typedi"; -import DeedTypesService from "@Services/DeedTypesService/DeedTypesService"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class DeedTypesController extends ApiController { - constructor(private deedTypesService: DeedTypesService) { - super(); - } - - /** - * @description Get all deedtypes - * @returns IDeedtype[] list of deedtypes - */ - @Get("/api/deed-types") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedTypesService.get()); - } - - /** - * @description Create a new deedtype - * @returns IDeedtype created - */ - @Post("/api/deed-types") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedTypesService.create()); - } - - /** - * @description Modify a specific deedtype by uid - * @returns IDeedtype modified - */ - @Put("/api/deed-types/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedTypesService.put()); - } - - /** - * @description Get a specific deedtype by uid - * @returns IDeedtype - */ - @Get("/api/deed-types/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedTypesService.getByUid("uid")); - } -} diff --git a/src/app/api/DeedsController.ts b/src/app/api/DeedsController.ts deleted file mode 100644 index 264d943a..00000000 --- a/src/app/api/DeedsController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import DeedsService from "@Services/DeedsService/DeedsService"; -import { Service } from "typedi"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class DeedsController extends ApiController { - constructor(private deedsService: DeedsService) { - super(); - } - - /** - * @description Get all deeds - * @returns IDeed[] list of deeds - */ - @Get("/api/deeds") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedsService.get()); - } - - /** - * @description Create a new deed - * @returns IDeed created - */ - @Post("/api/deeds") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedsService.create()); - } - - /** - * @description Modify a specific deed by uid - * @returns IDeed modified - */ - @Put("/api/deeds/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedsService.put()); - } - - /** - * @description Get a specific deed by uid - * @returns IDeed - */ - @Get("/api/deeds/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.deedsService.getByUid("uid")); - } -} diff --git a/src/app/api/DocumentTypesController.ts b/src/app/api/DocumentTypesController.ts deleted file mode 100644 index bea1cd3d..00000000 --- a/src/app/api/DocumentTypesController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import { Service } from "typedi"; -import DocumentTypesService from "@Services/DocumentTypesService/DocumentTypesService"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class DocumentTypesController extends ApiController { - constructor(private documentTypesService: DocumentTypesService) { - super(); - } - - /** - * @description Get all document-types - * @returns IFolder[] list of document-types - */ - @Get("/api/document-types") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentTypesService.get()); - } - - /** - * @description Create a new documentType - * @returns IFolder created - */ - @Post("/api/document-types") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentTypesService.create()); - } - - /** - * @description Modify a specific documentType by uid - * @returns IFolder modified - */ - @Put("/api/document-types/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentTypesService.put()); - } - - /** - * @description Get a specific documentType by uid - * @returns IFolder - */ - @Get("/api/document-types/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentTypesService.getByUid("uid")); - } -} diff --git a/src/app/api/DocumentsController.ts b/src/app/api/DocumentsController.ts deleted file mode 100644 index e23f2191..00000000 --- a/src/app/api/DocumentsController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import { Service } from "typedi"; -import DocumentsService from "@Services/DocumentsService/DocumentsService"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class DocumentsController extends ApiController { - constructor(private documentsService: DocumentsService) { - super(); - } - - /** - * @description Get all documents - * @returns IDocument[] list of documents - */ - @Get("/api/documents") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentsService.get()); - } - - /** - * @description Create a new document - * @returns IDocument created - */ - @Post("/api/documents") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentsService.create()); - } - - /** - * @description Modify a specific document by uid - * @returns IDocument modified - */ - @Put("/api/documents/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentsService.put()); - } - - /** - * @description Get a specific document by uid - * @returns IDocument - */ - @Get("/api/documents/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.documentsService.getByUid("uid")); - } -} diff --git a/src/app/api/FoldersController.ts b/src/app/api/FoldersController.ts deleted file mode 100644 index 4b5200ab..00000000 --- a/src/app/api/FoldersController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import FoldersService from "@Services/FoldersService/FoldersService"; -import { Service } from "typedi"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class FolderController extends ApiController { - constructor(private foldersService: FoldersService) { - super(); - } - - /** - * @description Get all folders - * @returns IFolder[] list of folders - */ - @Get("/api/folders") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.foldersService.get()); - } - - /** - * @description Create a new folder - * @returns IFolder created - */ - @Post("/api/folders") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.foldersService.create()); - } - - /** - * @description Modify a specific folder by uid - * @returns IFolder modified - */ - @Put("/api/folders/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.foldersService.put()); - } - - /** - * @description Get a specific folder by uid - * @returns IFolder - */ - @Get("/api/folders/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.foldersService.getByUid("uid")); - } -} diff --git a/src/app/api/OfficesController.ts b/src/app/api/OfficesController.ts deleted file mode 100644 index 6cf6140d..00000000 --- a/src/app/api/OfficesController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import OfficesService from "@Services/OfficesService/OfficesService"; -import { Service } from "typedi"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class OfficesController extends ApiController { - constructor(private officesService: OfficesService) { - super(); - } - - /** - * @description Get all offices - * @returns IOffice[] list of offices - */ - @Get("/api/offices") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.officesService.get()); - } - - /** - * @description Create a new office - * @returns IOffice created - */ - @Post("/api/offices") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.officesService.create()); - } - - /** - * @description Modify a specific office by uid - * @returns IOffice modified - */ - @Put("/api/offices/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.officesService.put()); - } - - /** - * @description Get a specific office by uid - * @returns IOffice - */ - @Get("/api/offices/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.officesService.getByUid("uid")); - } -} diff --git a/src/app/api/UsersController.ts b/src/app/api/UsersController.ts deleted file mode 100644 index fb2f5450..00000000 --- a/src/app/api/UsersController.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get, Post, Put } from "@ControllerPattern/index"; -import ApiController from "@Common/system/controller-pattern/ApiController"; -import UsersService from "@Services/UsersService/UsersService"; -import { Service } from "typedi"; -// import { IsNotEmpty, IsString, IsUUID } from "class-validator"; - -// class Params { -// @IsString() -// @IsNotEmpty() -// @IsUUID() -// public uuid!: string; -// } - -@Controller() -@Service() -export default class UsersController extends ApiController { - constructor(private usersService: UsersService) { - super(); - } - - /** - * @description Get all users - * @returns IUser[] list of users - */ - @Get("/api/users") - protected async get(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.usersService.get()); - } - - /** - * @description Create a new user - * @returns IUser created - */ - @Post("/api/users") - protected async post(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.usersService.create()); - } - - /** - * @description Modify a specific user by uid - * @returns IUser modified - */ - @Put("/api/users/:uid") - protected async put(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.usersService.put()); - } - - /** - * @description Get a specific user by uid - * @returns IUser - */ - @Get("/api/users/:uid") - protected async getOneByUid(req: Request, response: Response) { - try { - // TODO - } catch (error) { - this.httpBadRequest(response, error); - return; - } - this.httpSuccess(response, await this.usersService.getByUid("uid")); - } -} diff --git a/src/app/api/customer/DocumentsController.ts b/src/app/api/customer/DocumentsController.ts new file mode 100644 index 00000000..ebfccb15 --- /dev/null +++ b/src/app/api/customer/DocumentsController.ts @@ -0,0 +1,158 @@ +import { Response, Request } from "express"; +import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import { Service } from "typedi"; +import DocumentsService from "@Services/customer/DocumentsService/DocumentsService"; +import { Documents } from "@prisma/client"; +import { Document } from "le-coffre-resources/dist/Customer"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class DocumentsController extends ApiController { + constructor(private documentsService: DocumentsService) { + super(); + } + + /** + * @description Get all documents + * @returns IDocument[] list of documents + */ + @Get("/api/v1/customer/documents") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + + //call service to get prisma entity + const prismaEntity: Documents[] = await this.documentsService.get(query); + + //Hydrate ressource with prisma entity + const documents = Document.map(Document, prismaEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, documents); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new document + * @returns IDocument created + */ + @Post("/api/v1/customer/documents") + protected async post(req: Request, response: Response) { + try { + //init Document resource with request body values + const documentEntity = Document.hydrate(req.body); + + //validate document + await validateOrReject(documentEntity, { groups: ["createDocument"] }); + + //call service to get prisma entity + const prismaEntityCreated = await this.documentsService.create(documentEntity); + + //Hydrate ressource with prisma entity + const documentEntityCreated = Document.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, documentEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Update a specific document + */ + @Put("/api/v1/customer/documents/:uid") + protected async update(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + //init Document resource with request body values + const documentEntity = new Document(); + Document.hydrate(documentEntity, req.body); + + //validate document + await validateOrReject(documentEntity, { groups: ["createDocument"] }); + + //call service to get prisma entity + const prismaEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity); + + //Hydrate ressource with prisma entity + const document = Document.hydrate(prismaEntityUpdated, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, document); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Delete a specific document + */ + @Delete("/api/v1/customer/documents/:uid") + protected async delete(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + //call service to get prisma entity + const documentEntity: Documents = await this.documentsService.delete(uid); + + //Hydrate ressource with prisma entity + const document = Document.hydrate(documentEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, document); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific document by uid + */ + @Get("/api/v1/customer/documents/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + let documentEntity: Documents; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + documentEntity = await this.documentsService.getByUid(uid, query); + } else { + //call service to get prisma entity + documentEntity = await this.documentsService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const document = Document.hydrate(documentEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, document); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/idnot-user/UserInfoController.ts b/src/app/api/idnot-user/UserInfoController.ts new file mode 100644 index 00000000..f3854a1d --- /dev/null +++ b/src/app/api/idnot-user/UserInfoController.ts @@ -0,0 +1,32 @@ +import { Response, Request } from "express"; + import { Controller,Post } from "@ControllerPattern/index"; + import ApiController from "@Common/system/controller-pattern/ApiController"; + import { Service } from "typedi"; +import AuthService from "@Services/private-services/AuthService/AuthService"; +//import User from "le-coffre-resources/dist/Notary"; + + @Controller() + @Service() + export default class UserInfoController extends ApiController { + constructor(private authService: AuthService) { + super(); + } + + /** + * @description Get user created from IdNot authentification + * @returns User + */ + @Post("/api/v1/idnot-user/:code") + protected async getUserInfosFromIdnot(req: Request, response: Response) { + try { + const code = req.params["code"]; + const user = await this.authService.getUserFromIdNotTokens(code!); + //success + this.httpSuccess(response, user); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + +} \ No newline at end of file diff --git a/src/app/api/projects/UserController.ts b/src/app/api/projects/UserController.ts deleted file mode 100644 index e9aff82a..00000000 --- a/src/app/api/projects/UserController.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { type Response, type Request } from "express"; -import { Controller, Get } from "@ControllerPattern/index"; -import { Service } from "typedi"; -import ApiController from "@Common/system/controller-pattern/ApiController"; - -@Controller() -@Service() -export default class ProjectController extends ApiController { - - @Get("/api/projects/users") - protected async get(req: Request, res: Response) { - - // const query = processFindManyQuery(req.query); - this.httpSuccess(res, { message: "get" }); - } - -} - diff --git a/src/app/api/super-admin/CustomersController.ts b/src/app/api/super-admin/CustomersController.ts new file mode 100644 index 00000000..d283cb95 --- /dev/null +++ b/src/app/api/super-admin/CustomersController.ts @@ -0,0 +1,129 @@ +import { Response, Request } from "express"; +import { Controller, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import CustomersService from "@Services/super-admin/CustomersService/CustomersService"; +import { Service } from "typedi"; +import { Customer } from "le-coffre-resources/dist/SuperAdmin"; +import { Customers } from "@prisma/client"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class CustomersController extends ApiController { + constructor(private customersService: CustomersService) { + super(); + } + + /** + * @description Get all customers + */ + @Get("/api/v1/super-admin/customers") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + + //call service to get prisma entity + const customersEntity = await this.customersService.get(query); + + //Hydrate ressource with prisma entity + const customers = Customer.map(Customer, customersEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, customers); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new customer + */ + @Post("/api/v1/super-admin/customers") + protected async post(req: Request, response: Response) { + try { + //init IUser resource with request body values + const customerEntity = Customer.hydrate(req.body); + //validate user + await validateOrReject(customerEntity, { groups: ["createCustomer"], forbidUnknownValues: false }); + + //call service to get prisma entity + const prismaEntityCreated = await this.customersService.create(customerEntity); + //Hydrate ressource with prisma entity + const customerEntityCreated = Customer.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, customerEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Modify a specific customer by uid + */ + @Put("/api/v1/super-admin/customers/:uid") + protected async put(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + //init IUser resource with request body values + const customerEntity = Customer.hydrate(req.body); + + //validate user + await validateOrReject(customerEntity, { groups: ["updateCustomer"], forbidUnknownValues: false }); + + //call service to get prisma entity + const prismaEntityUpdated = await this.customersService.update(uid, customerEntity); + + //Hydrate ressource with prisma entity + const customerEntityUpdated = Customer.hydrate(prismaEntityUpdated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, customerEntityUpdated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific customer by uid + */ + @Get("/api/v1/super-admin/customers/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + let customerEntity: Customers; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + customerEntity = await this.customersService.getByUid(uid, query); + } else { + //call service to get prisma entity + customerEntity = await this.customersService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const customer = Customer.hydrate(customerEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, customer); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/DeedTypesController.ts b/src/app/api/super-admin/DeedTypesController.ts new file mode 100644 index 00000000..aba5721c --- /dev/null +++ b/src/app/api/super-admin/DeedTypesController.ts @@ -0,0 +1,134 @@ +import { Response, Request } from "express"; +import { Controller, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import { Service } from "typedi"; +import DeedTypesService from "@Services/super-admin/DeedTypesService/DeedTypesService"; +import { DeedTypes } from "@prisma/client"; +import { DeedType } from "le-coffre-resources/dist/SuperAdmin"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class DeedTypesController extends ApiController { + constructor(private deedTypesService: DeedTypesService) { + super(); + } + + /** + * @description Get all deedtypes + * @returns Deedtype[] list of deedtypes + */ + @Get("/api/v1/super-admin/deed-types") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + //call service to get prisma entity + const prismaEntity: DeedTypes[] = await this.deedTypesService.get(query); + + //Hydrate ressource with prisma entity + const DeedTypes = DeedType.map(DeedType, prismaEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, DeedTypes); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new deedtype + * @returns Deedtype created + */ + @Post("/api/v1/super-admin/deed-types") + protected async post(req: Request, response: Response) { + try { + //init DeedType resource with request body values + const deedTypeEntity = DeedType.hydrate(req.body); + + //validate deed type + await validateOrReject(deedTypeEntity, { groups: ["createDeedType"], forbidUnknownValues: false }); + + //call service to get prisma entity + const prismaEntityCreated = await this.deedTypesService.create(deedTypeEntity); + + //Hydrate ressource with prisma entity + const deedTypeEntityCreated = DeedType.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, deedTypeEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Modify a specific deedtype by uid + * @returns Deedtype modified + */ + @Put("/api/v1/super-admin/deed-types/:uid") + protected async put(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + //init DeedType resource with request body values + const deedTypeEntity = DeedType.hydrate(req.body); + + //validate deed type + await validateOrReject(deedTypeEntity, { groups: ["updateDeedType"] }); + + //call service to get prisma entity + const prismaEntityUpdated = await this.deedTypesService.update(uid, deedTypeEntity); + + //Hydrate ressource with prisma entity + const deedTypeEntityUpdated = DeedType.hydrate(prismaEntityUpdated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, deedTypeEntityUpdated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific deedtype by uid + * @returns IDeedtype + */ + @Get("/api/v1/super-admin/deed-types/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + let deedTypeEntity: DeedTypes; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + deedTypeEntity = await this.deedTypesService.getByUid(uid, query); + } else { + //call service to get prisma entity + deedTypeEntity = await this.deedTypesService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const deedType = DeedType.hydrate(deedTypeEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, deedType); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/DeedsController.ts b/src/app/api/super-admin/DeedsController.ts new file mode 100644 index 00000000..f8ff9da7 --- /dev/null +++ b/src/app/api/super-admin/DeedsController.ts @@ -0,0 +1,104 @@ +import { Response, Request } from "express"; +import { Controller, Get, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import DeedsService from "@Services/super-admin/DeedsService/DeedsService"; +import { Service } from "typedi"; +import { Deeds } from "@prisma/client"; +import { Deed } from "le-coffre-resources/dist/SuperAdmin"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class DeedsController extends ApiController { + constructor(private deedsService: DeedsService) { + super(); + } + + /** + * @description Get all deeds + * @returns Deed[] list of deeds + */ + @Get("/api/v1/super-admin/deeds") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + //call service to get prisma entity + const prismaEntity: Deeds[] = await this.deedsService.get(query); + + //Hydrate ressource with prisma entity + const deeds = Deed.map(Deed, prismaEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, deeds); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific deed by uid + * @returns Deed + */ + @Get("/api/v1/super-admin/deeds/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + let deedEntity: Deeds; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + deedEntity = await this.deedsService.getByUid(uid, query); + } else { + //call service to get prisma entity + deedEntity = await this.deedsService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const deed = Deed.hydrate(deedEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, deed); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Modify a specific deed by uid + */ + @Put("/api/v1/super-admin/deeds/:uid") + protected async put(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + //init OfficeFolder resource with request body values + const deedEntity = Deed.hydrate(req.body); + + //validate folder + await validateOrReject(deedEntity, { groups: ["updateDeed"], forbidUnknownValues: false }); + + //call service to get prisma entity + const prismaEntityUpdated = await this.deedsService.update(uid, deedEntity); + + //Hydrate ressource with prisma entity + const deedEntityUpdated = Deed.hydrate(prismaEntityUpdated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, deedEntityUpdated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/DocumentTypesController.ts b/src/app/api/super-admin/DocumentTypesController.ts new file mode 100644 index 00000000..3ef79a93 --- /dev/null +++ b/src/app/api/super-admin/DocumentTypesController.ts @@ -0,0 +1,130 @@ +import { Response, Request } from "express"; +import { Controller, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import { Service } from "typedi"; +import DocumentTypesService from "@Services/super-admin/DocumentTypesService/DocumentTypesService"; +import { DocumentTypes } from "@prisma/client"; +import ObjectHydrate from "@Common/helpers/ObjectHydrate"; +import { DocumentType } from "le-coffre-resources/dist/SuperAdmin"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class DocumentTypesController extends ApiController { + constructor(private documentTypesService: DocumentTypesService) { + super(); + } + + /** + * @description Get all document-types + */ + @Get("/api/v1/super-admin/document-types") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + + //call service to get prisma entity + const prismaEntity: DocumentTypes[] = await this.documentTypesService.get(query); + + //Hydrate ressource with prisma entity + const documentTypes = DocumentType.map(DocumentType, prismaEntity, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, documentTypes); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new documentType + */ + @Post("/api/v1/super-admin/document-types") + protected async post(req: Request, response: Response) { + try { + //init DocumentType resource with request body values + const documentTypeEntity = DocumentType.hydrate(req.body); + //validate user + await validateOrReject(documentTypeEntity, { groups: ["createDocumentType"], forbidUnknownValues: false }); + //call service to get prisma entity + const prismaEntityCreated = await this.documentTypesService.create(documentTypeEntity); + //Hydrate ressource with prisma entity + const userEntityCreated = DocumentType.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + //success + this.httpSuccess(response, userEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Modify a specific documentType by uid + */ + @Put("/api/v1/super-admin/document-types/:uid") + protected async put(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + //init DocumentType resource with request body values + const documentTypeEntity = DocumentType.hydrate(req.body); + + //validate user + await validateOrReject(documentTypeEntity, { groups: ["update"] }); + + //call service to get prisma entity + const prismaEntityUpdated = await this.documentTypesService.update(uid, documentTypeEntity); + + //Hydrate ressource with prisma entity + const documentTypeEntityUpdated = DocumentType.hydrate(prismaEntityUpdated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, documentTypeEntityUpdated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific documentType by uid + */ + @Get("/api/v1/super-admin/document-types/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + let documentTypeEntity: DocumentTypes; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + documentTypeEntity = await this.documentTypesService.getByUid(uid, query); + } else { + //call service to get prisma entity + documentTypeEntity = await this.documentTypesService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const user = ObjectHydrate.hydrate(new DocumentType(), documentTypeEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, user); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/DocumentsController.ts b/src/app/api/super-admin/DocumentsController.ts new file mode 100644 index 00000000..ae60a9ab --- /dev/null +++ b/src/app/api/super-admin/DocumentsController.ts @@ -0,0 +1,157 @@ +import { Response, Request } from "express"; +import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import { Service } from "typedi"; +import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService"; +import { Documents } from "@prisma/client"; +import { Document } from "le-coffre-resources/dist/SuperAdmin"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class DocumentsController extends ApiController { + constructor(private documentsService: DocumentsService) { + super(); + } + + /** + * @description Get all documents + * @returns IDocument[] list of documents + */ + @Get("/api/v1/super-admin/documents") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + + //call service to get prisma entity + const prismaEntity: Documents[] = await this.documentsService.get(query); + + //Hydrate ressource with prisma entity + const documents = Document.map(Document, prismaEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, documents); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new document + * @returns IDocument created + */ + @Post("/api/v1/super-admin/documents") + protected async post(req: Request, response: Response) { + try { + //init Document resource with request body values + const documentEntity = Document.hydrate(req.body); + + //validate document + await validateOrReject(documentEntity, { groups: ["createDocument"], forbidUnknownValues: false }); + + //call service to get prisma entity + const prismaEntityCreated = await this.documentsService.create(documentEntity); + + //Hydrate ressource with prisma entity + const documentEntityCreated = Document.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, documentEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Update a specific document + */ + @Put("/api/v1/super-admin/documents/:uid") + protected async update(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + //init Document resource with request body values + const documentEntity = Document.hydrate(req.body); + + //validate document + await validateOrReject(documentEntity, { groups: ["updateDocument"] }); + + //call service to get prisma entity + const prismaEntityUpdated: Documents = await this.documentsService.update(uid, documentEntity, req.body.refused_reason); + + //Hydrate ressource with prisma entity + const document = Document.hydrate(prismaEntityUpdated, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, document); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Delete a specific document + */ + @Delete("/api/v1/super-admin/documents/:uid") + protected async delete(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + //call service to get prisma entity + const documentEntity: Documents = await this.documentsService.delete(uid); + + //Hydrate ressource with prisma entity + const document = Document.hydrate(documentEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, document); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific document by uid + */ + @Get("/api/v1/super-admin/documents/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + let documentEntity: Documents; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + documentEntity = await this.documentsService.getByUid(uid, query); + } else { + //call service to get prisma entity + documentEntity = await this.documentsService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const document = Document.hydrate(documentEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, document); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/FilesController.ts b/src/app/api/super-admin/FilesController.ts new file mode 100644 index 00000000..68c2dfd1 --- /dev/null +++ b/src/app/api/super-admin/FilesController.ts @@ -0,0 +1,178 @@ +import { Response, Request } from "express"; +import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import { Service } from "typedi"; +import FilesService from "@Services/private-services/FilesService/FilesService"; +import { Files } from "@prisma/client"; +import { File, Document } from "le-coffre-resources/dist/SuperAdmin"; +import { validateOrReject } from "class-validator"; +import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService"; + +@Controller() +@Service() +export default class FilesController extends ApiController { + constructor(private filesService: FilesService, private documentService: DocumentsService) { + super(); + } + + /** + * @description Get all Files + * @returns File[] list of Files + */ + @Get("/api/v1/super-admin/files") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + + //call service to get prisma entity + const prismaEntity = await this.filesService.get(query); + + //Hydrate ressource with prisma entity + const files = File.map(File, prismaEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, files); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific File by uid + */ + @Get("/api/v1/super-admin/files/upload/:uid") + protected async getFileData(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + const file = await this.filesService.updload(uid); + + this.httpSuccess(response, file); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new File + * @returns File created + */ + @Post("/api/v1/super-admin/files") + protected async post(req: Request, response: Response) { + try { + + //get file + if(!req.file) throw new Error('No file provided') + + //init File resource with request body values + const fileEntity = File.hydrate(JSON.parse(req.body["q"])); + + //validate File + await validateOrReject(fileEntity, { groups: ["createFile"] }); + + //call service to get prisma entity + const prismaEntityCreated = await this.filesService.create(fileEntity, req.file); + + const document: Document = await this.documentService.getByUid(fileEntity.document!.uid!) + document.document_status = "DEPOSITED"; + await this.documentService.update(document.uid!, document); + + //Hydrate ressource with prisma entity + const fileEntityCreated = File.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, fileEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Update a specific file + */ + @Put("/api/v1/super-admin/files/:uid") + protected async update(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + //init File resource with request body values + const fileEntity = File.hydrate(req.body); + + //validate file + await validateOrReject(fileEntity, { groups: ["updateFile"] }); + + //call service to get prisma entity + const prismaEntityUpdated: Files = await this.filesService.update(uid, fileEntity); + + //Hydrate ressource with prisma entity + const file = File.hydrate(prismaEntityUpdated, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, file); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Delete a specific File + */ + @Delete("/api/v1/super-admin/files/:uid") + protected async delete(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + //call service to get prisma entity + const fileEntity: Files = await this.filesService.delete(uid); + + //Hydrate ressource with prisma entity + const file = File.hydrate(fileEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, file); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific File by uid + */ + @Get("/api/v1/super-admin/files/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + const fileEntity = await this.filesService.getByUid(uid); + + //Hydrate ressource with prisma entity + const file = File.hydrate(fileEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, file); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/OfficeFoldersController.ts b/src/app/api/super-admin/OfficeFoldersController.ts new file mode 100644 index 00000000..989ea9b5 --- /dev/null +++ b/src/app/api/super-admin/OfficeFoldersController.ts @@ -0,0 +1,154 @@ +import { Response, Request } from "express"; +import { Controller, Delete, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import OfficeFoldersService from "@Services/super-admin/OfficeFoldersService/OfficeFoldersService"; +import { Service } from "typedi"; +import { OfficeFolders } from "@prisma/client"; +import { OfficeFolder } from "le-coffre-resources/dist/SuperAdmin"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class OfficeFoldersController extends ApiController { + constructor(private officeFoldersService: OfficeFoldersService) { + super(); + } + + /** + * @description Get all folders + */ + @Get("/api/v1/super-admin/folders") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + //call service to get prisma entity + const prismaEntity: OfficeFolders[] = await this.officeFoldersService.get(query); + //Hydrate ressource with prisma entity + const officeFolders = OfficeFolder.map(OfficeFolder, prismaEntity, { + strategy: "excludeAll", + }); + //success + this.httpSuccess(response, officeFolders); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new folder + */ + @Post("/api/v1/super-admin/folders") + protected async post(req: Request, response: Response) { + try { + //init OfficeFolder resource with request body values + const officeFolderEntity = OfficeFolder.hydrate(req.body); + + //validate folder + await validateOrReject(officeFolderEntity, { groups: ["createFolder"] , forbidUnknownValues: false }); + //call service to get prisma entity + const prismaEntityCreated = await this.officeFoldersService.create(officeFolderEntity); + //Hydrate ressource with prisma entity + const officeFolderEntityCreated = OfficeFolder.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + //success + this.httpSuccess(response, officeFolderEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Modify a specific folder by uid + */ + @Put("/api/v1/super-admin/folders/:uid") + protected async put(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + //init OfficeFolder resource with request body values + const officeFolderEntity = OfficeFolder.hydrate(req.body); + + //validate folder + await validateOrReject(officeFolderEntity, { groups: ["updateFolder"], forbidUnknownValues: false }); + + //call service to get prisma entity + const prismaEntityUpdated = await this.officeFoldersService.update(uid, officeFolderEntity); + + //Hydrate ressource with prisma entity + const officeFolderEntityUpdated = OfficeFolder.hydrate(prismaEntityUpdated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, officeFolderEntityUpdated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific folder by uid + * @returns IFolder + */ + @Get("/api/v1/super-admin/folders/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + let officeFolderEntity: OfficeFolders; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + officeFolderEntity = await this.officeFoldersService.getByUid(uid, query); + } else { + //call service to get prisma entity + officeFolderEntity = await this.officeFoldersService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const officeFolder = OfficeFolder.hydrate(officeFolderEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, officeFolder); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + this.httpSuccess(response, await this.officeFoldersService.getByUid("uid")); + } + + /** + * @description Delete a specific folder + */ + @Delete("/api/v1/super-admin/folders/:uid") + protected async delete(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + + //call service to get prisma entity + const officeFoldertEntity: OfficeFolders = await this.officeFoldersService.delete(uid); + + //Hydrate ressource with prisma entity + const officeFolder = OfficeFolder.hydrate(officeFoldertEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, officeFolder); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/OfficesController.ts b/src/app/api/super-admin/OfficesController.ts new file mode 100644 index 00000000..8520fe49 --- /dev/null +++ b/src/app/api/super-admin/OfficesController.ts @@ -0,0 +1,113 @@ +import { Response, Request } from "express"; +import { Controller, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import OfficesService from "@Services/super-admin/OfficesService/OfficesService"; +import { Service } from "typedi"; +import { Offices } from "@prisma/client"; +import { Office as OfficeResource } from "le-coffre-resources/dist/SuperAdmin"; +import { validateOrReject } from "class-validator"; + +@Controller() +@Service() +export default class OfficesController extends ApiController { + constructor(private officesService: OfficesService) { + super(); + } + /** + * @description Get all offices + */ + @Get("/api/v1/super-admin/offices") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + //call service to get prisma entity + const officesEntity: Offices[] = await this.officesService.get(query); + //Hydrate ressource with prisma entity + const offices = OfficeResource.map(OfficeResource, officesEntity, { strategy: "excludeAll" }); + //success + this.httpSuccess(response, offices); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + /** + * @description Create a new office + */ + @Post("/api/v1/super-admin/offices") + protected async post(req: Request, response: Response) { + try { + //init IUser resource with request body values + const officeEntity = OfficeResource.hydrate(req.body); + //validate user + await validateOrReject(officeEntity, { groups: ["createOffice"], forbidUnknownValues: false }); + //call service to get prisma entity + const prismaEntityCreated = await this.officesService.create(officeEntity); + //Hydrate ressource with prisma entity + const officeEntityCreated = OfficeResource.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + //success + this.httpSuccess(response, officeEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + /** + * @description Modify a specific office by uid + */ + @Put("/api/v1/super-admin/offices/:uid") + protected async put(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + //init IUser resource with request body values + const officeEntity = OfficeResource.hydrate(req.body); + //validate user + await validateOrReject(officeEntity, { groups: ["update"] }); + //call service to get prisma entity + const prismaEntityUpdated = await this.officesService.update(uid, officeEntity); + //Hydrate ressource with prisma entity + const officeEntityUpdated = OfficeResource.hydrate(prismaEntityUpdated, { + strategy: "excludeAll", + }); + //success + this.httpSuccess(response, officeEntityUpdated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + /** + * @description Get a specific office by uid + */ + @Get("/api/v1/super-admin/offices/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + let officeEntity: Offices; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + officeEntity = await this.officesService.getByUid(uid, query); + } else { + //call service to get prisma entity + officeEntity = await this.officesService.getByUid(uid); + } + //Hydrate ressource with prisma entity + const office = OfficeResource.hydrate(officeEntity, { strategy: "excludeAll" }); + //success + this.httpSuccess(response, office); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/api/super-admin/UsersController.ts b/src/app/api/super-admin/UsersController.ts new file mode 100644 index 00000000..aee392e8 --- /dev/null +++ b/src/app/api/super-admin/UsersController.ts @@ -0,0 +1,130 @@ +import { Response, Request } from "express"; +import { Controller, Get, Post, Put } from "@ControllerPattern/index"; +import ApiController from "@Common/system/controller-pattern/ApiController"; +import UsersService from "@Services/super-admin/UsersService/UsersService"; +import { Service } from "typedi"; +import { validateOrReject } from "class-validator"; +import User from "le-coffre-resources/dist/Notary"; +import { Users } from "@prisma/client"; + +@Controller() +@Service() +export default class UsersController extends ApiController { + constructor(private usersService: UsersService) { + super(); + } + + /** + * @description Get all users + */ + @Get("/api/v1/super-admin/users") + protected async get(req: Request, response: Response) { + try { + //get query + const query = JSON.parse(req.query["q"] as string); + + //call service to get prisma entity + const usersEntity = await this.usersService.get(query); + + //Hydrate ressource with prisma entity + const users = User.map(User, usersEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, users); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Create a new user + */ + @Post("/api/v1/super-admin/users") + protected async getAddresses(req: Request, response: Response) { + try { + //init IUser resource with request body values + const userEntity = User.hydrate(req.body); + + //validate user + await validateOrReject(userEntity, { groups: ["createUser"] }); + + //call service to get prisma entity + const prismaEntityCreated = await this.usersService.create(userEntity); + + //Hydrate ressource with prisma entity + const userEntityCreated = User.hydrate(prismaEntityCreated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, userEntityCreated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Modify a specific user by uid + */ + @Put("/api/v1/super-admin/users/:uid") + protected async put(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + //init IUser resource with request body values + const userEntity = User.hydrate(req.body); + + //validate user + await validateOrReject(userEntity, { groups: ["update"] }); + + //call service to get prisma entity + const prismaEntityUpdated = await this.usersService.update(uid, userEntity); + + //Hydrate ressource with prisma entity + const userEntityUpdated = User.hydrate(prismaEntityUpdated, { + strategy: "excludeAll", + }); + + //success + this.httpSuccess(response, userEntityUpdated); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } + + /** + * @description Get a specific user by uid + */ + @Get("/api/v1/super-admin/users/:uid") + protected async getOneByUid(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + if (!uid) { + throw new Error("No uid provided"); + } + let userEntity: Users; + //get query + if (req.query["q"]) { + const query = JSON.parse(req.query["q"] as string); + userEntity = await this.usersService.getByUid(uid, query); + } else { + //call service to get prisma entity + userEntity = await this.usersService.getByUid(uid); + } + + //Hydrate ressource with prisma entity + const user = User.hydrate(userEntity, { strategy: "excludeAll" }); + + //success + this.httpSuccess(response, user); + } catch (error) { + this.httpBadRequest(response, error); + return; + } + } +} diff --git a/src/app/index.ts b/src/app/index.ts index 303407ef..e2b0a51f 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -1,13 +1,17 @@ import { Container } from "typedi"; import HomeController from "./HomeController"; -import UsersController from "./api/UsersController"; -import FoldersController from "./api/FoldersController"; -import CustomersController from "./api/CustomersController"; -import OfficesController from "./api/OfficesController"; -import DeedsController from "./api/DeedsController"; -import DeedTypesController from "./api/DeedTypesController"; -import DocumentsController from "./api/DocumentsController"; -import DocumentTypesController from "./api/DocumentTypesController"; +import UsersController from "./api/super-admin/UsersController"; +import FoldersController from "./api/super-admin/OfficeFoldersController"; +import CustomersController from "./api/super-admin/CustomersController"; +import OfficesController from "./api/super-admin/OfficesController"; +import DeedsController from "./api/super-admin/DeedsController"; +import DeedTypesController from "./api/super-admin/DeedTypesController"; +import DocumentsController from "./api/super-admin/DocumentsController"; +import DocumentTypesController from "./api/super-admin/DocumentTypesController"; +import IdNotUserInfoController from "./api/idnot-user/UserInfoController"; +import DocumentsControllerCustomer from "./api/customer/DocumentsController"; +import FilesController from "./api/super-admin/FilesController"; + /** * @description This allow to declare all controllers used in the application @@ -23,5 +27,8 @@ export default { Container.get(DeedTypesController); Container.get(DocumentsController); Container.get(DocumentTypesController); + Container.get(IdNotUserInfoController); + Container.get(FilesController); + Container.get(DocumentsControllerCustomer); }, }; diff --git a/src/app/middlewares/ErrorHandler.ts b/src/app/middlewares/ErrorHandler.ts index ac0b0f4d..274f5923 100644 --- a/src/app/middlewares/ErrorHandler.ts +++ b/src/app/middlewares/ErrorHandler.ts @@ -10,7 +10,7 @@ export default function errorHandler(error: any, req: Request, response: Respons if (error instanceof SyntaxError && errorStatus === 400 && "body" in error) { response.status(HttpCodes.BAD_REQUEST).send({ body: error["body"], - type: error as any ["type"], + type: error as any["type"], }); return; } @@ -22,4 +22,3 @@ export default function errorHandler(error: any, req: Request, response: Respons next(error); } - diff --git a/src/app/middlewares/FileHandler.ts b/src/app/middlewares/FileHandler.ts new file mode 100644 index 00000000..3a6138ac --- /dev/null +++ b/src/app/middlewares/FileHandler.ts @@ -0,0 +1,22 @@ +import { NextFunction, Request, Response } from "express"; +import multer from "multer"; + +export default function fileHandler(req: Request, response: Response, next: NextFunction) { + const storage = multer.memoryStorage() + const upload = multer({storage:storage}).single('file'); + + // Here call the upload middleware of multer + upload(req, response, function (err) { + if (err instanceof multer.MulterError) { + // A Multer error occurred when uploading. + const err = new Error('Multer error'); + return next(err) + } else if (err) { + // An unknown error occurred when uploading. + const err = new Error('Server Error') + return next(err) + } + next() + }) +} + diff --git a/src/common/config/database/IDatabaseConfig.ts b/src/common/config/database/IDatabaseConfig.ts index 24796543..2b03000e 100644 --- a/src/common/config/database/IDatabaseConfig.ts +++ b/src/common/config/database/IDatabaseConfig.ts @@ -1,4 +1,4 @@ -export default interface IDatabaseConfig { - name: string; - url?: string; -} +export default interface IDatabaseConfig { + name: string; + url?: string; +} diff --git a/src/common/config/variables/Variables.ts b/src/common/config/variables/Variables.ts index 482a9dce..bc20851c 100644 --- a/src/common/config/variables/Variables.ts +++ b/src/common/config/variables/Variables.ts @@ -1,6 +1,6 @@ -import { Service } from "typedi"; -import { validateOrReject, IsNotEmpty, IsOptional } from "class-validator"; +import { IsNotEmpty, IsOptional, validateOrReject } from "class-validator"; import dotenv from "dotenv"; +import { Service } from "typedi"; @Service() export class BackendVariables { @@ -8,10 +8,10 @@ export class BackendVariables { public readonly DATABASE_PORT!: string; @IsNotEmpty() - public readonly DATABASE_HOSTNAME!: string; + public readonly DATABASE_HOST!: string; @IsNotEmpty() - public readonly DATABASE_USER!: string; + public readonly DATABASE_USERNAME!: string; @IsNotEmpty() public readonly DATABASE_PASSWORD!: string; @@ -33,21 +33,48 @@ export class BackendVariables { public readonly NODE_ENV = process.env.NODE_ENV; + @IsNotEmpty() + public readonly IDNOT_CONNEXION_URL!: string; + + @IsNotEmpty() + public readonly IDNOT_CLIENT_ID!: string; + + @IsNotEmpty() + public readonly IDNOT_CLIENT_SECRET!: string; + + @IsNotEmpty() + public readonly IDNOT_REDIRECT_URL!: string; + + @IsNotEmpty() + public readonly PINATA_API_KEY!: string; + + @IsNotEmpty() + public readonly PINATA_API_SECRET!: string; + + @IsNotEmpty() + public readonly PINATA_GATEWAY!: string; + public constructor() { dotenv.config(); this.DATABASE_PORT = process.env["DATABASE_PORT"]!; - this.DATABASE_HOSTNAME = process.env["DATABASE_HOSTNAME"]!; - this.DATABASE_USER = process.env["DATABASE_USER"]!; + this.DATABASE_HOST = process.env["DATABASE_HOST"]!; + this.DATABASE_USERNAME = process.env["DATABASE_USERNAME"]!; this.DATABASE_PASSWORD = process.env["DATABASE_PASSWORD"]!; this.DATABASE_NAME = process.env["DATABASE_NAME"]!; this.API_ROOT_URL = process.env["API_ROOT_URL"]!; this.APP_PORT = process.env["APP_PORT"]!; this.APP_ROOT_URL = process.env["APP_ROOT_URL"]!; this.APP_LABEL = process.env["APP_LABEL"]!; + this.IDNOT_CONNEXION_URL = process.env["IDNOT_CONNEXION_URL"]!; + this.IDNOT_CLIENT_ID = process.env["IDNOT_CLIENT_ID"]!; + this.IDNOT_CLIENT_SECRET = process.env["IDNOT_CLIENT_SECRET"]!; + this.IDNOT_REDIRECT_URL = process.env["IDNOT_REDIRECT_URL"]!; + this.PINATA_API_KEY = process.env["PINATA_API_KEY"]!; + this.PINATA_API_SECRET = process.env["PINATA_API_SECRET"]!; + this.PINATA_GATEWAY = process.env["PINATA_GATEWAY"]!; } public async validate() { await validateOrReject(this); return this; } } - diff --git a/src/common/databases/database.ts b/src/common/databases/database.ts index ecd8b810..9d8b85ac 100644 --- a/src/common/databases/database.ts +++ b/src/common/databases/database.ts @@ -27,4 +27,3 @@ export default class Database { return name; } } - diff --git a/src/common/databases/migrations/20230426144239_init/migration.sql b/src/common/databases/migrations/20230426144239_init/migration.sql new file mode 100644 index 00000000..d017a9c4 --- /dev/null +++ b/src/common/databases/migrations/20230426144239_init/migration.sql @@ -0,0 +1,449 @@ +-- CreateEnum +CREATE TYPE "ECivility" AS ENUM ('MALE', 'FEMALE', 'OTHERS'); + +-- CreateEnum +CREATE TYPE "EFolderStatus" AS ENUM ('LIVE', 'ARCHIVED'); + +-- CreateEnum +CREATE TYPE "EOfficeStatus" AS ENUM ('ACTIVATED', 'DESACTIVATED'); + +-- CreateEnum +CREATE TYPE "ENotificationStatus" AS ENUM ('READ', 'UNREAD'); + +-- CreateEnum +CREATE TYPE "ECustomerStatus" AS ENUM ('VALIDATED', 'PENDING', 'ERRONED'); + +-- CreateEnum +CREATE TYPE "EDocumentStatus" AS ENUM ('ASKED', 'DEPOSITED', 'VALIDATED', 'ANCHORED', 'REFUSED'); + +-- CreateTable +CREATE TABLE "addresses" ( + "uid" TEXT NOT NULL, + "address" VARCHAR(255) NOT NULL, + "city" VARCHAR(255) NOT NULL, + "zip_code" INTEGER NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "addresses_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "contacts" ( + "uid" TEXT NOT NULL, + "first_name" VARCHAR(255) NOT NULL, + "last_name" VARCHAR(255) NOT NULL, + "email" VARCHAR(255) NOT NULL, + "phone_number" VARCHAR(50), + "cell_phone_number" VARCHAR(50), + "civility" "ECivility" NOT NULL DEFAULT 'MALE', + "address_uid" VARCHAR(255) NOT NULL, + "birthdate" TIMESTAMP(3), + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "contacts_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "users" ( + "uid" TEXT NOT NULL, + "idNot" VARCHAR(255) NOT NULL, + "contact_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + "office_uid" VARCHAR(255) NOT NULL, + + CONSTRAINT "users_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "offices" ( + "uid" TEXT NOT NULL, + "idNot" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "crpcen" VARCHAR(255) NOT NULL, + "address_uid" VARCHAR(255) NOT NULL, + "office_status" "EOfficeStatus" NOT NULL DEFAULT 'DESACTIVATED', + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "offices_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "customers" ( + "uid" TEXT NOT NULL, + "status" "ECustomerStatus" NOT NULL DEFAULT 'PENDING', + "contact_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "customers_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "user_has_notifications" ( + "uid" TEXT NOT NULL, + "user_uid" VARCHAR(255) NOT NULL, + "notification_uid" VARCHAR(255) NOT NULL, + "notification_status" "ENotificationStatus" NOT NULL DEFAULT 'UNREAD', + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "user_has_notifications_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "notifications" ( + "uid" TEXT NOT NULL, + "message" VARCHAR(255) NOT NULL, + "redirection_url" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "notifications_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "office_folders" ( + "uid" TEXT NOT NULL, + "folder_number" VARCHAR(255) NOT NULL, + "name" VARCHAR(255) NOT NULL, + "description" VARCHAR(255), + "archived_description" VARCHAR(255), + "status" "EFolderStatus" NOT NULL DEFAULT 'LIVE', + "deed_uid" VARCHAR(255) NOT NULL, + "office_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "office_folders_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "office_folder_has_customers" ( + "uid" TEXT NOT NULL, + "customer_uid" VARCHAR(255) NOT NULL, + "office_folder_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "office_folder_has_customers_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "office_folder_has_stakeholder" ( + "uid" TEXT NOT NULL, + "office_folder_uid" VARCHAR(255) NOT NULL, + "user_stakeholder_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "office_folder_has_stakeholder_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "documents" ( + "uid" TEXT NOT NULL, + "document_status" "EDocumentStatus" NOT NULL DEFAULT 'ASKED', + "document_type_uid" VARCHAR(255) NOT NULL, + "blockchain_anchor_uid" VARCHAR(255), + "folder_uid" VARCHAR(255) NOT NULL, + "depositor_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "documents_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "document_history" ( + "uid" TEXT NOT NULL, + "document_status" "EDocumentStatus" NOT NULL DEFAULT 'ASKED', + "refused_reason" VARCHAR(255), + "document_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "document_history_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "files" ( + "uid" TEXT NOT NULL, + "document_uid" VARCHAR(255) NOT NULL, + "file_path" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "files_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "blockchain_anchors" ( + "uid" TEXT NOT NULL, + "smartSigJobId" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "blockchain_anchors_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "document_types" ( + "uid" TEXT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "public_description" VARCHAR(255) NOT NULL, + "private_description" VARCHAR(255), + "office_uid" VARCHAR(255) NOT NULL, + "archived_at" TIMESTAMP(3), + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "document_types_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "deed_has_document_types" ( + "uid" TEXT NOT NULL, + "document_type_uid" VARCHAR(255) NOT NULL, + "deed_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "deed_has_document_types_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "deed" ( + "uid" TEXT NOT NULL, + "deed_type_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "deed_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "deed_types" ( + "uid" TEXT NOT NULL, + "name" VARCHAR(255) NOT NULL, + "description" VARCHAR(255) NOT NULL, + "archived_at" TIMESTAMP(3), + "office_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "deed_types_pkey" PRIMARY KEY ("uid") +); + +-- CreateTable +CREATE TABLE "deed_type_has_document_types" ( + "uid" TEXT NOT NULL, + "document_type_uid" VARCHAR(255) NOT NULL, + "deed_type_uid" VARCHAR(255) NOT NULL, + "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3), + + CONSTRAINT "deed_type_has_document_types_pkey" PRIMARY KEY ("uid") +); + +-- CreateIndex +CREATE UNIQUE INDEX "addresses_uid_key" ON "addresses"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "contacts_uid_key" ON "contacts"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "contacts_email_key" ON "contacts"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "contacts_cell_phone_number_key" ON "contacts"("cell_phone_number"); + +-- CreateIndex +CREATE UNIQUE INDEX "contacts_address_uid_key" ON "contacts"("address_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "users_uid_key" ON "users"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "users_idNot_key" ON "users"("idNot"); + +-- CreateIndex +CREATE UNIQUE INDEX "users_contact_uid_key" ON "users"("contact_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "offices_uid_key" ON "offices"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "offices_idNot_key" ON "offices"("idNot"); + +-- CreateIndex +CREATE UNIQUE INDEX "offices_crpcen_key" ON "offices"("crpcen"); + +-- CreateIndex +CREATE UNIQUE INDEX "offices_address_uid_key" ON "offices"("address_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "customers_uid_key" ON "customers"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "customers_contact_uid_key" ON "customers"("contact_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "user_has_notifications_uid_key" ON "user_has_notifications"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "user_has_notifications_notification_uid_user_uid_key" ON "user_has_notifications"("notification_uid", "user_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "notifications_uid_key" ON "notifications"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_folders_uid_key" ON "office_folders"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_folders_deed_uid_key" ON "office_folders"("deed_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_folders_folder_number_office_uid_key" ON "office_folders"("folder_number", "office_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_folder_has_customers_uid_key" ON "office_folder_has_customers"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_folder_has_customers_office_folder_uid_customer_uid_key" ON "office_folder_has_customers"("office_folder_uid", "customer_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_folder_has_stakeholder_uid_key" ON "office_folder_has_stakeholder"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "office_folder_has_stakeholder_office_folder_uid_user_stakeh_key" ON "office_folder_has_stakeholder"("office_folder_uid", "user_stakeholder_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "documents_uid_key" ON "documents"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "document_history_uid_key" ON "document_history"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "files_uid_key" ON "files"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "files_file_path_key" ON "files"("file_path"); + +-- CreateIndex +CREATE UNIQUE INDEX "blockchain_anchors_uid_key" ON "blockchain_anchors"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "blockchain_anchors_smartSigJobId_key" ON "blockchain_anchors"("smartSigJobId"); + +-- CreateIndex +CREATE UNIQUE INDEX "document_types_uid_key" ON "document_types"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "document_types_name_office_uid_key" ON "document_types"("name", "office_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "deed_has_document_types_uid_key" ON "deed_has_document_types"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "deed_has_document_types_deed_uid_document_type_uid_key" ON "deed_has_document_types"("deed_uid", "document_type_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "deed_uid_key" ON "deed"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "deed_types_uid_key" ON "deed_types"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "deed_types_name_office_uid_key" ON "deed_types"("name", "office_uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "deed_type_has_document_types_uid_key" ON "deed_type_has_document_types"("uid"); + +-- CreateIndex +CREATE UNIQUE INDEX "deed_type_has_document_types_deed_type_uid_document_type_ui_key" ON "deed_type_has_document_types"("deed_type_uid", "document_type_uid"); + +-- AddForeignKey +ALTER TABLE "contacts" ADD CONSTRAINT "contacts_address_uid_fkey" FOREIGN KEY ("address_uid") REFERENCES "addresses"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "users" ADD CONSTRAINT "users_contact_uid_fkey" FOREIGN KEY ("contact_uid") REFERENCES "contacts"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "users" ADD CONSTRAINT "users_office_uid_fkey" FOREIGN KEY ("office_uid") REFERENCES "offices"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "offices" ADD CONSTRAINT "offices_address_uid_fkey" FOREIGN KEY ("address_uid") REFERENCES "addresses"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "customers" ADD CONSTRAINT "customers_contact_uid_fkey" FOREIGN KEY ("contact_uid") REFERENCES "contacts"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "user_has_notifications" ADD CONSTRAINT "user_has_notifications_user_uid_fkey" FOREIGN KEY ("user_uid") REFERENCES "users"("uid") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "user_has_notifications" ADD CONSTRAINT "user_has_notifications_notification_uid_fkey" FOREIGN KEY ("notification_uid") REFERENCES "notifications"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "office_folders" ADD CONSTRAINT "office_folders_deed_uid_fkey" FOREIGN KEY ("deed_uid") REFERENCES "deed"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "office_folders" ADD CONSTRAINT "office_folders_office_uid_fkey" FOREIGN KEY ("office_uid") REFERENCES "offices"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "office_folder_has_customers" ADD CONSTRAINT "office_folder_has_customers_customer_uid_fkey" FOREIGN KEY ("customer_uid") REFERENCES "customers"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "office_folder_has_customers" ADD CONSTRAINT "office_folder_has_customers_office_folder_uid_fkey" FOREIGN KEY ("office_folder_uid") REFERENCES "office_folders"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "office_folder_has_stakeholder" ADD CONSTRAINT "office_folder_has_stakeholder_office_folder_uid_fkey" FOREIGN KEY ("office_folder_uid") REFERENCES "office_folders"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "office_folder_has_stakeholder" ADD CONSTRAINT "office_folder_has_stakeholder_user_stakeholder_uid_fkey" FOREIGN KEY ("user_stakeholder_uid") REFERENCES "users"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "documents" ADD CONSTRAINT "documents_document_type_uid_fkey" FOREIGN KEY ("document_type_uid") REFERENCES "document_types"("uid") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "documents" ADD CONSTRAINT "documents_blockchain_anchor_uid_fkey" FOREIGN KEY ("blockchain_anchor_uid") REFERENCES "blockchain_anchors"("uid") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "documents" ADD CONSTRAINT "documents_folder_uid_fkey" FOREIGN KEY ("folder_uid") REFERENCES "office_folders"("uid") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "documents" ADD CONSTRAINT "documents_depositor_uid_fkey" FOREIGN KEY ("depositor_uid") REFERENCES "customers"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "document_history" ADD CONSTRAINT "document_history_document_uid_fkey" FOREIGN KEY ("document_uid") REFERENCES "documents"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "files" ADD CONSTRAINT "files_document_uid_fkey" FOREIGN KEY ("document_uid") REFERENCES "documents"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "document_types" ADD CONSTRAINT "document_types_office_uid_fkey" FOREIGN KEY ("office_uid") REFERENCES "offices"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "deed_has_document_types" ADD CONSTRAINT "deed_has_document_types_document_type_uid_fkey" FOREIGN KEY ("document_type_uid") REFERENCES "document_types"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "deed_has_document_types" ADD CONSTRAINT "deed_has_document_types_deed_uid_fkey" FOREIGN KEY ("deed_uid") REFERENCES "deed"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "deed" ADD CONSTRAINT "deed_deed_type_uid_fkey" FOREIGN KEY ("deed_type_uid") REFERENCES "deed_types"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "deed_types" ADD CONSTRAINT "deed_types_office_uid_fkey" FOREIGN KEY ("office_uid") REFERENCES "offices"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "deed_type_has_document_types" ADD CONSTRAINT "deed_type_has_document_types_document_type_uid_fkey" FOREIGN KEY ("document_type_uid") REFERENCES "document_types"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "deed_type_has_document_types" ADD CONSTRAINT "deed_type_has_document_types_deed_type_uid_fkey" FOREIGN KEY ("deed_type_uid") REFERENCES "deed_types"("uid") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AlterTable +ALTER TABLE "contacts" ALTER COLUMN "cell_phone_number" SET NOT NULL, +ALTER COLUMN "address_uid" DROP NOT NULL; \ No newline at end of file diff --git a/src/common/databases/migrations/20230505075245_v1/migration.sql b/src/common/databases/migrations/20230505075245_v1/migration.sql new file mode 100644 index 00000000..c212eab0 --- /dev/null +++ b/src/common/databases/migrations/20230505075245_v1/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `iv` to the `files` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "files" ADD COLUMN "iv" VARCHAR(255) NOT NULL; diff --git a/src/common/databases/migrations/20230505131655_v2/migration.sql b/src/common/databases/migrations/20230505131655_v2/migration.sql new file mode 100644 index 00000000..a7f5aaa6 --- /dev/null +++ b/src/common/databases/migrations/20230505131655_v2/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `file_name` to the `files` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "files" ADD COLUMN "file_name" VARCHAR(255) NOT NULL; diff --git a/src/common/databases/migrations/20230510204321_v4/migration.sql b/src/common/databases/migrations/20230510204321_v4/migration.sql new file mode 100644 index 00000000..463c9e19 --- /dev/null +++ b/src/common/databases/migrations/20230510204321_v4/migration.sql @@ -0,0 +1,9 @@ +/* + Warnings: + + - You are about to drop the column `iv` on the `files` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "files" DROP COLUMN "iv", +ADD COLUMN "key" VARCHAR(255); diff --git a/src/common/databases/migrations/20230511085908_v5/migration.sql b/src/common/databases/migrations/20230511085908_v5/migration.sql new file mode 100644 index 00000000..a5b3abcb --- /dev/null +++ b/src/common/databases/migrations/20230511085908_v5/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "files" ADD COLUMN "archived_at" TIMESTAMP(3); diff --git a/src/common/databases/schema.prisma b/src/common/databases/schema.prisma index 8d670423..742b331b 100644 --- a/src/common/databases/schema.prisma +++ b/src/common/databases/schema.prisma @@ -2,6 +2,7 @@ generator client { provider = "prisma-client-js" + //binaryTargets = ["native"] } datasource db { @@ -17,30 +18,31 @@ datasource db { // id String @unique @default(auto()) @map("_id") @db.ObjectId // @map de la table checker le naming avec le tiret model Addresses { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) address String @db.VarChar(255) city String @db.VarChar(255) zip_code Int - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt contacts Contacts? - office Office? + office Offices? @@map("addresses") } model Contacts { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) first_name String @db.VarChar(255) last_name String @db.VarChar(255) - email String @db.VarChar(255) + email String @unique @db.VarChar(255) phone_number String? @db.VarChar(50) - cell_phone_number String? @db.VarChar(50) + cell_phone_number String @unique @db.VarChar(50) civility ECivility @default(MALE) - address Addresses @relation(fields: [address_uuid], references: [uuid]) - address_uuid String @unique @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + address Addresses? @relation(fields: [address_uid], references: [uid], onDelete: Cascade) + address_uid String? @unique @db.VarChar(255) + birthdate DateTime? + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt users Users? customers Customers? @@ -48,44 +50,45 @@ model Contacts { } model Users { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) @map("uid") idNot String @unique @db.VarChar(255) - contact Contacts @relation(fields: [contact_uuid], references: [uuid]) - contact_uuid String @unique @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt - office_membership Office @relation(fields: [office_uuid], references: [uuid]) - office_uuid String @db.VarChar(255) + contact Contacts @relation(fields: [contact_uid], references: [uid], onDelete: Cascade) + contact_uid String @unique @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + office_membership Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade) + office_uid String @db.VarChar(255) user_has_notifications UserHasNotifications[] office_folder_has_stakeholder OfficeFolderHasStakeholders[] @@map("users") } -model Office { - uuid String @id @unique @default(uuid()) +model Offices { + uid String @id @unique @default(uuid()) idNot String @unique @db.VarChar(255) name String @db.VarChar(255) crpcen String @unique @db.VarChar(255) - address Addresses @relation(fields: [address_uuid], references: [uuid]) - address_uuid String @unique @db.VarChar(255) + address Addresses @relation(fields: [address_uid], references: [uid], onDelete: Cascade) + address_uid String @unique @db.VarChar(255) office_status EOfficeStatus @default(DESACTIVATED) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt deed_types DeedTypes[] users Users[] office_folders OfficeFolders[] + document_types DocumentTypes[] @@map("offices") } model Customers { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) status ECustomerStatus @default(PENDING) - contact Contacts @relation(fields: [contact_uuid], references: [uuid]) - contact_uuid String @unique @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + contact Contacts @relation(fields: [contact_uid], references: [uid], onDelete: Cascade) + contact_uid String @unique @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt office_folder_has_customers OfficeFolderHasCustomers[] documents Documents[] @@ -93,158 +96,169 @@ model Customers { } model UserHasNotifications { - uuid String @id @unique @default(uuid()) - user Users @relation(fields: [user_uuid], references: [uuid]) - user_uuid String @db.VarChar(255) - notification Notifications @relation(fields: [notification_uuid], references: [uuid]) - notification_uuid String @db.VarChar(255) + uid String @id @unique @default(uuid()) + user Users @relation(fields: [user_uid], references: [uid]) + user_uid String @db.VarChar(255) + notification Notifications @relation(fields: [notification_uid], references: [uid], onDelete: Cascade) + notification_uid String @db.VarChar(255) notification_status ENotificationStatus @default(UNREAD) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + @@unique([notification_uid, user_uid]) @@map("user_has_notifications") } model Notifications { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) message String @db.VarChar(255) redirection_url String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt user_has_notifications UserHasNotifications[] @@map("notifications") } model OfficeFolders { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) folder_number String @db.VarChar(255) name String @db.VarChar(255) description String? @db.VarChar(255) archived_description String? @db.VarChar(255) status EFolderStatus @default(LIVE) - deed Deed @relation(fields: [deed_uuid], references: [uuid]) - deed_uuid String @unique @db.VarChar(255) - office Office @relation(fields: [office_uuid], references: [uuid]) - office_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + deed Deeds @relation(fields: [deed_uid], references: [uid], onDelete: Cascade) + deed_uid String @unique @db.VarChar(255) + office Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade) + office_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt office_folder_has_customers OfficeFolderHasCustomers[] office_folder_has_stakeholder OfficeFolderHasStakeholders[] documents Documents[] + @@unique([folder_number, office_uid]) @@map("office_folders") } model OfficeFolderHasCustomers { - uuid String @id @unique @default(uuid()) - customer Customers @relation(fields: [customer_uuid], references: [uuid]) - customer_uuid String @db.VarChar(255) - office_folder OfficeFolders @relation(fields: [office_folder_uuid], references: [uuid]) - office_folder_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + uid String @id @unique @default(uuid()) + customer Customers @relation(fields: [customer_uid], references: [uid], onDelete: Cascade) + customer_uid String @db.VarChar(255) + office_folder OfficeFolders @relation(fields: [office_folder_uid], references: [uid], onDelete: Cascade) + office_folder_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + @@unique([office_folder_uid, customer_uid]) @@map("office_folder_has_customers") } model OfficeFolderHasStakeholders { - uuid String @id @unique @default(uuid()) - office_folder OfficeFolders @relation(fields: [office_folder_uuid], references: [uuid]) - office_folder_uuid String @db.VarChar(255) - user_stakeholder Users @relation(fields: [user_stakeholder_uuid], references: [uuid]) - user_stakeholder_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + uid String @id @unique @default(uuid()) + office_folder OfficeFolders @relation(fields: [office_folder_uid], references: [uid], onDelete: Cascade) + office_folder_uid String @db.VarChar(255) + user_stakeholder Users @relation(fields: [user_stakeholder_uid], references: [uid], onDelete: Cascade) + user_stakeholder_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + @@unique([office_folder_uid, user_stakeholder_uid]) @@map("office_folder_has_stakeholder") } model Documents { - uuid String @id @unique @default(uuid()) - document_status EDocumentStatus @default(ASKED) - document_type DocumentTypes @relation(fields: [type_uuid], references: [uuid]) - type_uuid String @db.VarChar(255) - blockchain_anchor BlockchainAnchors? @relation(fields: [blockchain_anchor_uuid], references: [uuid]) - blockchain_anchor_uuid String? @db.VarChar(255) - folder OfficeFolders @relation(fields: [folder_uuid], references: [uuid]) - folder_uuid String @db.VarChar(255) - depositor Customers @relation(fields: [depositor_uuid], references: [uuid]) - depositor_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt - files Files[] - document_history DocumentHistory[] + uid String @id @unique @default(uuid()) + document_status EDocumentStatus @default(ASKED) + document_type DocumentTypes @relation(fields: [document_type_uid], references: [uid]) + document_type_uid String @db.VarChar(255) + blockchain_anchor BlockchainAnchors? @relation(fields: [blockchain_anchor_uid], references: [uid]) + blockchain_anchor_uid String? @db.VarChar(255) + folder OfficeFolders @relation(fields: [folder_uid], references: [uid]) + folder_uid String @db.VarChar(255) + depositor Customers @relation(fields: [depositor_uid], references: [uid], onDelete: Cascade) + depositor_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + files Files[] + document_history DocumentHistory[] @@map("documents") } model DocumentHistory { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) document_status EDocumentStatus @default(ASKED) refused_reason String? @db.VarChar(255) - document Documents @relation(fields: [document_uuid], references: [uuid]) - document_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + document Documents @relation(fields: [document_uid], references: [uid], onDelete: Cascade) + document_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt @@map("document_history") } model Files { - uuid String @id @unique @default(uuid()) - document Documents @relation(fields: [document_uuid], references: [uuid]) - document_uuid String @db.VarChar(255) - file_path String? @unique @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + uid String @id @unique @default(uuid()) + document Documents @relation(fields: [document_uid], references: [uid], onDelete: Cascade) + document_uid String @db.VarChar(255) + file_path String @unique @db.VarChar(255) + file_name String @db.VarChar(255) + archived_at DateTime? + key String? @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt @@map("files") } model BlockchainAnchors { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) smartSigJobId String @unique @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt documents Documents[] @@map("blockchain_anchors") } model DocumentTypes { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) name String @db.VarChar(255) public_description String @db.VarChar(255) private_description String? @db.VarChar(255) + office Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade) + office_uid String @db.VarChar(255) archived_at DateTime? - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt documents Documents[] deed_has_document_types DeedHasDocumentTypes[] deed_type_has_document_types DeedTypeHasDocumentTypes[] + @@unique([name, office_uid]) @@map("document_types") } model DeedHasDocumentTypes { - uuid String @id @unique @default(uuid()) - document_type DocumentTypes @relation(fields: [document_type_uuid], references: [uuid]) - document_type_uuid String @db.VarChar(255) - deed Deed @relation(fields: [deed_uuid], references: [uuid]) - deed_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + uid String @id @unique @default(uuid()) + document_type DocumentTypes @relation(fields: [document_type_uid], references: [uid], onDelete: Cascade) + document_type_uid String @db.VarChar(255) + deed Deeds @relation(fields: [deed_uid], references: [uid], onDelete: Cascade) + deed_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + @@unique([deed_uid, document_type_uid]) @@map("deed_has_document_types") } -model Deed { - uuid String @id @unique @default(uuid()) - deed_type DeedTypes @relation(fields: [deed_type_uuid], references: [uuid]) - deed_type_uuid String @unique @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt +model Deeds { + uid String @id @unique @default(uuid()) + deed_type DeedTypes @relation(fields: [deed_type_uid], references: [uid], onDelete: Cascade) + deed_type_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt deed_has_document_types DeedHasDocumentTypes[] office_folder OfficeFolders? @@ -252,33 +266,34 @@ model Deed { } model DeedTypes { - uuid String @id @unique @default(uuid()) + uid String @id @unique @default(uuid()) name String @db.VarChar(255) description String @db.VarChar(255) archived_at DateTime? - office Office @relation(fields: [office_uuid], references: [uuid]) - office_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt - deed Deed? + office Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade) + office_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + deed Deeds[] deed_type_has_document_types DeedTypeHasDocumentTypes[] + @@unique([name, office_uid]) @@map("deed_types") } model DeedTypeHasDocumentTypes { - uuid String @id @unique @default(uuid()) - document_type DocumentTypes @relation(fields: [document_type_uuid], references: [uuid]) - document_type_uuid String @db.VarChar(255) - deed_type DeedTypes @relation(fields: [deed_type_uuid], references: [uuid]) - deed_type_uuid String @db.VarChar(255) - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + uid String @id @unique @default(uuid()) + document_type DocumentTypes @relation(fields: [document_type_uid], references: [uid], onDelete: Cascade) + document_type_uid String @db.VarChar(255) + deed_type DeedTypes @relation(fields: [deed_type_uid], references: [uid], onDelete: Cascade) + deed_type_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt + @@unique([deed_type_uid, document_type_uid]) @@map("deed_type_has_document_types") } -// TODO SE RENSEIGNER SUR LES ENUMS enum ECivility { MALE FEMALE diff --git a/src/common/databases/seeders/seeder.ts b/src/common/databases/seeders/seeder.ts new file mode 100644 index 00000000..39f8f7cd --- /dev/null +++ b/src/common/databases/seeders/seeder.ts @@ -0,0 +1,605 @@ +import { + Addresses, + Contacts, + Customers, + DeedHasDocumentTypes, + DeedTypeHasDocumentTypes, + DeedTypes, + Deeds, + DocumentHistory, + DocumentTypes, + Documents, + EDocumentStatus, + EFolderStatus, + EOfficeStatus, + Files, + OfficeFolderHasCustomers, + OfficeFolders, + Offices, + Users, + ECivility, + ECustomerStatus, + PrismaClient, +} from "@prisma/client"; + +(async () => { + const prisma = new PrismaClient(); + + const randomString = () => { + const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + let result = ""; + for (let i = 10; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; + return result; + }; + const uidCustomer1: string = randomString(); + const uidCustomer2: string = randomString(); + + const uidContact1: string = randomString(); + const uidContact2: string = randomString(); + const uidContact3: string = randomString(); + const uidContact4: string = randomString(); + + const uidAddress1: string = randomString(); + const uidAddress2: string = randomString(); + const uidAddress3: string = randomString(); + const uidAddress4: string = randomString(); + + const uidOffice1: string = randomString(); + const uidOffice2: string = randomString(); + + const uidUser1: string = randomString(); + const uidUser2: string = randomString(); + + const uidOfficeFolder1: string = randomString(); + const uidOfficeFolder2: string = randomString(); + const uidOfficeFolder3: string = randomString(); + const uidOfficeFolder4: string = randomString(); + const uidOfficeFolder5: string = randomString(); + + const uidDeed1: string = randomString(); + const uidDeed2: string = randomString(); + const uidDeed3: string = randomString(); + const uidDeed4: string = randomString(); + const uidDeed5: string = randomString(); + + const uidDeedType1: string = randomString(); + const uidDeedType2: string = randomString(); + + const uidDocument1: string = randomString(); + const uidDocument2: string = randomString(); + const uidDocument3: string = randomString(); + const uidDocument4: string = randomString(); + const uidDocument5: string = randomString(); + + const uidDocumentType1: string = randomString(); + const uidDocumentType2: string = randomString(); + const uidDocumentType3: string = randomString(); + + const uidOfficeFolderHasCustomer1: string = randomString(); + const uidOfficeFolderHasCustomer2: string = randomString(); + + const uidFiles1: string = randomString(); + const uidFiles2: string = randomString(); + + const uidDeedHasDocumentType1: string = randomString(); + const uidDeedHasDocumentType2: string = randomString(); + + const uidDeedTypeHasDocumentType1: string = randomString(); + const uidDeedTypeHasDocumentType2: string = randomString(); + + const uidDocumentHistory1: string = randomString(); + const uidDocumentHistory2: string = randomString(); + + // const existingData = await prisma.contacts.findFirst({ where: { uid: uidContact4 } }); + // if (existingData) { + // console.log("Seed data already exists. Skipping seeding process."); + // return; + // } + + + const customers: Customers[] = [ + { + uid: uidCustomer1, + contact_uid: uidContact1, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer2, + contact_uid: uidContact2, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + ]; + + const addresses: Addresses[] = [ + { + uid: uidAddress1, + address: "123 Main St", + city: "Los Angeles", + zip_code: 90001, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress2, + address: "Rue Pierre Emillion", + city: "Paris", + zip_code: 75003, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress3, + address: "Rue Pierre Charles", + city: "Paris", + zip_code: 75003, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress4, + address: "Rue Pierre Pologne", + city: "Paris", + zip_code: 75003, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const contacts: Contacts[] = [ + { + uid: uidContact1, + address_uid: uidAddress1, + first_name: "John", + last_name: "Doe", + email: "john.doe@example.com", + phone_number: randomString(), + cell_phone_number: randomString(), + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact2, + address_uid: uidAddress2, + first_name: "Jane", + last_name: "Doe", + email: "jane.doe@example.com", + phone_number: randomString(), + cell_phone_number: randomString(), + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact3, + address_uid: uidAddress3, + first_name: "Maitre Marcelino", + last_name: "Jack", + email: "Marcelino.Jack@example.com", + phone_number: randomString(), + cell_phone_number: randomString(), + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact4, + address_uid: uidAddress4, + first_name: "Maitre Massi", + last_name: "Jack", + email: "Massi.Jack@example.com", + phone_number: randomString(), + cell_phone_number: randomString(), + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + ]; + + const offices: Offices[] = [ + { + uid: uidOffice1, + idNot: randomString(), + name: "LA Office", + crpcen: randomString(), + address_uid: uidAddress1, + created_at: new Date(), + updated_at: new Date(), + office_status: EOfficeStatus.ACTIVATED, + }, + { + uid: uidOffice2, + idNot: randomString(), + name: "NYC Office", + crpcen: randomString(), + address_uid: uidAddress2, + created_at: new Date(), + updated_at: new Date(), + office_status: EOfficeStatus.DESACTIVATED, + }, + ]; + + const users: Users[] = [ + { + uid: uidUser1, + created_at: new Date(), + updated_at: new Date(), + idNot: randomString(), + contact_uid: uidContact1, + office_uid: uidOffice1, + }, + { + uid: uidUser2, + created_at: new Date(), + updated_at: new Date(), + idNot: randomString(), + contact_uid: uidContact2, + office_uid: uidOffice2, + }, + ]; + + const officeFolders: OfficeFolders[] = [ + { + uid: uidOfficeFolder1, + folder_number: "0001", + name: "Dossier", + deed_uid: uidDeed1, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder2, + folder_number: "0002", + name: "Dossier", + deed_uid: uidDeed2, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice2, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder3, + folder_number: "0003", + name: "Dossier", + deed_uid: uidDeed3, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice2, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder4, + folder_number: "0004", + name: "Dossier", + deed_uid: uidDeed4, + status: EFolderStatus.ARCHIVED, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice2, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder5, + folder_number: "0005", + name: "Dossier", + deed_uid: uidDeed5, + status: EFolderStatus.ARCHIVED, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice2, + description: null, + archived_description: null, + }, + ]; + + const deeds: Deeds[] = [ + { + uid: uidDeed1, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed2, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed3, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed4, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed5, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const deedTypes: DeedTypes[] = [ + { + uid: uidDeedType1, + name: "Acte de mariage", + archived_at: null, + description: "Acte regroupant deux personnes en mariage", + office_uid: uidOffice1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedType2, + name: "Vente d'un bien immobilier", + archived_at: null, + description: "Permet de vendre un bien immobilier à une entité ou une personne physique", + office_uid: uidOffice2, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const documents: Documents[] = [ + { + uid: uidDocument1, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer1, + document_status: EDocumentStatus.DEPOSITED, + folder_uid: uidOfficeFolder1, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocument2, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer2, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder2, + document_type_uid: uidDocumentType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocument3, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer1, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder1, + document_type_uid: uidDocumentType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocument4, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer1, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder1, + document_type_uid: uidDocumentType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocument5, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer1, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder1, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const documentTypes: DocumentTypes[] = [ + { + uid: uidDocumentType1, + archived_at: null, + name: "Acte de naissance", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Acte de naissance est un document officiel qui atteste de la naissance d'une personne", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType2, + archived_at: null, + name: "Carte d'identité", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, demander un recto-verso au client", + public_description: "Carte d'identité est un document officiel qui atteste de l'identité d'une personne", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType3, + archived_at: null, + name: "Autres documents", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, demander un recto-verso au client", + public_description: "Carte d'identité est un document officiel qui atteste de l'identité d'une personne", + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const officeFolderHasCustomers: OfficeFolderHasCustomers[] = [ + { + uid: uidOfficeFolderHasCustomer1, + customer_uid: uidCustomer1, + office_folder_uid: uidOfficeFolder1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidOfficeFolderHasCustomer2, + customer_uid: uidCustomer2, + office_folder_uid: uidOfficeFolder2, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const files: Files[] = [ + { + uid: uidFiles1, + document_uid: uidDocument1, + file_name: "fileName1", + file_path: "https://www.google1.com", + key: '', + archived_at: null, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidFiles2, + document_uid: uidDocument1, + file_name: "fileName2", + file_path: "https://www.google2.com", + key: '', + archived_at: null, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const deedHasDocumentTypes: DeedHasDocumentTypes[] = [ + { + uid: uidDeedHasDocumentType1, + deed_uid: uidDeed1, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType2, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType2, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const deedTypeHasDocumentTypes: DeedTypeHasDocumentTypes[] = [ + { + uid: uidDeedTypeHasDocumentType1, + deed_type_uid: uidDeedType1, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedTypeHasDocumentType2, + deed_type_uid: uidDeedType2, + document_type_uid: uidDocumentType2, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const documentHistories: DocumentHistory[] = [ + { + uid: uidDocumentHistory1, + document_status: EDocumentStatus.ASKED, + document_uid: uidDocument1, + refused_reason: "", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentHistory2, + document_status: EDocumentStatus.DEPOSITED, + document_uid: uidDocument1, + refused_reason: "Le document n'est pas conforme", + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + for (const address of addresses) { + await prisma.addresses.create({ data: address }); + } + + for (const contact of contacts) { + await prisma.contacts.create({ data: contact }); + } + + for (const office of offices) { + await prisma.offices.create({ data: office }); + } + + for (const user of users) { + await prisma.users.create({ data: user }); + } + + for (const customer of customers) { + await prisma.customers.create({ data: customer }); + } + + for (const deedType of deedTypes) { + await prisma.deedTypes.create({ data: deedType }); + } + + for (const deed of deeds) { + await prisma.deeds.create({ data: deed }); + } + for (const officeFolder of officeFolders) { + await prisma.officeFolders.create({ data: officeFolder }); + } + + for (const documentType of documentTypes) { + await prisma.documentTypes.create({ data: documentType }); + } + + for (const document of documents) { + await prisma.documents.create({ data: document }); + } + + for (const file of files) { + await prisma.files.create({ data: file }); + } + + for (const documentHistory of documentHistories) { + await prisma.documentHistory.create({ data: documentHistory }); + } + + for (const officeFolderHasCustomer of officeFolderHasCustomers) { + await prisma.officeFolderHasCustomers.create({ data: officeFolderHasCustomer }); + } + + for (const deedHasDocumentType of deedHasDocumentTypes) { + await prisma.deedHasDocumentTypes.create({ data: deedHasDocumentType }); + } + + for (const deedTypeHasDocumentType of deedTypeHasDocumentTypes) { + await prisma.deedTypeHasDocumentTypes.create({ data: deedTypeHasDocumentType }); + } + + console.log(">MOCK DATA - Seeding completed!"); +})(); diff --git a/src/common/databases/seeders/seeder2.ts b/src/common/databases/seeders/seeder2.ts new file mode 100644 index 00000000..e0e6b892 --- /dev/null +++ b/src/common/databases/seeders/seeder2.ts @@ -0,0 +1,2088 @@ +import { + Addresses, + Contacts, + Customers, + DeedHasDocumentTypes, + DeedTypeHasDocumentTypes, + DeedTypes, + Deeds, + DocumentHistory, + DocumentTypes, + Documents, + EDocumentStatus, + EFolderStatus, + EOfficeStatus, + Files, + OfficeFolderHasCustomers, + OfficeFolders, + Offices, + Users, + ECivility, + ECustomerStatus, + PrismaClient, +} from "@prisma/client"; + +(async () => { + const prisma = new PrismaClient(); + + const existingData = await prisma.contacts.findFirst({ where: { email: "john.doe@example.com" } }); + if (existingData) { + console.log("Seed data already exists. Skipping seeding process."); + return; + } + + const randomString = () => { + const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + let result = ""; + for (let i = 10; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)]; + return result; + }; + const uidCustomer1: string = randomString(); + const uidCustomer2: string = randomString(); + const uidCustomer3: string = randomString(); + const uidCustomer4: string = randomString(); + const uidCustomer5: string = randomString(); + const uidCustomer6: string = randomString(); + const uidCustomer7: string = randomString(); + const uidCustomer8: string = randomString(); + const uidCustomer9: string = randomString(); + const uidCustomer10: string = randomString(); + const uidCustomer11: string = randomString(); + const uidCustomer12: string = randomString(); + const uidCustomer13: string = randomString(); + const uidCustomer14: string = randomString(); + const uidCustomer15: string = randomString(); + + const uidContact1: string = randomString(); + const uidContact2: string = randomString(); + const uidContact3: string = randomString(); + const uidContact4: string = randomString(); + const uidContact5: string = randomString(); + const uidContact6: string = randomString(); + const uidContact7: string = randomString(); + const uidContact8: string = randomString(); + const uidContact9: string = randomString(); + const uidContact10: string = randomString(); + const uidContact11: string = randomString(); + const uidContact12: string = randomString(); + const uidContact13: string = randomString(); + const uidContact14: string = randomString(); + const uidContact15: string = randomString(); + const uidContact16: string = randomString(); + const uidContact17: string = randomString(); + const uidContact18: string = randomString(); + const uidContact19: string = randomString(); + const uidContact20: string = randomString(); + + const uidAddress1: string = randomString(); + const uidAddress2: string = randomString(); + const uidAddress3: string = randomString(); + const uidAddress4: string = randomString(); + const uidAddress5: string = randomString(); + const uidAddress6: string = randomString(); + const uidAddress7: string = randomString(); + const uidAddress8: string = randomString(); + const uidAddress9: string = randomString(); + const uidAddress10: string = randomString(); + const uidAddress11: string = randomString(); + const uidAddress12: string = randomString(); + const uidAddress13: string = randomString(); + const uidAddress14: string = randomString(); + const uidAddress15: string = randomString(); + const uidAddress16: string = randomString(); + const uidAddress17: string = randomString(); + const uidAddress18: string = randomString(); + const uidAddress19: string = randomString(); + const uidAddress20: string = randomString(); + + const uidOffice1: string = randomString(); + + const uidUser1: string = randomString(); + const uidUser2: string = randomString(); + const uidUser3: string = randomString(); + const uidUser4: string = randomString(); + const uidUser5: string = randomString(); + + const uidOfficeFolder1: string = randomString(); + const uidOfficeFolder2: string = randomString(); + const uidOfficeFolder3: string = randomString(); + const uidOfficeFolder4: string = randomString(); + const uidOfficeFolder5: string = randomString(); + const uidOfficeFolder6: string = randomString(); + const uidOfficeFolder7: string = randomString(); + const uidOfficeFolder8: string = randomString(); + const uidOfficeFolder9: string = randomString(); + const uidOfficeFolder10: string = randomString(); + const uidOfficeFolder11: string = randomString(); + const uidOfficeFolder12: string = randomString(); + const uidOfficeFolder13: string = randomString(); + const uidOfficeFolder14: string = randomString(); + const uidOfficeFolder15: string = randomString(); + const uidOfficeFolder16: string = randomString(); + const uidOfficeFolder17: string = randomString(); + const uidOfficeFolder18: string = randomString(); + const uidOfficeFolder19: string = randomString(); + const uidOfficeFolder20: string = randomString(); + const uidOfficeFolder21: string = randomString(); + + const uidDeed1: string = randomString(); + const uidDeed2: string = randomString(); + const uidDeed3: string = randomString(); + const uidDeed4: string = randomString(); + const uidDeed5: string = randomString(); + const uidDeed6: string = randomString(); + const uidDeed7: string = randomString(); + const uidDeed8: string = randomString(); + const uidDeed9: string = randomString(); + const uidDeed10: string = randomString(); + const uidDeed11: string = randomString(); + const uidDeed12: string = randomString(); + const uidDeed13: string = randomString(); + const uidDeed14: string = randomString(); + const uidDeed15: string = randomString(); + const uidDeed16: string = randomString(); + const uidDeed17: string = randomString(); + const uidDeed18: string = randomString(); + const uidDeed19: string = randomString(); + const uidDeed20: string = randomString(); + const uidDeed21: string = randomString(); + + + const uidDeedType1: string = randomString(); + const uidDeedType2: string = randomString(); + const uidDeedType3: string = randomString(); + const uidDeedType4: string = randomString(); + + const uidDocument1: string = randomString(); + const uidDocument2: string = randomString(); + const uidDocument3: string = randomString(); + const uidDocument4: string = randomString(); + + const uidDocumentType1: string = randomString(); + const uidDocumentType2: string = randomString(); + const uidDocumentType3: string = randomString(); + const uidDocumentType4: string = randomString(); + const uidDocumentType5: string = randomString(); + const uidDocumentType6: string = randomString(); + const uidDocumentType7: string = randomString(); + const uidDocumentType8: string = randomString(); + const uidDocumentType9: string = randomString(); + const uidDocumentType10: string = randomString(); + const uidDocumentType11: string = randomString(); + const uidDocumentType12: string = randomString(); + const uidDocumentType13: string = randomString(); + const uidDocumentType14: string = randomString(); + const uidDocumentType15: string = randomString(); + const uidDocumentType16: string = randomString(); + const uidDocumentType17: string = randomString(); + const uidDocumentType18: string = randomString(); + + const uidOfficeFolderHasCustomer1: string = randomString(); + const uidOfficeFolderHasCustomer2: string = randomString(); + const uidOfficeFolderHasCustomer3: string = randomString(); + const uidOfficeFolderHasCustomer4: string = randomString(); + const uidOfficeFolderHasCustomer5: string = randomString(); + + + const uidFiles1: string = randomString(); + const uidFiles2: string = randomString(); + + const uidDeedHasDocumentType1: string = randomString(); + const uidDeedHasDocumentType2: string = randomString(); + const uidDeedHasDocumentType3: string = randomString(); + const uidDeedHasDocumentType4: string = randomString(); + const uidDeedHasDocumentType5: string = randomString(); + const uidDeedHasDocumentType6: string = randomString(); + const uidDeedHasDocumentType7: string = randomString(); + const uidDeedHasDocumentType8: string = randomString(); + const uidDeedHasDocumentType9: string = randomString(); + const uidDeedHasDocumentType10: string = randomString(); + const uidDeedHasDocumentType11: string = randomString(); + const uidDeedHasDocumentType12: string = randomString(); + const uidDeedHasDocumentType13: string = randomString(); + const uidDeedHasDocumentType14: string = randomString(); + const uidDeedHasDocumentType15: string = randomString(); + const uidDeedHasDocumentType16: string = randomString(); + const uidDeedHasDocumentType17: string = randomString(); + const uidDeedHasDocumentType18: string = randomString(); + const uidDeedHasDocumentType19: string = randomString(); + const uidDeedHasDocumentType20: string = randomString(); + const uidDeedHasDocumentType21: string = randomString(); + const uidDeedHasDocumentType22: string = randomString(); + const uidDeedHasDocumentType23: string = randomString(); + const uidDeedHasDocumentType24: string = randomString(); + const uidDeedHasDocumentType25: string = randomString(); + const uidDeedHasDocumentType26: string = randomString(); + const uidDeedHasDocumentType27: string = randomString(); + const uidDeedHasDocumentType28: string = randomString(); + const uidDeedHasDocumentType29: string = randomString(); + const uidDeedHasDocumentType30: string = randomString(); + const uidDeedHasDocumentType31: string = randomString(); + const uidDeedHasDocumentType32: string = randomString(); + const uidDeedHasDocumentType33: string = randomString(); + const uidDeedHasDocumentType34: string = randomString(); + const uidDeedHasDocumentType35: string = randomString(); + const uidDeedHasDocumentType36: string = randomString(); + const uidDeedHasDocumentType37: string = randomString(); + const uidDeedHasDocumentType38: string = randomString(); + const uidDeedHasDocumentType39: string = randomString(); + const uidDeedHasDocumentType40: string = randomString(); + const uidDeedHasDocumentType41: string = randomString(); + const uidDeedHasDocumentType42: string = randomString(); + const uidDeedHasDocumentType43: string = randomString(); + const uidDeedHasDocumentType44: string = randomString(); + const uidDeedHasDocumentType45: string = randomString(); + const uidDeedHasDocumentType46: string = randomString(); + const uidDeedHasDocumentType47: string = randomString(); + const uidDeedHasDocumentType48: string = randomString(); + const uidDeedHasDocumentType49: string = randomString(); + const uidDeedHasDocumentType50: string = randomString(); + const uidDeedHasDocumentType51: string = randomString(); + const uidDeedHasDocumentType52: string = randomString(); + const uidDeedHasDocumentType53: string = randomString(); + + + + const uidDeedTypeHasDocumentType1: string = randomString(); + const uidDeedTypeHasDocumentType2: string = randomString(); + const uidDeedTypeHasDocumentType3: string = randomString(); + const uidDeedTypeHasDocumentType4: string = randomString(); + const uidDeedTypeHasDocumentType5: string = randomString(); + const uidDeedTypeHasDocumentType6: string = randomString(); + const uidDeedTypeHasDocumentType7: string = randomString(); + const uidDeedTypeHasDocumentType8: string = randomString(); + + + + + const uidDocumentHistory1: string = randomString(); + const uidDocumentHistory2: string = randomString(); + + const customers: Customers[] = [ + { + uid: uidCustomer1, + contact_uid: uidContact1, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer2, + contact_uid: uidContact2, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer3, + contact_uid: uidContact3, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer4, + contact_uid: uidContact4, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer5, + contact_uid: uidContact5, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer6, + contact_uid: uidContact6, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer7, + contact_uid: uidContact7, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer8, + contact_uid: uidContact8, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer9, + contact_uid: uidContact9, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer10, + contact_uid: uidContact10, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer11, + contact_uid: uidContact11, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer12, + contact_uid: uidContact12, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer13, + contact_uid: uidContact13, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer14, + contact_uid: uidContact14, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + { + uid: uidCustomer15, + contact_uid: uidContact15, + created_at: new Date(), + updated_at: new Date(), + status: ECustomerStatus.PENDING, + }, + ]; + + const addresses: Addresses[] = [ + { + uid: uidAddress1, + address: "148 Avenue du bac", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress2, + address: "Rue Pierre Emillion", + city: "Pacé", + zip_code: 35740, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress3, + address: "Rue Pierre Charles", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress4, + address: "Rue Pierre Pologne", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress5, + address: "Rue Pierre Marcel", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress6, + address: "Rue Pierre Jacques", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress7, + address: "Rue Pierre Pascal", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress8, + address: "Rue Maxime Henry", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress9, + address: "Rue Maxime Francis", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress10, + address: "Avenue Paul Roger", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress11, + address: "Avenue Paul Franck", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress12, + address: "Avenue Paul Maréchal", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress13, + address: "Avenue Marcel Denis", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress14, + address: "Place Alexandre", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress15, + address: "Place Alexandre Jacques", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress16, + address: "Place Alexandre 2", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress17, + address: "Rue du livre", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress18, + address: "Place de la joie", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress19, + address: "Rue Paul Henry", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidAddress20, + address: "Rue Marcelin", + city: "Rennes", + zip_code: 35000, + created_at: new Date(), + updated_at: new Date(), + }, + + ]; + + const contacts: Contacts[] = [ + { + uid: uidContact1, + address_uid: uidAddress1, + first_name: "Manon", + last_name: "Simon", + email: "manon.simon@gmail.com", + phone_number: "06 12 34 56 78", + cell_phone_number: "06 12 34 56 78", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact2, + address_uid: uidAddress2, + first_name: "Kevin", + last_name: "Hautefaye", + email: "kevin.hautefaye@gmail.com", + phone_number: "06 23 45 67 89", + cell_phone_number: "06 23 45 67 89", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact3, + address_uid: uidAddress3, + first_name: "Maxime", + last_name: "Lalo", + email: "maxime.lalo@gmail.com", + phone_number: "06 34 56 78 90", + cell_phone_number: "06 34 56 78 90", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact4, + address_uid: uidAddress4, + first_name: "Vincent", + last_name: "Brognard", + email: "vincent.brognard@gmail.com", + phone_number: "06 45 67 89 01", + cell_phone_number: "06 45 67 89 01", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact5, + address_uid: uidAddress5, + first_name: "Maxime", + last_name: "Leroy", + email: "maxime.leroy@hotmail.fr", + phone_number: "06 56 78 90 12", + cell_phone_number: "06 56 78 90 12", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact6, + address_uid: uidAddress6, + first_name: "Thibault", + last_name: "Dubois", + email: "thibault.dubois@outlook.com", + phone_number: "06 67 89 01 23", + cell_phone_number: "06 67 89 01 23", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact7, + address_uid: uidAddress7, + first_name: "Léa", + last_name: "Fontaine", + email: "lea.fontaine@gmail.com", + phone_number: "06 78 90 12 34", + cell_phone_number: "06 78 90 12 34", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact8, + address_uid: uidAddress8, + first_name: "Guillaume", + last_name: "Renaud", + email: "guillaume.renaud@gmail.com", + phone_number: "06 89 01 23 45", + cell_phone_number: "06 89 01 23 45", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact9, + address_uid: uidAddress9, + first_name: "Lucie", + last_name: "Chevalier", + email: "lucie.chevalier@outlook.com", + phone_number: "07 12 34 56 78", + cell_phone_number: "07 12 34 56 78", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact10, + address_uid: uidAddress10, + first_name: "Sébastien", + last_name: "Dubois", + email: "sebastien.dubois@gmail.com", + phone_number: "07 23 45 67 89", + cell_phone_number: "07 23 45 67 89", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact11, + address_uid: uidAddress11, + first_name: "Mathilde", + last_name: "Durand", + email: "mathilde.durand@gmail.com", + phone_number: "07 34 56 78 90", + cell_phone_number: "07 34 56 78 90", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact12, + address_uid: uidAddress12, + first_name: "Antoine", + last_name: "Bernard", + email: "antoine.bernard@outlook.com", + phone_number: "07 45 67 89 01", + cell_phone_number: "07 45 67 89 01", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact13, + address_uid: uidAddress13, + first_name: "Camille", + last_name: "Laurent", + email: "camille.laurent@gmail.com", + phone_number: "07 56 78 90 12", + cell_phone_number: "07 56 78 90 12", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact14, + address_uid: uidAddress14, + first_name: "Julien", + last_name: "Mercier", + email: "julien.mercier@hotmail.fr", + phone_number: "07 67 89 01 23", + cell_phone_number: "07 67 89 01 23", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact15, + address_uid: uidAddress15, + first_name: "Charlotte", + last_name: "Lefebvre", + email: "charlotte.lefebvre@gmail.com", + phone_number: "07 78 90 12 34", + cell_phone_number: "07 78 90 12 34", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact16, + address_uid: uidAddress16, + first_name: "Caroline", + last_name: "Pallut", + email: "caroline.pallut@gmail.com", + phone_number: "07 89 01 23 45", + cell_phone_number: "07 89 01 23 45", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact17, + address_uid: uidAddress17, + first_name: "Nadège", + last_name: "Gauchet", + email: "nedege.gauchet@outlook.com", + phone_number: "06 11 22 33 44", + cell_phone_number: "06 11 22 33 44", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact18, + address_uid: uidAddress18, + first_name: "Matthieu", + last_name: "Bougeard", + email: "matthieu.bougeard@gmail.com", + phone_number: "07 22 33 44 55", + cell_phone_number: "07 22 33 44 55", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + { + uid: uidContact19, + address_uid: uidAddress19, + first_name: "Cécile", + last_name: "Celton", + email: "cecile.celton@outlook.com", + phone_number: "06 55 66 77 88", + cell_phone_number: "06 55 66 77 88", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.FEMALE, + }, + { + uid: uidContact20, + address_uid: uidAddress20, + first_name: "Gwendal", + last_name: "Texier", + email: "gwendal.texier@gmail.com", + phone_number: "07 88 99 00 11", + cell_phone_number: "07 88 99 00 11", + birthdate: null, + created_at: new Date(), + updated_at: new Date(), + civility: ECivility.MALE, + }, + ]; + + const offices: Offices[] = [ + { + uid: uidOffice1, + idNot: randomString(), + name: "Office Rennes", + crpcen: randomString(), + address_uid: uidAddress1, + created_at: new Date(), + updated_at: new Date(), + office_status: EOfficeStatus.ACTIVATED, + } + ]; + + const users: Users[] = [ + { + uid: uidUser1, + created_at: new Date(), + updated_at: new Date(), + idNot: randomString(), + contact_uid: uidContact16, + office_uid: uidOffice1, + }, + { + uid: uidUser2, + created_at: new Date(), + updated_at: new Date(), + idNot: randomString(), + contact_uid: uidContact17, + office_uid: uidOffice1, + }, + { + uid: uidUser3, + created_at: new Date(), + updated_at: new Date(), + idNot: randomString(), + contact_uid: uidContact18, + office_uid: uidOffice1, + }, + { + uid: uidUser4, + created_at: new Date(), + updated_at: new Date(), + idNot: randomString(), + contact_uid: uidContact19, + office_uid: uidOffice1, + }, + { + uid: uidUser5, + created_at: new Date(), + updated_at: new Date(), + idNot: randomString(), + contact_uid: uidContact20, + office_uid: uidOffice1, + }, + ]; + + const officeFolders: OfficeFolders[] = [ + { + uid: uidOfficeFolder1, + folder_number: "0001", + name: "Dossier", + deed_uid: uidDeed1, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder2, + folder_number: "0002", + name: "Dossier", + deed_uid: uidDeed2, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder3, + folder_number: "0003", + name: "Dossier", + deed_uid: uidDeed3, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder4, + folder_number: "0004", + name: "Dossier", + deed_uid: uidDeed4, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder5, + folder_number: "0005", + name: "Dossier", + deed_uid: uidDeed5, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder6, + folder_number: "0006", + name: "Dossier", + deed_uid: uidDeed6, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder7, + folder_number: "0007", + name: "Dossier", + deed_uid: uidDeed7, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder8, + folder_number: "0008", + name: "Dossier", + deed_uid: uidDeed8, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder9, + folder_number: "0009", + name: "Dossier", + deed_uid: uidDeed9, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder10, + folder_number: "00010", + name: "Dossier", + deed_uid: uidDeed10, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder11, + folder_number: "00011", + name: "Dossier", + deed_uid: uidDeed11, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder12, + folder_number: "00012", + name: "Dossier", + deed_uid: uidDeed12, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder13, + folder_number: "00013", + name: "Dossier", + deed_uid: uidDeed13, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder14, + folder_number: "00014", + name: "Dossier", + deed_uid: uidDeed14, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder15, + folder_number: "00015", + name: "Dossier", + deed_uid: uidDeed15, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder16, + folder_number: "00016", + name: "Dossier", + deed_uid: uidDeed16, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder17, + folder_number: "00017", + name: "Dossier", + deed_uid: uidDeed17, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder18, + folder_number: "00018", + name: "Dossier", + deed_uid: uidDeed18, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder19, + folder_number: "00019", + name: "Dossier", + deed_uid: uidDeed19, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder20, + folder_number: "00020", + name: "Dossier", + deed_uid: uidDeed20, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + { + uid: uidOfficeFolder21, + folder_number: "00021", + name: "Dossier", + deed_uid: uidDeed21, + status: EFolderStatus.LIVE, + created_at: new Date(), + updated_at: new Date(), + office_uid: uidOffice1, + description: null, + archived_description: null, + }, + ]; + + const deeds: Deeds[] = [ + { + uid: uidDeed1, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed2, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed3, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed4, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed5, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed6, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed7, + deed_type_uid: uidDeedType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed8, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed9, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed10, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed11, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed12, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed13, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed14, + deed_type_uid: uidDeedType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed15, + deed_type_uid: uidDeedType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed16, + deed_type_uid: uidDeedType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed17, + deed_type_uid: uidDeedType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed18, + deed_type_uid: uidDeedType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed19, + deed_type_uid: uidDeedType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed20, + deed_type_uid: uidDeedType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeed21, + deed_type_uid: uidDeedType3, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const deedTypes: DeedTypes[] = [ + { + uid: uidDeedType1, + name: "Acte de donation", + archived_at: null, + description: "Acte de donation", + office_uid: uidOffice1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedType2, + name: "Acte de vente", + archived_at: null, + description: "Acte de vente", + office_uid: uidOffice1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedType3, + name: "Acte de succession", + archived_at: null, + description: "Acte de succession", + office_uid: uidOffice1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedType4, + name: "Acte de vente de maison individuelle", + archived_at: null, + description: "Acte de vente de maison individuelle", + office_uid: uidOffice1, + created_at: new Date(), + updated_at: new Date(), + }, + + ]; + + const documents: Documents[] = [ + { + uid: uidDocument1, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer1, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder1, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocument2, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer2, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder2, + document_type_uid: uidDocumentType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocument3, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer3, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder3, + document_type_uid: uidDocumentType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocument4, + blockchain_anchor_uid: null, + depositor_uid: uidCustomer4, + document_status: EDocumentStatus.ASKED, + folder_uid: uidOfficeFolder4, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const documentTypes: DocumentTypes[] = [ + { + uid: uidDocumentType1, + archived_at: null, + name: "Document d'identité", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, demander un recto-verso au client", + public_description: "Document officiel d'identification utilisé par plusieurs personnes pour prouver leur identité et leur nationalité (CNI, passeport)", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType2, + archived_at: null, + name: "Taxe Foncière", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Impôt annuel imposé sur les propriétés foncières et utilisé pour financer les services publics locaux.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType3, + archived_at: null, + name: "Contrat Mariage", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Accord légal qui établit les droits et les obligations entre deux personnes s'unissant en mariage.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType4, + archived_at: null, + name: "Livret de famille", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document officiel qui enregistre les détails et les événements familiaux tels que les mariages, les naissances et les décès d'un couple et de leurs enfants.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType16, + archived_at: null, + name: "Bail commercial", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Contrat légal entre un propriétaire et un locataire pour la location d'un bien immobilier utilisé à des fins commerciales ou professionnelles.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType5, + archived_at: null, + name: "Statuts SCI", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document légal qui définit les règles et les dispositions régissant la Société Civile Immobilière (SCI).", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType6, + archived_at: null, + name: "Avis de taxe foncière", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Notification officielle indiquant le montant de l'impôt foncier dû sur une propriété.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType7, + archived_at: null, + name: "Appel de charge de copropriété", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document envoyé aux copropriétaires pour les informer des dépenses et des charges communes liées à la gestion et à l'entretien de l'immeuble.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType8, + archived_at: null, + name: "PVAG", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Compte rendu écrit des discussions, décisions et résolutions prises lors d'une réunion d'assemblée générale de copropriété.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType9, + archived_at: null, + name: "Règlement de copropriété", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document juridique qui établit les règles et les droits des copropriétaires d'un immeuble en copropriété.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType10, + archived_at: null, + name: "Titre de propriété", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document légal qui atteste de la propriété d'un bien immobilier et en identifie le propriétaire.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType11, + archived_at: null, + name: "Plan et loi carrez", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document officiel qui mesure la superficie d'un lot ou d'un bien immobilier, conformément à la loi Carrez qui encadre les transactions immobilières.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType12, + archived_at: null, + name: "CNI", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document officiel d'identification délivré par l'État pour prouver l'identité et la nationalité d'une personne.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType13, + archived_at: null, + name: "Modifications règlement copropriété (plusieurs)", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Documents légaux qui apportent des changements ou des ajustements aux règles et dispositions du règlement de copropriété initial.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType14, + archived_at: null, + name: "Avis de décès", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Notification officielle délivrée par les autorités compétentes pour informer du décès d'une personne.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType15, + archived_at: null, + name: "Lettre de mission", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Document contractuel qui définit les termes et les objectifs d'une mission confiée à une personne ou à une entreprise.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType17, + archived_at: null, + name: "DPE", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "Diagnostic de Performance Energétique.", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentType18, + archived_at: null, + name: "RIB", + office_uid: uidOffice1, + private_description: "Ce document est confidentiel, et ne doit pas être divulgué", + public_description: "RIB.", + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const officeFolderHasCustomers: OfficeFolderHasCustomers[] = [ + { + uid: uidOfficeFolderHasCustomer1, + customer_uid: uidCustomer1, + office_folder_uid: uidOfficeFolder1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidOfficeFolderHasCustomer2, + customer_uid: uidCustomer2, + office_folder_uid: uidOfficeFolder2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidOfficeFolderHasCustomer3, + customer_uid: uidCustomer3, + office_folder_uid: uidOfficeFolder3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidOfficeFolderHasCustomer4, + customer_uid: uidCustomer4, + office_folder_uid: uidOfficeFolder4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidOfficeFolderHasCustomer5, + customer_uid: uidCustomer2, + office_folder_uid: uidOfficeFolder21, + created_at: new Date(), + updated_at: new Date(), + }, + + ]; + + const files: Files[] = [ + { + uid: uidFiles1, + document_uid: uidDocument1, + file_name: "fileName1", + file_path: "https://www.google1.com", + key: '', + archived_at: null, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidFiles2, + document_uid: uidDocument2, + file_name: "fileName1", + file_path: "https://www.google2.com", + key: '', + archived_at: null, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const deedHasDocumentTypes: DeedHasDocumentTypes[] = [ + { + uid: uidDeedHasDocumentType1, + deed_uid: uidDeed1, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType2, + deed_uid: uidDeed1, + document_type_uid: uidDocumentType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType3, + deed_uid: uidDeed1, + document_type_uid: uidDocumentType3, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType4, + deed_uid: uidDeed1, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType5, + deed_uid: uidDeed1, + document_type_uid: uidDocumentType16, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType6, + deed_uid: uidDeed1, + document_type_uid: uidDocumentType5, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType7, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType6, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType8, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType7, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType9, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType8, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType10, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType9, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType11, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType12, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType11, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType13, + deed_uid: uidDeed2, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType19, + deed_uid: uidDeed3, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType20, + deed_uid: uidDeed3, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType21, + deed_uid: uidDeed3, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType22, + deed_uid: uidDeed3, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType23, + deed_uid: uidDeed3, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType14, + deed_uid: uidDeed4, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType15, + deed_uid: uidDeed4, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType26, + deed_uid: uidDeed4, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType27, + deed_uid: uidDeed4, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType28, + deed_uid: uidDeed4, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType29, + deed_uid: uidDeed5, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType30, + deed_uid: uidDeed5, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType31, + deed_uid: uidDeed5, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType32, + deed_uid: uidDeed5, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType33, + deed_uid: uidDeed5, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType34, + deed_uid: uidDeed6, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType35, + deed_uid: uidDeed6, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType36, + deed_uid: uidDeed6, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType37, + deed_uid: uidDeed6, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType38, + deed_uid: uidDeed6, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType39, + deed_uid: uidDeed7, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType40, + deed_uid: uidDeed7, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType41, + deed_uid: uidDeed7, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType42, + deed_uid: uidDeed7, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType43, + deed_uid: uidDeed7, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType44, + deed_uid: uidDeed8, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType45, + deed_uid: uidDeed8, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType46, + deed_uid: uidDeed8, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType47, + deed_uid: uidDeed8, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType48, + deed_uid: uidDeed8, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType49, + deed_uid: uidDeed9, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType50, + deed_uid: uidDeed9, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType51, + deed_uid: uidDeed9, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType16, + deed_uid: uidDeed9, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType17, + deed_uid: uidDeed9, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedHasDocumentType18, + deed_uid: uidDeed10, + document_type_uid: uidDocumentType14, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType24, + deed_uid: uidDeed10, + document_type_uid: uidDocumentType15, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType25, + deed_uid: uidDeed10, + document_type_uid: uidDocumentType4, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType52, + deed_uid: uidDeed10, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedHasDocumentType53, + deed_uid: uidDeed10, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + + + ]; + + const deedTypeHasDocumentTypes: DeedTypeHasDocumentTypes[] = [ + { + uid: uidDeedTypeHasDocumentType1, + deed_type_uid: uidDeedType1, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedTypeHasDocumentType2, + deed_type_uid: uidDeedType2, + document_type_uid: uidDocumentType2, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedTypeHasDocumentType3, + deed_type_uid: uidDeedType3, + document_type_uid: uidDocumentType3, + created_at: new Date(), + updated_at: new Date(), + }, + + { + uid: uidDeedTypeHasDocumentType4, + deed_type_uid: uidDeedType4, + document_type_uid: uidDocumentType1, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedTypeHasDocumentType5, + deed_type_uid: uidDeedType4, + document_type_uid: uidDocumentType6, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedTypeHasDocumentType6, + deed_type_uid: uidDeedType4, + document_type_uid: uidDocumentType10, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedTypeHasDocumentType7, + deed_type_uid: uidDeedType4, + document_type_uid: uidDocumentType17, + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDeedTypeHasDocumentType8, + deed_type_uid: uidDeedType4, + document_type_uid: uidDocumentType18, + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + const documentHistories: DocumentHistory[] = [ + { + uid: uidDocumentHistory1, + document_status: EDocumentStatus.ASKED, + document_uid: uidDocument1, + refused_reason: "", + created_at: new Date(), + updated_at: new Date(), + }, + { + uid: uidDocumentHistory2, + document_status: EDocumentStatus.DEPOSITED, + document_uid: uidDocument1, + refused_reason: "Le document n'est pas conforme", + created_at: new Date(), + updated_at: new Date(), + }, + ]; + + for (const address of addresses) { + await prisma.addresses.create({ data: address }); + } + + for (const contact of contacts) { + await prisma.contacts.create({ data: contact }); + } + + for (const office of offices) { + await prisma.offices.create({ data: office }); + } + + for (const user of users) { + await prisma.users.create({ data: user }); + } + + for (const customer of customers) { + await prisma.customers.create({ data: customer }); + } + + for (const deedType of deedTypes) { + await prisma.deedTypes.create({ data: deedType }); + } + + for (const deed of deeds) { + await prisma.deeds.create({ data: deed }); + } + for (const officeFolder of officeFolders) { + await prisma.officeFolders.create({ data: officeFolder }); + } + + for (const documentType of documentTypes) { + await prisma.documentTypes.create({ data: documentType }); + } + + for (const document of documents) { + await prisma.documents.create({ data: document }); + } + + for (const file of files) { + await prisma.files.create({ data: file }); + } + + for (const documentHistory of documentHistories) { + await prisma.documentHistory.create({ data: documentHistory }); + } + + for (const officeFolderHasCustomer of officeFolderHasCustomers) { + await prisma.officeFolderHasCustomers.create({ data: officeFolderHasCustomer }); + } + + for (const deedHasDocumentType of deedHasDocumentTypes) { + await prisma.deedHasDocumentTypes.create({ data: deedHasDocumentType }); + } + + for (const deedTypeHasDocumentType of deedTypeHasDocumentTypes) { + await prisma.deedTypeHasDocumentTypes.create({ data: deedTypeHasDocumentType }); + } + + console.log(">MOCK DATA - Seeding completed!"); +})(); diff --git a/src/common/helpers/ObjectHydrate.ts b/src/common/helpers/ObjectHydrate.ts index 5e220bd0..92cb3194 100644 --- a/src/common/helpers/ObjectHydrate.ts +++ b/src/common/helpers/ObjectHydrate.ts @@ -1,13 +1,23 @@ -import { type ClassTransformOptions, plainToClass, plainToClassFromExist } from "class-transformer"; - -export default abstract class ObjectHydrate { - public static hydrate(object: T, from: Partial, options?: ClassTransformOptions): T { - return plainToClassFromExist(object, from, options); - } - - public static map(ClassEntity: { new (): T }, fromArray: Partial[], options?: ClassTransformOptions): T[] { - return fromArray.map((from) => { - return plainToClass(ClassEntity, from, options); - }); - } -} +import { type ClassTransformOptions, plainToClassFromExist, plainToInstance } from "class-transformer"; + +export default abstract class ObjectHydrate { + public static hydrate(object: T, from: Partial, options?: ClassTransformOptions): T { + return plainToClassFromExist(object, from, options); + } + + public static map(ClassEntity: { new (): T }, fromArray: Partial[], options?: ClassTransformOptions): T[] { + return fromArray.map((from) => { + return plainToInstance(ClassEntity, from, options); + }); + } + + // public static fromTypeToRessource(ClassEntity: { new (): T }, from: Record): T { + // const properties = Object.getOwnPropertyNames(ClassEntity); + // const classInstance = new ClassEntity() as T; + // properties.forEach((property) => { + // if (property in from) { + // classInstance[property] = from[property] as T[keyof T]; + // } + // }); + // } +} diff --git a/src/common/repositories/AddressesRepository.ts b/src/common/repositories/AddressesRepository.ts new file mode 100644 index 00000000..7bd53e84 --- /dev/null +++ b/src/common/repositories/AddressesRepository.ts @@ -0,0 +1,42 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Addresses } from "@prisma/client"; + +@Service() +export default class AddressesRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().addresses; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many addresses + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Find one address + */ + public async findOneByUid(uid: string): Promise { + const addressEntity = await this.model.findUnique({ + where: { + uid: uid, + }, + }); + + if (!addressEntity) { + throw new Error("Address not found"); + } + + return addressEntity; + } +} diff --git a/src/common/repositories/ContactsRepository.ts b/src/common/repositories/ContactsRepository.ts new file mode 100644 index 00000000..b302d1f6 --- /dev/null +++ b/src/common/repositories/ContactsRepository.ts @@ -0,0 +1,42 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Contacts } from "@prisma/client"; + +@Service() +export default class ContactsRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().contacts; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many contacts + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Find unique contact + */ + public async findOneByUid(uid: string): Promise { + const contactEntity = await this.model.findUnique({ + where: { + uid: uid, + }, + }); + + if (!contactEntity) { + throw new Error("contact not found"); + } + + return contactEntity; + } +} diff --git a/src/common/repositories/CustomersRepository.ts b/src/common/repositories/CustomersRepository.ts new file mode 100644 index 00000000..4f846795 --- /dev/null +++ b/src/common/repositories/CustomersRepository.ts @@ -0,0 +1,117 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Contacts, Customers, ECivility, ECustomerStatus, Prisma } from "@prisma/client"; +import { Customer } from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class CustomersRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().customers; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many customers + */ + public async findMany(query: Prisma.CustomersFindManyArgs): Promise< + (Customers & { + contact: Contacts; + })[] + > { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + if (!query.include) return this.model.findMany({ ...query, include: { contact: true } }); + return this.model.findMany({ ...query, include: { contact: { include: { address: true } } } }); + } + + /** + * @description : Create a customer + */ + public async create(customer: Customer): Promise { + const createArgs: Prisma.CustomersCreateArgs = { + data: { + status: ECustomerStatus.PENDING, + contact: { + create: { + first_name: customer.contact!.first_name, + last_name: customer.contact!.last_name, + email: customer.contact!.email, + phone_number: customer.contact!.phone_number, + cell_phone_number: customer.contact!.cell_phone_number, + civility: ECivility[customer.contact!.civility as keyof typeof ECivility], + address: {}, + }, + }, + }, + }; + + if (customer.contact!.address) { + createArgs.data.contact!.create!.address = { + create: { + address: customer.contact!.address!.address, + zip_code: customer.contact!.address!.zip_code, + city: customer.contact!.address!.city, + }, + }; + } + return this.model.create({ ...createArgs, include: { contact: true } }); + } + + /** + * @description : Update data from a customer + */ + public async update(uid: string, customer: Customer): Promise { + const updateArgs: Prisma.CustomersUpdateArgs = { + where: { + uid: uid, + }, + data: { + status: ECustomerStatus[customer.status as keyof typeof ECustomerStatus], + contact: { + update: { + first_name: customer.contact!.first_name, + last_name: customer.contact!.last_name, + email: customer.contact!.email, + phone_number: customer.contact!.phone_number, + cell_phone_number: customer.contact!.cell_phone_number, + civility: ECivility[customer.contact!.civility as keyof typeof ECivility], + address: {}, + }, + }, + }, + }; + if (customer.contact!.address) { + updateArgs.data.contact!.update!.address!.update = { + address: customer.contact!.address!.address, + zip_code: customer.contact!.address!.zip_code, + city: customer.contact!.address!.city, + }; + } + return this.model.update({ ...updateArgs, include: { contact: true } }); + } + + /** + * @description : Find unique customer + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.CustomersFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const customerEntity = await this.model.findUnique(findOneArgs); + if (!customerEntity) { + throw new Error("Customer not found"); + } + + return customerEntity; + } +} diff --git a/src/common/repositories/DeedTypesHasDocumentTypesRepository.ts b/src/common/repositories/DeedTypesHasDocumentTypesRepository.ts new file mode 100644 index 00000000..53cb40a7 --- /dev/null +++ b/src/common/repositories/DeedTypesHasDocumentTypesRepository.ts @@ -0,0 +1,42 @@ +import Database from "@Common/databases/database"; +import { DeedTypeHasDocumentTypes } from "@prisma/client"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; + +@Service() +export default class DeedTypeHasDocumentTypesRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().deedTypeHasDocumentTypes; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many relations between deed type and a document type + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Find unique relation between deed type and a document type + */ + public async findOneByUid(uid: string): Promise { + const deedTypeHasDoculmentTypesEntity = await this.model.findUnique({ + where: { + uid: uid, + }, + }); + + if (!deedTypeHasDoculmentTypesEntity) { + throw new Error("deed type not found"); + } + + return deedTypeHasDoculmentTypesEntity; + } +} diff --git a/src/common/repositories/DeedTypesRepository.ts b/src/common/repositories/DeedTypesRepository.ts new file mode 100644 index 00000000..6f38421d --- /dev/null +++ b/src/common/repositories/DeedTypesRepository.ts @@ -0,0 +1,111 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { DeedTypes, Prisma } from "@prisma/client"; +import { DeedType } from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class DeedTypesRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().deedTypes; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many deed types + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Create new deed type + */ + public async create(deedType: DeedType): Promise { + const createArgs: Prisma.DeedTypesCreateArgs = { + data: { + name: deedType.name, + description: deedType.description, + office: { + connect: { + uid: deedType.office!.uid, + }, + }, + }, + }; + if (deedType.deed_type_has_document_types) { + createArgs.data.deed_type_has_document_types = { + createMany: { + data: deedType.deed_type_has_document_types.map((relation) => ({ + document_type_uid: relation.document_type.uid!, + })), + skipDuplicates: true, + }, + }; + } + return this.model.create(createArgs); + } + + /** + * @description : Update data of a deed type + */ + public async update(uid: string, deedType: DeedType): Promise { + const updateArgs: Prisma.DeedTypesUpdateArgs = { + where: { + uid: uid, + }, + data: { + name: deedType.name, + description: deedType.description, + archived_at: deedType.archived_at, + office: { + connect: { + uid: deedType.office!.uid, + }, + }, + }, + include: { + deed_type_has_document_types: true, + }, + }; + if (deedType.deed_type_has_document_types) { + updateArgs.data.deed_type_has_document_types = { + deleteMany: { deed_type_uid: uid }, + createMany: { + data: deedType.deed_type_has_document_types.map((relation) => ({ + document_type_uid: relation.document_type.uid!, + })), + skipDuplicates: true, + }, + }; + } + return this.model.update(updateArgs); + } + + /** + * @description : Find unique deed type + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.DeedTypesFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const deedTypeEntity = await this.model.findUnique(findOneArgs); + + if (!deedTypeEntity) { + throw new Error("deed type not found"); + } + + return deedTypeEntity; + } +} diff --git a/src/common/repositories/DeedsHasDocumentTypesRepository.ts b/src/common/repositories/DeedsHasDocumentTypesRepository.ts new file mode 100644 index 00000000..65bac2c0 --- /dev/null +++ b/src/common/repositories/DeedsHasDocumentTypesRepository.ts @@ -0,0 +1,42 @@ +import Database from "@Common/databases/database"; +import { DeedHasDocumentTypes } from "@prisma/client"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; + +@Service() +export default class DeedHasDocumentTypesRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().deedHasDocumentTypes; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many deeds + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Find unique relation between deed and a document type + */ + public async findOneByUid(uid: string): Promise { + const deedHasDocumentTypesEntity = await this.model.findUnique({ + where: { + uid: uid, + }, + }); + + if (!deedHasDocumentTypesEntity) { + throw new Error("relation between deed and document type not found"); + } + + return deedHasDocumentTypesEntity; + } +} diff --git a/src/common/repositories/DeedsRepository.ts b/src/common/repositories/DeedsRepository.ts new file mode 100644 index 00000000..945a181d --- /dev/null +++ b/src/common/repositories/DeedsRepository.ts @@ -0,0 +1,110 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Deeds, Prisma } from "@prisma/client"; +import { Deed } from "le-coffre-resources/dist/Notary"; + +@Service() +export default class DeedsRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().deeds; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many users + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Create a deed based on a deed type + */ + public async create(deed: Deed): Promise { + const createArgs: Prisma.DeedsCreateArgs = { + data: { + deed_type: { + connect: { + uid: deed.deed_type!.uid, + }, + }, + }, + }; + const deedTypeWithDocumentTypes = await this.instanceDb.deedTypes.findUniqueOrThrow({ + where: { + uid: deed.deed_type!.uid, + }, + include: { deed_type_has_document_types: true }, + }); + + if (deedTypeWithDocumentTypes.archived_at) throw new Error("deed type is archived"); + + if (deedTypeWithDocumentTypes.deed_type_has_document_types) { + createArgs.data.deed_has_document_types = { + createMany: { + data: deedTypeWithDocumentTypes.deed_type_has_document_types.map((relation) => ({ + document_type_uid: relation.document_type_uid, + })), + skipDuplicates: true, + }, + }; + } + return this.model.create(createArgs); + } + + /** + * @description : Update data of a deed type + */ + public async update(uid: string, deed: Deed): Promise { + const updateArgs: Prisma.DeedsUpdateArgs = { + where: { + uid: uid, + }, + data: {}, + include: { + deed_has_document_types: true, + }, + }; + + if (deed.deed_has_document_types) { + updateArgs.data.deed_has_document_types = { + deleteMany: { deed_uid: uid }, + createMany: { + data: deed.deed_has_document_types.map((relation) => ({ + document_type_uid: relation.document_type.uid!, + })), + skipDuplicates: true, + }, + }; + } + return this.model.update(updateArgs); + } + + /** + * @description : Find unique deed + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.DeedsFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const deedTypeEntity = await this.model.findUnique(findOneArgs); + + if (!deedTypeEntity) { + throw new Error("deed not found"); + } + + return deedTypeEntity; + } +} diff --git a/src/common/repositories/DocumentTypesRepository.ts b/src/common/repositories/DocumentTypesRepository.ts new file mode 100644 index 00000000..e9cb3fef --- /dev/null +++ b/src/common/repositories/DocumentTypesRepository.ts @@ -0,0 +1,87 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { DocumentTypes, Prisma } from "prisma/prisma-client"; +import { DocumentType } from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class DocumentTypesRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().documentTypes; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many document types + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Create a document type + */ + public async create(documentType: DocumentType): Promise { + return this.model.create({ + data: { + name: documentType.name, + public_description: documentType.public_description, + private_description: documentType.private_description, + office: { + connect: { + uid: documentType.office!.uid, + }, + }, + }, + }); + } + + /** + * @description : update given document type + */ + public async update(uid: string, documentType: DocumentType): Promise { + return this.model.update({ + where: { + uid: uid, + }, + data: { + name: documentType.name, + public_description: documentType.public_description, + private_description: documentType.private_description, + archived_at: documentType.archived_at, + office: { + connect: { + uid: documentType.office!.uid, + }, + }, + }, + }); + } + + /** + * @description : find unique document type + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.DocumentTypesFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const documentTypeEntity = await this.model.findUnique(findOneArgs); + + if (!documentTypeEntity) { + throw new Error("Document Type not found"); + } + + return documentTypeEntity; + } +} diff --git a/src/common/repositories/DocumentsRepository.ts b/src/common/repositories/DocumentsRepository.ts new file mode 100644 index 00000000..1e1aa340 --- /dev/null +++ b/src/common/repositories/DocumentsRepository.ts @@ -0,0 +1,128 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Documents, EDocumentStatus, Prisma } from "@prisma/client"; +import { Document } from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class DocumentsRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().documents; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many documents + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Create a document + */ + public async create(document: Document): Promise { + const documentCreated = await this.model.create({ + data: { + folder: { + connect: { + uid: document.folder!.uid, + }, + }, + depositor: { + connect: { + uid: document.depositor!.uid, + }, + }, + document_type: { + connect: { + uid: document.document_type!.uid, + }, + }, + }, + }); + + await this.instanceDb.documentHistory.create({ + data: { + document: { + connect: { + uid: documentCreated.uid, + }, + }, + }, + }); + + return documentCreated; + } + + /** + * @description : Create many documents linked to an office folder + */ + public async createMany(documents: Document[]): Promise { + return this.model.createMany({ + data: documents.map((document) => ({ + folder_uid: document.folder!.uid!, + depositor_uid: document.depositor!.uid!, + document_type_uid: document.document_type!.uid!, + })), + skipDuplicates: true, + }); + } + + /** + * @description : Update data of a document + */ + public async update(uid: string, document: Document, refusedReason?: string): Promise { + return this.model.update({ + where: { + uid: uid, + }, + data: { + document_status: EDocumentStatus[document.document_status as keyof typeof EDocumentStatus], + document_history: { + create: { + document_status: EDocumentStatus[document.document_status as keyof typeof EDocumentStatus], + refused_reason: refusedReason, + }, + } + }, + }); + } + + /** + * @description : Delete a document + */ + public async delete(uid: string): Promise { + return this.model.delete({ + where: { + uid: uid, + }, + }); + } + + /** + * @description : Find unique document + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.DocumentsFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const documentEntity = await this.model.findUnique(findOneArgs); + if (!documentEntity) { + throw new Error("Document not found"); + } + + return documentEntity; + } +} diff --git a/src/common/repositories/FilesRepository.ts b/src/common/repositories/FilesRepository.ts new file mode 100644 index 00000000..34f2f89c --- /dev/null +++ b/src/common/repositories/FilesRepository.ts @@ -0,0 +1,91 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Files } from "@prisma/client"; +import { File } from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class FilesRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().files; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many files + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Create a file linked to a document + */ + public async create(file: File, key: string): Promise { + return this.model.create({ + data: { + document: { + connect: { + uid: file.document!.uid, + }, + }, + file_name: file.file_name, + file_path: file.file_path, + key: key + }, + include: { document: true } + }); + } + + /** + * @description : Update data of a file + */ + public async update(uid: string, file: File): Promise { + return this.model.update({ + where: { + uid: uid, + }, + data: { + file_path: file.file_path, + }, + }); + } + + /** + * @description : Delete a file + */ + public async delete(uid: string): Promise { + return this.model.update({ + where: { + uid: uid, + }, + data: { + key: null, + archived_at: new Date(Date.now()) + } + }); + } + + /** + * @description : Find unique file + */ + public async findOneByUid(uid: string): Promise { + const fileEntity = await this.model.findUnique({ + where: { + uid: uid, + }, + }); + + if (!fileEntity) { + throw new Error("File not found"); + } + + return fileEntity; + } +} diff --git a/src/common/repositories/OfficeFoldersHasCustomerRepository.ts b/src/common/repositories/OfficeFoldersHasCustomerRepository.ts new file mode 100644 index 00000000..2d4b403d --- /dev/null +++ b/src/common/repositories/OfficeFoldersHasCustomerRepository.ts @@ -0,0 +1,42 @@ +import Database from "@Common/databases/database"; +import { OfficeFolderHasCustomers } from "@prisma/client"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; + +@Service() +export default class OfficeFoldersHasCustomerRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().officeFolderHasCustomers; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many relations + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Find a unique relation between an office folder and customers + */ + public async findOneByUid(uid: string): Promise { + const officeFolderHasCustomersEntity = await this.model.findUnique({ + where: { + uid: uid, + }, + }); + + if (!officeFolderHasCustomersEntity) { + throw new Error("relation between office folder and customer not found"); + } + + return officeFolderHasCustomersEntity; + } +} diff --git a/src/common/repositories/OfficeFoldersHasStakeholderRepository.ts b/src/common/repositories/OfficeFoldersHasStakeholderRepository.ts new file mode 100644 index 00000000..02b2bb11 --- /dev/null +++ b/src/common/repositories/OfficeFoldersHasStakeholderRepository.ts @@ -0,0 +1,42 @@ +import Database from "@Common/databases/database"; +import { OfficeFolderHasStakeholders } from "@prisma/client"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; + +@Service() +export default class OfficeFoldersHasStakeholderRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().officeFolderHasStakeholders; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many relations + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Find a unique relation between an office folder and stakeholders + */ + public async findOneByUid(uid: string): Promise { + const officeFolderHasStakeholdersEntity = await this.model.findUnique({ + where: { + uid: uid, + }, + }); + + if (!officeFolderHasStakeholdersEntity) { + throw new Error("relation between office folder and stakeholder not found"); + } + + return officeFolderHasStakeholdersEntity; + } +} diff --git a/src/common/repositories/OfficeFoldersRepository.ts b/src/common/repositories/OfficeFoldersRepository.ts new file mode 100644 index 00000000..18f6e894 --- /dev/null +++ b/src/common/repositories/OfficeFoldersRepository.ts @@ -0,0 +1,153 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { EFolderStatus, OfficeFolders, Prisma } from "@prisma/client"; +import { OfficeFolder } from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class OfficeFoldersRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().officeFolders; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many office folders + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Create new office folder with stakeholders + */ + public async create(officeFolder: OfficeFolder): Promise { + const createArgs: Prisma.OfficeFoldersCreateArgs = { + data: { + folder_number: officeFolder.folder_number, + name: officeFolder.name, + description: officeFolder.description, + status: EFolderStatus.LIVE, + deed: { + connect: { + uid: officeFolder.deed?.uid + }, + }, + office: { + connect: { + uid: officeFolder.office!.uid, + }, + }, + }, + include: { + office_folder_has_stakeholder: true, + }, + }; + if (officeFolder.office_folder_has_stakeholder) { + createArgs.data.office_folder_has_stakeholder = { + createMany: { + data: officeFolder.office_folder_has_stakeholder.map((relation) => ({ + user_stakeholder_uid: relation.user_stakeholder.uid!, + })), + skipDuplicates: true, + }, + }; + } + return this.model.create(createArgs); + } + + /** + * @description : Update data of an office folder + */ + public async update(officeFolderuid: string, officeFolder: OfficeFolder): Promise { + const updateArgs: Prisma.OfficeFoldersUpdateArgs = { + where: { + uid: officeFolderuid, + }, + data: { + folder_number: officeFolder.folder_number, + name: officeFolder.name, + description: officeFolder.description, + status: EFolderStatus[officeFolder.status as keyof typeof EFolderStatus], + archived_description: officeFolder.archived_description, + }, + include: { + office_folder_has_stakeholder: true, + office_folder_has_customers: true, + documents: true, + }, + }; + if (officeFolder.office_folder_has_stakeholder) { + updateArgs.data.office_folder_has_stakeholder = { + deleteMany: { office_folder_uid: officeFolderuid }, + createMany: { + data: officeFolder.office_folder_has_stakeholder.map((relation) => ({ + user_stakeholder_uid: relation.user_stakeholder.uid!, + })), + skipDuplicates: true, + }, + }; + } + if (officeFolder.office_folder_has_customers) { + updateArgs.data.office_folder_has_customers = { + deleteMany: { office_folder_uid: officeFolderuid }, + createMany: { + data: officeFolder.office_folder_has_customers.map((relation) => ({ + customer_uid: relation.customer.uid!, + })), + skipDuplicates: true, + }, + }; + } + if (officeFolder.documents) { + updateArgs.data.documents = { + createMany: { + data: officeFolder.documents.map((relation) => ({ + document_type_uid: relation.document_type!.uid!, + depositor_uid: relation.depositor!.uid!, + })), + skipDuplicates: true, + }, + }; + } + return this.model.update(updateArgs); + } + + /** + * @description : Find one office folder + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.OfficeFoldersFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const officeFolderEntity = await this.model.findUnique(findOneArgs); + + if (!officeFolderEntity) { + throw new Error("office folder not found"); + } + + return officeFolderEntity; + } + + /** + * @description : Delete a folder + */ + public async delete(uid: string): Promise { + return this.model.delete({ + where: { + uid: uid, + }, + }); + } +} diff --git a/src/common/repositories/OfficesRepository.ts b/src/common/repositories/OfficesRepository.ts new file mode 100644 index 00000000..7595a1f5 --- /dev/null +++ b/src/common/repositories/OfficesRepository.ts @@ -0,0 +1,91 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { EOfficeStatus, Offices, Prisma } from "@prisma/client"; +import { Office as OfficeRessource } from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class OfficesRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().offices; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many users + */ + public async findMany(query: any): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + + return this.model.findMany(query); + } + + /** + * @description : Create an office + */ + public async create(office: OfficeRessource): Promise { + return this.model.create({ + data: { + idNot: office.idNot, + name: office.name, + crpcen: office.crpcen, + address: { + create: { + address: office.address!.address, + zip_code: office.address!.zip_code, + city: office.address!.city, + }, + }, + office_status: EOfficeStatus.DESACTIVATED, + }, + }); + } + + /** + * @description : Update data from an office + */ + public async update(uid: string, office: OfficeRessource): Promise { + return this.model.update({ + where: { + uid: uid, + }, + data: { + name: office.name, + address: { + create: { + address: office.address!.address, + zip_code: office.address!.zip_code, + city: office.address!.city, + }, + }, + office_status: EOfficeStatus[office.office_status as keyof typeof EOfficeStatus], + }, + }); + } + + /** + * @description : Find one office + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.OfficesFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const officeEntity = await this.model.findUnique(findOneArgs); + + if (!officeEntity) { + throw new Error("office not found"); + } + + return officeEntity; + } +} diff --git a/src/common/repositories/UsersRepository.ts b/src/common/repositories/UsersRepository.ts new file mode 100644 index 00000000..b7643e18 --- /dev/null +++ b/src/common/repositories/UsersRepository.ts @@ -0,0 +1,158 @@ +import Database from "@Common/databases/database"; +import BaseRepository from "@Repositories/BaseRepository"; +import { Service } from "typedi"; +import { Addresses, Contacts, ECivility, Offices, Prisma, Users } from "@prisma/client"; +import User from "le-coffre-resources/dist/SuperAdmin"; + +@Service() +export default class UsersRepository extends BaseRepository { + constructor(private database: Database) { + super(); + } + protected get model() { + return this.database.getClient().users; + } + protected get instanceDb() { + return this.database.getClient(); + } + + /** + * @description : Find many users + */ + public async findMany(query: Prisma.UsersFindManyArgs): Promise { + query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); + return this.model.findMany(query); + } + + /** + * @description : Create a user + */ + public async create(user: User): Promise { + const createArgs: Prisma.UsersCreateArgs = { + data: { + idNot: user.idNot, + office_membership: { + connectOrCreate: { + where: { + idNot: user.office_membership!.idNot, + }, + create: { + idNot: user.office_membership!.idNot, + name: user.office_membership!.name, + crpcen: user.office_membership!.crpcen, + address: { + create: { + address: user.office_membership!.address!.address, + zip_code: user.office_membership!.address!.zip_code, + city: user.office_membership!.address!.city, + }, + }, + }, + }, + }, + contact: { + create: { + first_name: user.contact!.first_name, + last_name: user.contact!.last_name, + email: user.contact!.email, + phone_number: user.contact!.phone_number, + cell_phone_number: user.contact!.cell_phone_number, + civility: ECivility[user.contact!.civility as keyof typeof ECivility], + address: {}, + }, + }, + }, + }; + if (user.contact!.address) { + createArgs.data.contact!.create!.address!.create = { + address: user.contact!.address.address, + zip_code: user.contact!.address.zip_code, + city: user.contact!.address.city, + }; + } + return this.model.create({ ...createArgs, include: { contact: true, office_membership: { include: { address: true } } } }); + } + + /** + * @description : Update data from a user + */ + public async update( + uid: string, + user: User, + ): Promise< + Users & { + contact: Contacts; + office_membership: Offices & { + address: Addresses; + }; + } + > { + const updateArgs: Prisma.UsersUpdateArgs = { + where: { + uid: uid, + }, + data: { + idNot: user.idNot, + office_membership: { + connectOrCreate: { + where: { + idNot: user.office_membership!.idNot, + }, + create: { + idNot: user.office_membership!.idNot, + name: user.office_membership!.name, + crpcen: user.office_membership!.crpcen, + address: { + create: { + address: user.office_membership!.address!.address, + zip_code: user.office_membership!.address!.zip_code, + city: user.office_membership!.address!.city, + }, + }, + }, + }, + }, + contact: { + update: { + first_name: user.contact!.first_name, + last_name: user.contact!.last_name, + email: user.contact!.email, + phone_number: user.contact!.phone_number, + cell_phone_number: user.contact!.cell_phone_number, + civility: ECivility[user.contact!.civility as keyof typeof ECivility], + address: {}, + }, + }, + }, + }; + if (user.contact!.address) { + updateArgs.data.contact!.update!.address!.update = { + address: user.contact!.address!.address, + zip_code: user.contact!.address!.zip_code, + city: user.contact!.address!.city, + }; + } + return this.model.update({ ...updateArgs, include: { contact: true, office_membership: { include: { address: true } } } }); + } + + /** + * @description : Find one user + */ + public async findOneByUid(uid: string, query?: any): Promise { + const findOneArgs: Prisma.UsersFindUniqueArgs = { + where: { + uid: uid, + }, + }; + if (query) { + findOneArgs.include = query; + } + const userEntity = await this.model.findUnique(findOneArgs); + + if (!userEntity) { + throw new Error("User not found"); + } + + return userEntity; + } +} diff --git a/src/common/repositories/_TemplateRepository/_TemplateRepository.ts b/src/common/repositories/_TemplateRepository/_TemplateRepository.ts deleted file mode 100644 index 8ea415db..00000000 --- a/src/common/repositories/_TemplateRepository/_TemplateRepository.ts +++ /dev/null @@ -1,82 +0,0 @@ -// import Database from "@Common/databases/Database"; -import { ORMBadQueryError } from "@Common/system/database/exceptions/ORMBadQueryError"; -import BaseRepository from "@Repositories/BaseRepository"; -import { Service } from "typedi"; - -export class RequestsByDayMetrics { - date_requested!: Date; - count!: number; -} - -export class CountRpcPathUsage { - path!: string; - count!: number; -} - -@Service() -export default class _TemplateRepository extends BaseRepository { - // TODO ? -> Injection private database: Database - constructor() { - super(); - } - // protected get model() { - // return this.database.getClient().metric; - // } - // protected get instanceDb() { - // return this.database.getClient(); - // } - - /** - * @description : Find many T - * @arguments : query: Prisma.TFindManyArgs - * @returns : Promise - */ - public async findMany() { - try { - // Query - } catch (error) { - throw new ORMBadQueryError((error as Error).message, error as Error); - } - } - - /** - * @description : Find many T - * @arguments : t : Partial - * @returns : Promise - */ - public async findOne() { - try { - // Query - } catch (error) { - throw new ORMBadQueryError((error as Error).message, error as Error); - } - } - - /** - * @description : Create T - * @arguments : t : Partial - * @returns : Promise - */ - public async create() { - try { - // Create a new T - // return T - } catch (error) { - throw new ORMBadQueryError((error as Error).message, error as Error); - } - } - - /** - * @description : Create bulk T - * @arguments : t : Partial - * @returns : Promise - */ - public async createMany() { - try { - // Create many new T - // return T[] - } catch (error) { - throw new ORMBadQueryError((error as Error).message, error as Error); - } - } -} diff --git a/src/common/system/ExpressServer.ts b/src/common/system/ExpressServer.ts index 8f381907..ec8e217b 100644 --- a/src/common/system/ExpressServer.ts +++ b/src/common/system/ExpressServer.ts @@ -31,4 +31,3 @@ export default class ExpressServer implements ServerInterface { return this; } } - diff --git a/src/common/system/ExpressServerTest.ts b/src/common/system/ExpressServerTest.ts new file mode 100644 index 00000000..abf20b60 --- /dev/null +++ b/src/common/system/ExpressServerTest.ts @@ -0,0 +1,39 @@ +import express, { Express, Router } from "express"; +import { Service } from "typedi"; +import ServerInterface, { IConfig } from "./ServerInterface"; + +@Service() +export default class ExpressServer implements ServerInterface { + public router: Express = express(); + private subRouter: Router = express.Router(); + + public getRouter(): Router { + return this.subRouter; + } + + protected getMainRouter(): Express { + return this.router; + } + + public init(config: IConfig) { + this.router.use(...config.middlwares); + this.router.use(config.rootUrl, this.subRouter); + if (config.errorHandler) this.router.use(config.errorHandler); + return this; + } + + public listen() { + return this.router.listen(3001, () => { + console.table( + [ + { + "Entry label": "le coffre API", + Port: 3001, + "Root url": "/api", + }, + ], + ["Entry label", "Port", "Root url"], + ); + }); + } +} diff --git a/src/common/system/ServerInterface.ts b/src/common/system/ServerInterface.ts index 15ea57f2..e3962a03 100644 --- a/src/common/system/ServerInterface.ts +++ b/src/common/system/ServerInterface.ts @@ -14,4 +14,3 @@ export default interface ServerInterface { init(config: IConfig): this; } - diff --git a/src/common/system/controller-pattern/ApiController.ts b/src/common/system/controller-pattern/ApiController.ts index f1159f3e..3f8458c7 100644 --- a/src/common/system/controller-pattern/ApiController.ts +++ b/src/common/system/controller-pattern/ApiController.ts @@ -6,4 +6,3 @@ import HttpCodes from "@Common/system/controller-pattern/HttpCodes"; export default abstract class ApiController extends BaseController {} export { HttpCodes as ResponseStatusCodes }; - diff --git a/src/common/system/controller-pattern/BaseController.ts b/src/common/system/controller-pattern/BaseController.ts index 516b7e66..3b128b1f 100644 --- a/src/common/system/controller-pattern/BaseController.ts +++ b/src/common/system/controller-pattern/BaseController.ts @@ -2,10 +2,8 @@ import { StRoute } from "./StRoute"; import { Response } from "express"; import HttpCodes from "@Common/system/controller-pattern/HttpCodes"; - type IResponseData = {} | string | number | boolean | null | unknown; - export default abstract class BaseController { public expressRoutes!: StRoute[]; public httpCode: typeof HttpCodes = HttpCodes; diff --git a/src/common/system/controller-pattern/Controller.ts b/src/common/system/controller-pattern/Controller.ts index 9a5c8d2e..91d5789f 100644 --- a/src/common/system/controller-pattern/Controller.ts +++ b/src/common/system/controller-pattern/Controller.ts @@ -34,4 +34,3 @@ function createRoute(controller: any, route: StRoute) { } export default Controller; - diff --git a/src/common/system/controller-pattern/ErrorCatch.ts b/src/common/system/controller-pattern/ErrorCatch.ts index d6bed57c..8dc0aea4 100644 --- a/src/common/system/controller-pattern/ErrorCatch.ts +++ b/src/common/system/controller-pattern/ErrorCatch.ts @@ -12,4 +12,3 @@ export default class ErrorCatch { next(args[args.length - 1] ?? "Unknown Error"); } } - diff --git a/src/common/system/controller-pattern/HttpCodes.ts b/src/common/system/controller-pattern/HttpCodes.ts index 433b5525..8ca2500b 100644 --- a/src/common/system/controller-pattern/HttpCodes.ts +++ b/src/common/system/controller-pattern/HttpCodes.ts @@ -1,10 +1,10 @@ -enum HttpCodes { - SUCCESS = 200, - CREATED = 201, - BAD_REQUEST = 400, - INTERNAL_ERROR = 500, - UNKNOWN_ERROR = 520, - NOT_IMPLEMENTED = 501, - NOT_FOUND = 404, -} -export default HttpCodes; +enum HttpCodes { + SUCCESS = 200, + CREATED = 201, + BAD_REQUEST = 400, + INTERNAL_ERROR = 500, + UNKNOWN_ERROR = 520, + NOT_IMPLEMENTED = 501, + NOT_FOUND = 404, +} +export default HttpCodes; diff --git a/src/common/system/controller-pattern/Methods.ts b/src/common/system/controller-pattern/Methods.ts index b0dd3729..43c0f6f0 100644 --- a/src/common/system/controller-pattern/Methods.ts +++ b/src/common/system/controller-pattern/Methods.ts @@ -1,7 +1,12 @@ import BaseController from "./BaseController"; import { StRoute } from "./StRoute"; -function MethodsAny(type: StRoute["type"], path: string, frontMiddlewares: StRoute["frontMiddlewares"] = [], backMiddlewares: StRoute["backMiddlewares"] = []) { +function MethodsAny( + type: StRoute["type"], + path: string, + frontMiddlewares: StRoute["frontMiddlewares"] = [], + backMiddlewares: StRoute["backMiddlewares"] = [], +) { return (target: any, memberName: string, propertyDescriptor: PropertyDescriptor) => { const func = propertyDescriptor.value; const constructor: typeof BaseController = target.constructor; @@ -29,4 +34,3 @@ export const Delete = MethodsAny.bind(null, "delete"); * @description Decorator Method PUT */ export const Put = MethodsAny.bind(null, "put"); - diff --git a/src/common/system/controller-pattern/StRoute.ts b/src/common/system/controller-pattern/StRoute.ts index f216112f..fe6ae78d 100644 --- a/src/common/system/controller-pattern/StRoute.ts +++ b/src/common/system/controller-pattern/StRoute.ts @@ -7,4 +7,3 @@ export interface StRoute { frontMiddlewares: ((requests: Request, response: Response, next: NextFunction) => void)[]; backMiddlewares: ((requests: Request, response: Response, next: NextFunction) => void)[]; } - diff --git a/src/common/system/controller-pattern/exceptions/HttpException.ts b/src/common/system/controller-pattern/exceptions/HttpException.ts index ceb49fa7..62a485b7 100644 --- a/src/common/system/controller-pattern/exceptions/HttpException.ts +++ b/src/common/system/controller-pattern/exceptions/HttpException.ts @@ -1,7 +1,7 @@ -import HttpCodes from "../HttpCodes"; - -export default class HttpException extends Error { - constructor(message: string, public httpCode: HttpCodes = HttpCodes.UNKNOWN_ERROR) { - super(message); - } -} +import HttpCodes from "../HttpCodes"; + +export default class HttpException extends Error { + constructor(message: string, public httpCode: HttpCodes = HttpCodes.UNKNOWN_ERROR) { + super(message); + } +} diff --git a/src/common/system/database/DbProvider.ts b/src/common/system/database/DbProvider.ts index 0037217b..fa640f45 100644 --- a/src/common/system/database/DbProvider.ts +++ b/src/common/system/database/DbProvider.ts @@ -1,34 +1,36 @@ -import dotenv from "dotenv"; -import { PrismaClient } from "@prisma/client"; -import IDatabaseConfig from "../../config/database/IDatabaseConfig"; -import { BackendVariables } from "@Common/config/variables/Variables"; -import Container from "typedi"; - -dotenv.config(); - -export default class DbProvider { - protected readonly variables = Container.get(BackendVariables); - protected client = new PrismaClient({ - datasources: { - db: { - url: `postgres://${this.variables.DATABASE_USER}:${this.variables.DATABASE_PASSWORD}@${this.variables.DATABASE_HOSTNAME}:${this.variables.DATABASE_PORT}/${this.variables.DATABASE_NAME}`, - }, - }, - }); - - constructor(protected config: IDatabaseConfig) {} - - public async connect(): Promise { - await this.client.$connect(); - console.info(`⚡️[Prisma]: Connected to ${this.config.name}`); // A Logger middleware is to be added here - } - - public getClient() { - return this.client; - } - - public async disconnect(): Promise { - await this.client.$disconnect(); - console.info(`⚡️[Prisma]: Disconnected from ${this.config.name}`); // A Logger middleware is to be added here - } -} +import { BackendVariables } from "@Common/config/variables/Variables"; +import { PrismaClient } from "@prisma/client"; +import dotenv from "dotenv"; +import Container from "typedi"; + +import IDatabaseConfig from "../../config/database/IDatabaseConfig"; + +dotenv.config(); + +export default class DbProvider { + protected readonly variables = Container.get(BackendVariables); + protected url = `postgres://${this.variables.DATABASE_USERNAME}:${this.variables.DATABASE_PASSWORD}@${this.variables.DATABASE_HOST}:${this.variables.DATABASE_PORT}/${this.variables.DATABASE_NAME}`; + protected client = new PrismaClient({ + datasources: { + db: { + url: this.url, + }, + }, + }); + + constructor(protected config: IDatabaseConfig) {} + + public async connect(): Promise { + await this.client.$connect(); + console.info(`⚡️[Prisma]: Connected to ${this.config.name}`); // A Logger middleware is to be added here + } + + public getClient() { + return this.client; + } + + public async disconnect(): Promise { + await this.client.$disconnect(); + console.info(`⚡️[Prisma]: Disconnected from ${this.config.name}`); // A Logger middleware is to be added here + } +} diff --git a/src/common/system/database/exceptions/ORMBadQueryError.ts b/src/common/system/database/exceptions/ORMBadQueryError.ts index b61c4d15..89255e6a 100644 --- a/src/common/system/database/exceptions/ORMBadQueryError.ts +++ b/src/common/system/database/exceptions/ORMBadQueryError.ts @@ -2,4 +2,4 @@ export class ORMBadQueryError extends Error { constructor(message: string, public error: Error) { super(message); } -} \ No newline at end of file +} diff --git a/src/common/system/database/index.ts b/src/common/system/database/index.ts index 6f728469..943586b8 100644 --- a/src/common/system/database/index.ts +++ b/src/common/system/database/index.ts @@ -2,4 +2,4 @@ import IDatabaseConfig from "@Common/config/database/IDatabaseConfig"; import DbProvider from "./DbProvider"; export type { IDatabaseConfig }; -export default DbProvider; \ No newline at end of file +export default DbProvider; diff --git a/src/entries/App.ts b/src/entries/App.ts index 5db0695d..da76f6ae 100644 --- a/src/entries/App.ts +++ b/src/entries/App.ts @@ -8,6 +8,7 @@ import bodyParser from "body-parser"; // import TezosLink from "@Common/databases/TezosLink"; import errorHandler from "@App/middlewares/ErrorHandler"; import { BackendVariables } from "@Common/config/variables/Variables"; +import fileHandler from "@App/middlewares/FileHandler"; (async () => { try { @@ -16,13 +17,13 @@ import { BackendVariables } from "@Common/config/variables/Variables"; const port = variables.APP_PORT; const rootUrl = variables.APP_ROOT_URL; const label = variables.APP_LABEL ?? "Unknown Service"; - + // Container.get(TezosLink).connect(); Container.get(ExpressServer).init({ label, port: parseInt(port), rootUrl, - middlwares: [cors({ origin: "*" }), bodyParser.urlencoded({ extended: true }), bodyParser.json()], + middlwares: [cors({ origin: "*" }), fileHandler, bodyParser.urlencoded({ extended: true }), bodyParser.json()], errorHandler, }); @@ -31,4 +32,3 @@ import { BackendVariables } from "@Common/config/variables/Variables"; console.error(e); } })(); - diff --git a/src/services/AddressesService/AddressesService.ts b/src/services/AddressesService/AddressesService.ts deleted file mode 100644 index 8295b1a0..00000000 --- a/src/services/AddressesService/AddressesService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class AddressesService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all addresses - * @returns : T - * @throws {Error} If addresses cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const address = await this.usersRepository.findOne(uuid); - // if (!address) Promise.reject(new Error("Cannot get address by uuid")); - return { response: "/api/addresses > GET : All addresses > Not implemented yet" }; - } - - /** - * @description : Create a new address - * @returns : T - * @throws {Error} If address cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const address = await this.projectRepository.create(projectEntity); - // if (!address) Promise.reject(new Error("Cannot create project")); - return { response: "/api/addresses > POST : Create address > Not implemented yet" }; - } - - /** - * @description : Modify a new address - * @returns : T - * @throws {Error} If address cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const address = await this.projectRepository.create(projectEntity); - // if (!address) Promise.reject(new Error("Cannot create project")); - return { response: "/api/addresses > PUT : Modified address > Not implemented yet" }; - } - - /** - * @description : Get a address by uid - * @returns : T - * @throws {Error} If address cannot be created - * @param : projectEntity: Partial - */ - public async getByUid(uuid: string) { - // const address = await this.usersRepository.findOne(uuid); - // if (!address) Promise.reject(new Error("Cannot get address by uuid")); - return { response: "/api/addresses/:uuid > GET : address by uid > Not implemented yet" }; - } -} diff --git a/src/services/BaseService.ts b/src/services/BaseService.ts index 91aae64f..0ff263c1 100644 --- a/src/services/BaseService.ts +++ b/src/services/BaseService.ts @@ -1,8 +1,6 @@ - export default abstract class BaseService { /** @TODO place methods in a config file */ public static readonly whitelisted: string[] = ["/chains/main/blocks"]; public static readonly blacklisted: string[] = ["/context/contracts", "/monitor", "/network"]; public static readonly rollingPatterns: string[] = ["/head", "/injection/operation"]; } - diff --git a/src/services/ContactsService/ContactsService.ts b/src/services/ContactsService/ContactsService.ts deleted file mode 100644 index 02cde913..00000000 --- a/src/services/ContactsService/ContactsService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class ContactsService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all contacts - * @returns : T - * @throws {Error} If contacts cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const contact = await this.usersRepository.findOne(uuid); - // if (!contact) Promise.reject(new Error("Cannot get contact by uuid")); - return { response: "/api/contacts > GET : All contacts > Not implemented yet" }; - } - - /** - * @description : Create a new contact - * @returns : T - * @throws {Error} If contact cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const contact = await this.projectRepository.create(projectEntity); - // if (!contact) Promise.reject(new Error("Cannot create project")); - return { response: "/api/contacts > POST : Create contact > Not implemented yet" }; - } - - /** - * @description : Modify a new contact - * @returns : T - * @throws {Error} If contact cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const contact = await this.projectRepository.create(projectEntity); - // if (!contact) Promise.reject(new Error("Cannot create project")); - return { response: "/api/contacts > PUT : Modified contact > Not implemented yet" }; - } - - /** - * @description : Get a contact by uid - * @returns : T - * @throws {Error} If project cannot be created - * @param : projectEntity: Partial - */ - public async getByUid(uuid: string) { - // const contact = await this.usersRepository.findOne(uuid); - // if (!contact) Promise.reject(new Error("Cannot get contact by uuid")); - return { response: "/api/contacts/:uuid > GET : contact by uid > Not implemented yet" }; - } -} diff --git a/src/services/CustomersService/CustomersService.ts b/src/services/CustomersService/CustomersService.ts deleted file mode 100644 index 89b01607..00000000 --- a/src/services/CustomersService/CustomersService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class CustomersService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all Customers - * @returns : T - * @throws {Error} If Customers cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const customer = await this.customersRepository.findOne(uuid); - // if (!customer) Promise.reject(new Error("Cannot get customer by uuid")); - return { response: "/api/customers > GET : All customers > Not implemented yet" }; - } - - /** - * @description : Create a new customer - * @returns : T - * @throws {Error} If customer cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const customer = await this.projectRepository.create(projectEntity); - // if (!customer) Promise.reject(new Error("Cannot create project")); - return { response: "/api/customers > POST : Create customer > Not implemented yet" }; - } - - /** - * @description : Modify a customer - * @returns : T - * @throws {Error} If customer cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const customer = await this.projectRepository.create(projectEntity); - // if (!customer) Promise.reject(new Error("Cannot create project")); - return { response: "/api/customers > PUT : Modified customer > Not implemented yet" }; - } - - /** - * @description : Get a customer by uid - * @returns : T - * @throws {Error} If customer cannot be get by uid - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const customer = await this.customersRepository.findOne(uid); - // if (!customer) Promise.reject(new Error("Cannot get customer by uid")); - return { response: "/api/customers/:uid > GET : customer by uid > Not implemented yet" }; - } -} diff --git a/src/services/DeedTypesService/DeedTypesService.ts b/src/services/DeedTypesService/DeedTypesService.ts deleted file mode 100644 index a85eea94..00000000 --- a/src/services/DeedTypesService/DeedTypesService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class DeedTypesService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all deed-types - * @returns : T - * @throws {Error} If deed-types cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const deedtype = await this.customersRepository.findOne(uuid); - // if (!deedtype) Promise.reject(new Error("Cannot get deedtype by uuid")); - return { response: "/api/deed-types > GET : All deed-types > Not implemented yet" }; - } - - /** - * @description : Create a new deed-type - * @returns : T - * @throws {Error} If deed-type cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const project = await this.projectRepository.create(projectEntity); - // if (!project) Promise.reject(new Error("Cannot create project")); - return { response: "/api/deed-types > POST : Create deed-type > Not implemented yet" }; - } - - /** - * @description : Modify a deed-type - * @returns : T - * @throws {Error} If deed-type cannot be modifified - * @param : projectEntity: Partial - */ - public async put() { - // const project = await this.projectRepository.create(projectEntity); - // if (!project) Promise.reject(new Error("Cannot create project")); - return { response: "/api/deed-types > PUT : Modified deed-type > Not implemented yet" }; - } - - /** - * @description : Get a deedtype by uid - * @returns : T - * @throws {Error} If deed-type cannot be get by uid - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const deedtype = await this.customersRepository.findOne(uuid); - // if (!deedtype) Promise.reject(new Error("Cannot get deedtype by uid")); - return { response: "/api/deed-types/:uid > GET : deed-type by uid > Not implemented yet" }; - } -} diff --git a/src/services/DeedsService/DeedsService.ts b/src/services/DeedsService/DeedsService.ts deleted file mode 100644 index 09ca10fe..00000000 --- a/src/services/DeedsService/DeedsService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class DeedsService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all deeds - * @returns : T - * @throws {Error} If deeds cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const deed = await this.usersRepository.findOne(uuid); - // if (!deed) Promise.reject(new Error("Cannot get deed by uuid")); - return { response: "/api/deeds > GET : All deeds > Not implemented yet" }; - } - - /** - * @description : Create a new deed - * @returns : T - * @throws {Error} If deeds cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const deeds = await this.projectRepository.create(projectEntity); - // if (!deeds) Promise.reject(new Error("Cannot create project")); - return { response: "/api/deeds > POST : Create deed > Not implemented yet" }; - } - - /** - * @description : Modify a new deed - * @returns : T - * @throws {Error} If deeds cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const deeds = await this.projectRepository.create(projectEntity); - // if (!deeds) Promise.reject(new Error("Cannot create project")); - return { response: "/api/deeds > PUT : Modified deed > Not implemented yet" }; - } - - /** - * @description : Get a deed by uid - * @returns : T - * @throws {Error} If project cannot be created - * @param : projectEntity: Partial - */ - public async getByUid(uuid: string) { - // const deed = await this.usersRepository.findOne(uuid); - // if (!deed) Promise.reject(new Error("Cannot get deed by uuid")); - return { response: "/api/deeds/:uuid > GET : deed by uid > Not implemented yet" }; - } -} diff --git a/src/services/DocumentTypesService/DocumentTypesService.ts b/src/services/DocumentTypesService/DocumentTypesService.ts deleted file mode 100644 index 202074db..00000000 --- a/src/services/DocumentTypesService/DocumentTypesService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class DocumentTypesService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all document-types - * @returns : T - * @throws {Error} If document-types cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const documentType = await this.foldersRepository.findOne(uuid); - // if (!documentType) Promise.reject(new Error("Cannot get document-type by uuid")); - return { response: "/api/document-types > GET : All document-types > Not implemented yet" }; - } - - /** - * @description : Create a new document-type - * @returns : T - * @throws {Error} If document-types cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const project = await this.projectRepository.create(projectEntity); - // if (!project) Promise.reject(new Error("Cannot create project")); - return { response: "/api/document-types > POST : Create document-type > Not implemented yet" }; - } - - /** - * @description : Modify a document-type - * @returns : T - * @throws {Error} If document-type cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const documentType = await this.projectRepository.create(projectEntity); - // if (!documentType) Promise.reject(new Error("Cannot create documentType")); - return { response: "/api/document-types > PUT : Modified document-type > Not implemented yet" }; - } - - /** - * @description : Get a document-type by uid - * @returns : T - * @throws {Error} If document-type cannot be get bu uid - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const documentType = await this.foldersRepository.findOne(uid); - // if (!documentType) Promise.reject(new Error("Cannot get document-type by uid")); - return { response: "/api/document-types/:uid > GET : document-type by uid > Not implemented yet" }; - } -} diff --git a/src/services/DocumentsService/DocumentsService.ts b/src/services/DocumentsService/DocumentsService.ts deleted file mode 100644 index 790f7843..00000000 --- a/src/services/DocumentsService/DocumentsService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class DocumentsService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all documents - * @returns : T - * @throws {Error} If documents cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const document = await this.customersRepository.findOne(uuid); - // if (!document) Promise.reject(new Error("Cannot get documents")); - return { response: "/api/documents > GET : All documents > Not implemented yet" }; - } - - /** - * @description : Create a new document - * @returns : T - * @throws {Error} If document cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const document = await this.projectRepository.create(projectEntity); - // if (!document) Promise.reject(new Error("Cannot create document")); - return { response: "/api/documents > POST : Create document > Not implemented yet" }; - } - - /** - * @description : Modify a document - * @returns : T - * @throws {Error} If document cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const document = await this.projectRepository.create(projectEntity); - // if (!document) Promise.reject(new Error("Cannot create document")); - return { response: "/api/documents > PUT : Modified document > Not implemented yet" }; - } - - /** - * @description : Get a document by uid - * @returns : T - * @throws {Error} If document cannot be get by uid - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const document = await this.customersRepository.findOne(uid); - // if (!document) Promise.reject(new Error("Cannot get document by uid")); - return { response: "/api/documents/:uid > GET : document by uid > Not implemented yet" }; - } -} diff --git a/src/services/FilesService/FilesService.ts b/src/services/FilesService/FilesService.ts deleted file mode 100644 index c4c1f6f8..00000000 --- a/src/services/FilesService/FilesService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class FilesService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all files - * @returns : T - * @throws {Error} If files cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const files = await this.usersRepository.findOne(uuid); - // if (!files) Promise.reject(new Error("Cannot get files")); - return { response: "/api/files > GET : All files > Not implemented yet" }; - } - - /** - * @description : Create a new file - * @returns : T - * @throws {Error} If file cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const file = await this.projectRepository.create(projectEntity); - // if (!file) Promise.reject(new Error("Cannot create project")); - return { response: "/api/files > POST : Create file > Not implemented yet" }; - } - - /** - * @description : Modify a new file - * @returns : T - * @throws {Error} If file cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const file = await this.projectRepository.create(projectEntity); - // if (!file) Promise.reject(new Error("Cannot create project")); - return { response: "/api/files > PUT : Modified file > Not implemented yet" }; - } - - /** - * @description : Get a file by uid - * @returns : T - * @throws {Error} If project cannot be created - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const file = await this.usersRepository.findOne(uid); - // if (!file) Promise.reject(new Error("Cannot get file by uid")); - return { response: "/api/files/:uid > GET : file by uid > Not implemented yet" }; - } -} diff --git a/src/services/FoldersService/FoldersService.ts b/src/services/FoldersService/FoldersService.ts deleted file mode 100644 index 633f64b9..00000000 --- a/src/services/FoldersService/FoldersService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class FoldersService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all folders - * @returns : T - * @throws {Error} If folders cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const folder = await this.foldersRepository.findOne(uuid); - // if (!folder) Promise.reject(new Error("Cannot get folder by uuid")); - return { response: "/api/folders > GET : All folders > Not implemented yet" }; - } - - /** - * @description : Create a new folder - * @returns : T - * @throws {Error} If folder cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const folder = await this.projectRepository.create(projectEntity); - // if (!folder) Promise.reject(new Error("Cannot create folder")); - return { response: "/api/folders > POST : Create folder > Not implemented yet" }; - } - - /** - * @description : Modify a folder - * @returns : T - * @throws {Error} If folder cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const folder = await this.projectRepository.create(projectEntity); - // if (!folder) Promise.reject(new Error("Cannot create folder")); - return { response: "/api/folders > PUT : Modified folder > Not implemented yet" }; - } - - /** - * @description : Get a folder by uid - * @returns : T - * @throws {Error} If folder cannot be get by uid - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const folder = await this.foldersRepository.findOne(uid); - // if (!folder) Promise.reject(new Error("Cannot get folder by uid")); - return { response: "/api/folders/:uid > GET : folder by uid > Not implemented yet" }; - } -} diff --git a/src/services/OfficesService/OfficesService.ts b/src/services/OfficesService/OfficesService.ts deleted file mode 100644 index 2b6d2ba8..00000000 --- a/src/services/OfficesService/OfficesService.ts +++ /dev/null @@ -1,58 +0,0 @@ -// import ProjectsRepository from "@Common/repositories/projects/ProjectsRepository"; -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class OfficesService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all office - * @returns : T - * @throws {Error} If offices cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const office = await this.usersRepository.findOne(uuid); - // if (!office) Promise.reject(new Error("Cannot get office by uuid")); - return { response: "/api/office > GET : All office > Not implemented yet" }; - } - - /** - * @description : Create a new office - * @returns : T - * @throws {Error} If office cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const project = await this.projectRepository.create(projectEntity); - // if (!project) Promise.reject(new Error("Cannot create project")); - return { response: "/api/office > POST : Create office > Not implemented yet" }; - } - - /** - * @description : Modify an office - * @returns : T - * @throws {Error} If office cannot be modified - * @param : projectEntity: Partial - */ - public async put() { - // const project = await this.projectRepository.create(projectEntity); - // if (!project) Promise.reject(new Error("Cannot create project")); - return { response: "/api/office > PUT : Modified office > Not implemented yet" }; - } - - /** - * @description : Get a office by uid - * @returns : T - * @throws {Error} If office cannot be get - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const office = await this.usersRepository.findOne(uuid); - // if (!office) Promise.reject(new Error("Cannot get office by uuid")); - return { response: "/api/office/:uid > GET : office by uid > Not implemented yet" }; - } -} diff --git a/src/services/UsersService/UsersService.ts b/src/services/UsersService/UsersService.ts deleted file mode 100644 index a1b12d29..00000000 --- a/src/services/UsersService/UsersService.ts +++ /dev/null @@ -1,57 +0,0 @@ -import BaseService from "@Services/BaseService"; -import { Service } from "typedi"; - -@Service() -export default class UsersService extends BaseService { - constructor() { - super(); - } - - /** - * @description : Get all users - * @returns : T - * @throws {Error} If users cannot be get - * @param : projectEntity: Partial - */ - public async get() { - // const user = await this.usersRepository.findOne(uuid); - // if (!user) Promise.reject(new Error("Cannot get user by uuid")); - return { response: "/api/users > GET : All users > Not implemented yet" }; - } - - /** - * @description : Create a new user - * @returns : T - * @throws {Error} If user cannot be created - * @param : projectEntity: Partial - */ - public async create() { - // const project = await this.projectRepository.create(projectEntity); - // if (!project) Promise.reject(new Error("Cannot create project")); - return { response: "/api/users > POST : Create user > Not implemented yet" }; - } - - /** - * @description : Modify a user - * @returns : T - * @throws {Error} If user cannot be modififed - * @param : projectEntity: Partial - */ - public async put() { - // const project = await this.projectRepository.create(projectEntity); - // if (!project) Promise.reject(new Error("Cannot create project")); - return { response: "/api/users > PUT : Modified user > Not implemented yet" }; - } - - /** - * @description : Get a user by uid - * @returns : T - * @throws {Error} If user cannot be get bu uid - * @param : projectEntity: Partial - */ - public async getByUid(uid: string) { - // const user = await this.usersRepository.findOne(uuid); - // if (!user) Promise.reject(new Error("Cannot get user by uuid")); - return { response: "/api/users/:uid > GET : user by uid > Not implemented yet" }; - } -} diff --git a/src/services/customer/DocumentsService/DocumentsService.ts b/src/services/customer/DocumentsService/DocumentsService.ts new file mode 100644 index 00000000..b5d470e0 --- /dev/null +++ b/src/services/customer/DocumentsService/DocumentsService.ts @@ -0,0 +1,60 @@ +import { Documents, Prisma } from "@prisma/client"; +import { Document } from "le-coffre-resources/dist/Customer"; +import DocumentsRepository from "@Repositories/DocumentsRepository"; +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; + +@Service() +export default class DocumentsService extends BaseService { + constructor(private documentsRepository: DocumentsRepository) { + super(); + } + + /** + * @description : Get all documents + * @throws {Error} If documents cannot be get + */ + public async get(query: any) { + return this.documentsRepository.findMany(query); + } + + /** + * @description : Create a new document + * @throws {Error} If document cannot be created + */ + public async create(document: Document): Promise { + return this.documentsRepository.create(document); + } + + /** + * @description : Create new documents + * @throws {Error} If documents or one of them cannot be created + */ + public async createMany(documents: Document[]): Promise { + return this.documentsRepository.createMany(documents); + } + + /** + * @description : Modify a document + * @throws {Error} If document cannot be modified + */ + public async update(uid: string, document: Document): Promise { + return this.documentsRepository.update(uid, document); + } + + /** + * @description : Delete a document + * @throws {Error} If document cannot be deleted + */ + public async delete(uid: string): Promise { + return this.documentsRepository.delete(uid); + } + + /** + * @description : Get a document by uid + * @throws {Error} If document cannot be get by uid + */ + public async getByUid(uid: string, query?: any) { + return this.documentsRepository.findOneByUid(uid, query); + } +} diff --git a/src/services/private-services/AddressesService/AddressesService.ts b/src/services/private-services/AddressesService/AddressesService.ts new file mode 100644 index 00000000..41e53765 --- /dev/null +++ b/src/services/private-services/AddressesService/AddressesService.ts @@ -0,0 +1,26 @@ +import AddressesRepository from "@Repositories/AddressesRepository"; +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; + +@Service() +export default class AddressesService extends BaseService { + constructor(private addressRepository: AddressesRepository) { + super(); + } + + /** + * @description : Get all addresses + * @throws {Error} If addresses cannot be get + */ + public async get(query: any) { + return this.addressRepository.findMany(query); + } + + /** + * @description : Get a address by uid + * @throws {Error} If address cannot be get + */ + public async getByUid(uid: string) { + return this.addressRepository.findOneByUid(uid); + } +} diff --git a/src/services/private-services/AuthService/AuthService.ts b/src/services/private-services/AuthService/AuthService.ts new file mode 100644 index 00000000..ab528ec4 --- /dev/null +++ b/src/services/private-services/AuthService/AuthService.ts @@ -0,0 +1,53 @@ +import jwt from "jsonwebtoken"; +import BaseService from "@Services/BaseService"; +import "reflect-metadata"; +import { BackendVariables } from "@Common/config/variables/Variables"; +import Container, { Service } from "typedi"; + +type IdNotTokens = { + access_token: string; + id_token: string; +}; + +@Service() +export default class AuthService extends BaseService { + protected readonly variables = Container.get(BackendVariables); + private constructor() { + super(); + } + + /** + * @description : Get IdNot id_token and access_token + * @throws {Error} If jwt pair cannot be get + */ + public async getUserFromIdNotTokens(code: string) { + const tokens = await this.getIdNotTokens(code); + return jwt.decode(tokens.id_token); + } + + private async getIdNotTokens(code: string): Promise { + const url = new URL( + this.variables.IDNOT_CONNEXION_URL.concat("?") + + new URLSearchParams({ + client_id: this.variables.IDNOT_CLIENT_ID, + client_secret: this.variables.IDNOT_CLIENT_SECRET, + redirect_uri: this.variables.IDNOT_REDIRECT_URL, + code: code, + grant_type: "authorization_code", + }), + ); + try { + const headers = new Headers({ + "Content-Type": "application/x-www-form-urlencoded", + }); + const res = await fetch(url, { + method: "POST", + headers: headers, + }); + const data = await res.json(); + return data as IdNotTokens; + } catch (error) { + throw new Error(); + } + } +} diff --git a/src/services/private-services/ContactsService/ContactsService.ts b/src/services/private-services/ContactsService/ContactsService.ts new file mode 100644 index 00000000..4d381a84 --- /dev/null +++ b/src/services/private-services/ContactsService/ContactsService.ts @@ -0,0 +1,26 @@ +import ContactsRepository from "@Repositories/ContactsRepository"; +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; + +@Service() +export default class ContactsService extends BaseService { + constructor(private contactRepository: ContactsRepository) { + super(); + } + + /** + * @description : Get all contacts + * @throws {Error} If contacts cannot be get + */ + public async get(query: any) { + return this.contactRepository.findMany(query); + } + + /** + * @description : Get a contact by uid + * @throws {Error} If contact cannot be get + */ + public async getByUid(uid: string) { + return this.contactRepository.findOneByUid(uid); + } +} diff --git a/src/services/private-services/CryptoService/CryptoService.ts b/src/services/private-services/CryptoService/CryptoService.ts new file mode 100644 index 00000000..5ac62af1 --- /dev/null +++ b/src/services/private-services/CryptoService/CryptoService.ts @@ -0,0 +1,48 @@ +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; +import { BackendVariables } from "@Common/config/variables/Variables"; +import crypto from "crypto"; + +@Service() +export default class CryptoService extends BaseService { + + private static readonly CRYPTO_ALGORITHM = "aes-256-ctr"; + + constructor(protected variables: BackendVariables) { + super(); + } + + private getKey(key: string) { + return crypto.createHash('sha256').update(String(key)).digest('base64').slice(0, 32); + } + + /** + * @description : encrypt data + * @throws {Error} If data cannot be encrypted + */ + public async encrypt(buffer: Buffer, key: string): Promise { + // Create an initialization vector + const iv = crypto.randomBytes(16); + // Create a new cipher using the algorithm, key, and iv + const cipher = crypto.createCipheriv(CryptoService.CRYPTO_ALGORITHM, this.getKey(key), iv); + // Create the new (encrypted) buffer + const result = Buffer.concat([iv, cipher.update(buffer), cipher.final()]); + return result; + } + + /** + * @description : decrypt data with an initialization vector + * @throws {Error} If data cannot be decrypted + */ + public async decrypt(encrypted: Buffer, key: string): Promise { + // Get the iv: the first 16 bytes + const iv = encrypted.subarray(0, 16); + // Get the rest + encrypted = encrypted.subarray(16); + // Create a decipher + const decipher = crypto.createDecipheriv(CryptoService.CRYPTO_ALGORITHM, this.getKey(key), iv); + // Actually decrypt it + const result = Buffer.concat([decipher.update(encrypted), decipher.final()]); + return result; + } +} diff --git a/src/services/private-services/FilesService/FilesService.ts b/src/services/private-services/FilesService/FilesService.ts new file mode 100644 index 00000000..88e5948b --- /dev/null +++ b/src/services/private-services/FilesService/FilesService.ts @@ -0,0 +1,88 @@ +import FilesRepository from "@Repositories/FilesRepository"; +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; +import { File } from "le-coffre-resources/dist/SuperAdmin"; +import CryptoService from "../CryptoService/CryptoService"; +import IpfsService from "../IpfsService/IpfsService"; +import { BackendVariables } from "@Common/config/variables/Variables"; +import { Readable } from "stream"; +import { v4 } from "uuid"; + +@Service() +export default class FilesService extends BaseService { + constructor( + private filesRepository: FilesRepository, + private ipfsService: IpfsService, + private variables: BackendVariables, + private cryptoService: CryptoService, + ) { + super(); + } + + /** + * @description : Get all files + * @throws {Error} If files cannot be ge + */ + public async get(query: any) { + return this.filesRepository.findMany(query); + } + + /** + * @description : Get a file by uid + * @throws {Error} If project cannot be created + */ + public async getByUid(uid: string) { + return this.filesRepository.findOneByUid(uid); + } + + /** + * @description : view a file + * @throws {Error} If file cannot be deleted + */ + public async updload(uid: string) { + const file = await this.filesRepository.findOneByUid(uid); + if (!file.key) throw new Error("file deleted"); + const fileResult = await fetch(file.file_path); + const fileContent = await fileResult.arrayBuffer(); + return await this.cryptoService.decrypt(Buffer.from(fileContent), file.key); + } + + /** + * @description : Create a new file + * @throws {Error} If file cannot be created + */ + public async create(file: File, fileData: Express.Multer.File) { + const key = v4(); + const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key); + //const encryptedFileName = await this.cryptoService.encrypt(Buffer.from(fileData.originalname, 'utf-8'), key); + const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname); + file.file_name = fileData.originalname; //encryptedFileName.toString('utf-8') + file.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash); + + return this.filesRepository.create(file, key); + } + + /** + * @description : Modify a new file + * @throws {Error} If file cannot be modified + */ + public async update(uid: string, file: File) { + return this.filesRepository.update(uid, file); + } + + /** + * @description : Delete a file + * @throws {Error} If file cannot be deleted + */ + public async delete(uid: string) { + try { + const fileToUnpin = await this.filesRepository.findOneByUid(uid); + const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length); + await this.ipfsService.unpinFile(fileHash); + } catch(error) { + console.error(error); + } + + return this.filesRepository.delete(uid); + } +} diff --git a/src/services/private-services/IpfsService/IpfsService.ts b/src/services/private-services/IpfsService/IpfsService.ts new file mode 100644 index 00000000..cc0f3df7 --- /dev/null +++ b/src/services/private-services/IpfsService/IpfsService.ts @@ -0,0 +1,30 @@ +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; +import pinataSDK from "@pinata/sdk"; +import { BackendVariables } from "@Common/config/variables/Variables"; +import { Readable } from "stream"; + +@Service() +export default class FilesService extends BaseService { + private ipfsClient: pinataSDK; + constructor(protected variables: BackendVariables) { + super(); + this.ipfsClient = new pinataSDK({ pinataApiKey: variables.PINATA_API_KEY, pinataSecretApiKey: variables.PINATA_API_SECRET }) + } + + /** + * @description : pin a file + * @throws {Error} If file cannot be pinned + */ + public async pinFile(stream: Readable, fileName: string) { + return this.ipfsClient.pinFileToIPFS(stream, {pinataMetadata : {name: fileName}}); + } + + /** + * @description : unpin a file + * @throws {Error} If file cannot be unpinned + */ + public async unpinFile(hashToUnpin: string) { + return this.ipfsClient.unpin(hashToUnpin); + } +} diff --git a/src/services/NotificationsService/NotificationsService.ts b/src/services/private-services/NotificationsService/NotificationsService.ts similarity index 99% rename from src/services/NotificationsService/NotificationsService.ts rename to src/services/private-services/NotificationsService/NotificationsService.ts index 790e0bab..4187e937 100644 --- a/src/services/NotificationsService/NotificationsService.ts +++ b/src/services/private-services/NotificationsService/NotificationsService.ts @@ -18,7 +18,7 @@ export default class NotificationsService extends BaseService { // if (!notifications) Promise.reject(new Error("Cannot get notifications")); return { response: "/api/notifications > GET : All notifications > Not implemented yet" }; } - + /** * @description : Create a new notification * @returns : T diff --git a/src/services/super-admin/CustomersService/CustomersService.ts b/src/services/super-admin/CustomersService/CustomersService.ts new file mode 100644 index 00000000..80765051 --- /dev/null +++ b/src/services/super-admin/CustomersService/CustomersService.ts @@ -0,0 +1,44 @@ +import { Customers, Prisma } from "@prisma/client"; +import CustomersRepository from "@Repositories/CustomersRepository"; +import BaseService from "@Services/BaseService"; +import { Customer } from "le-coffre-resources/dist/SuperAdmin"; +import { Service } from "typedi"; + +@Service() +export default class CustomersService extends BaseService { + constructor(private customerRepository: CustomersRepository) { + super(); + } + + /** + * @description : Get all Customers + * @throws {Error} If Customers cannot be get + */ + public async get(query: Prisma.CustomersFindManyArgs): Promise { + return this.customerRepository.findMany(query); + } + + /** + * @description : Create a new customer + * @throws {Error} If customer cannot be created + */ + public async create(customerEntity: Customer): Promise { + return this.customerRepository.create(customerEntity); + } + + /** + * @description : Modify a customer + * @throws {Error} If customer cannot be modified + */ + public async update(uid: string, customerEntity: Customer): Promise { + return this.customerRepository.update(uid, customerEntity); + } + + /** + * @description : Get a customer by uid + * @throws {Error} If customer cannot be get by uid + */ + public async getByUid(uid: string, query?: any): Promise { + return this.customerRepository.findOneByUid(uid, query); + } +} diff --git a/src/services/super-admin/DeedTypesService/DeedTypesService.ts b/src/services/super-admin/DeedTypesService/DeedTypesService.ts new file mode 100644 index 00000000..da71909e --- /dev/null +++ b/src/services/super-admin/DeedTypesService/DeedTypesService.ts @@ -0,0 +1,46 @@ +import { DeedTypes } from "@prisma/client"; +import DeedTypesRepository from "@Repositories/DeedTypesRepository"; +import BaseService from "@Services/BaseService"; +import { DeedType } from "le-coffre-resources/dist/SuperAdmin"; +import { Service } from "typedi"; + +@Service() +export default class DeedTypesService extends BaseService { + constructor( + private deedTypeRepository: DeedTypesRepository, + ) { + super(); + } + + /** + * @description : Get all deed-types + * @throws {Error} If deed-types cannot be get + */ + public async get(query: any): Promise { + return this.deedTypeRepository.findMany(query); + } + + /** + * @description : Create a new deed-type + * @throws {Error} If deed-type cannot be created + */ + public async create(deedTypeEntity: DeedType): Promise { + return this.deedTypeRepository.create(deedTypeEntity); + } + + /** + * @description : Modify a deed-type + * @throws {Error} If deed-type cannot be modifified + */ + public async update(uid: string, deedTypeEntity: DeedType): Promise { + return this.deedTypeRepository.update(uid, deedTypeEntity); + } + + /** + * @description : Get a deedtype by uid + * @throws {Error} If deed-type cannot be get by uid + */ + public async getByUid(uid: string, query?: any) { + return this.deedTypeRepository.findOneByUid(uid, query); + } +} diff --git a/src/services/super-admin/DeedsService/DeedsService.ts b/src/services/super-admin/DeedsService/DeedsService.ts new file mode 100644 index 00000000..93a6c6bd --- /dev/null +++ b/src/services/super-admin/DeedsService/DeedsService.ts @@ -0,0 +1,44 @@ +import { Deeds } from "@prisma/client"; +import DeedsRepository from "@Repositories/DeedsRepository"; +import BaseService from "@Services/BaseService"; +import { Deed } from "le-coffre-resources/dist/SuperAdmin"; +import { Service } from "typedi"; + +@Service() +export default class DeedsService extends BaseService { + constructor(private deedRepository: DeedsRepository) { + super(); + } + + /** + * @description : Get all deeds + * @throws {Error} If deeds cannot be get + */ + public async get(query: any) { + return this.deedRepository.findMany(query); + } + + /** + * @description : Create a new deed with document types + * @throws {Error} If deeds cannot be created + */ + public async create(deed: Deed): Promise { + return this.deedRepository.create(deed); + } + + /** + * @description : Update data of a deed with document types + * @throws {Error} If deeds cannot be updated with document types or one of them + */ + public async update(deeduid: string, deed: Deed): Promise { + return this.deedRepository.update(deeduid, deed); + } + + /** + * @description : Get a deed by uid + * @throws {Error} If deed-type cannot be get by uid + */ + public async getByUid(uid: string, query?: any) { + return this.deedRepository.findOneByUid(uid, query); + } +} diff --git a/src/services/super-admin/DocumentTypesService/DocumentTypesService.ts b/src/services/super-admin/DocumentTypesService/DocumentTypesService.ts new file mode 100644 index 00000000..dacfe17f --- /dev/null +++ b/src/services/super-admin/DocumentTypesService/DocumentTypesService.ts @@ -0,0 +1,44 @@ +import { DocumentTypes } from "@prisma/client"; +import DocumentTypesRepository from "@Repositories/DocumentTypesRepository"; +import BaseService from "@Services/BaseService"; +import { DocumentType } from "le-coffre-resources/dist/SuperAdmin"; +import { Service } from "typedi"; + +@Service() +export default class DocumentTypesService extends BaseService { + constructor(private documentTypeRepository: DocumentTypesRepository) { + super(); + } + + /** + * @description : Get all document-types + * @throws {Error} If document-types cannot be get + */ + public async get(query: any) { + return this.documentTypeRepository.findMany(query); + } + + /** + * @description : Create a new document-type + * @throws {Error} If document-types cannot be created + */ + public async create(documentTypeEntity: DocumentType): Promise { + return this.documentTypeRepository.create(documentTypeEntity); + } + + /** + * @description : Modify a document-type + * @throws {Error} If document-type cannot be modified + */ + public async update(uid: string, documentTypeEntity: DocumentType): Promise { + return this.documentTypeRepository.update(uid, documentTypeEntity); + } + + /** + * @description : Get a document-type by uid + * @throws {Error} If document-type is not found + */ + public async getByUid(uid: string, query?: any) { + return this.documentTypeRepository.findOneByUid(uid, query); + } +} diff --git a/src/services/super-admin/DocumentsService/DocumentsService.ts b/src/services/super-admin/DocumentsService/DocumentsService.ts new file mode 100644 index 00000000..81a0d8bc --- /dev/null +++ b/src/services/super-admin/DocumentsService/DocumentsService.ts @@ -0,0 +1,67 @@ +import { Documents, Prisma } from "@prisma/client"; +import { Document } from "le-coffre-resources/dist/SuperAdmin"; +import DocumentsRepository from "@Repositories/DocumentsRepository"; +import BaseService from "@Services/BaseService"; +import { Service } from "typedi"; + +@Service() +export default class DocumentsService extends BaseService { + constructor(private documentsRepository: DocumentsRepository) { + super(); + } + + /** + * @description : Get all documents + * @throws {Error} If documents cannot be get + */ + public async get(query: any) { + return this.documentsRepository.findMany(query); + } + + /** + * @description : Create a new document + * @throws {Error} If document cannot be created + */ + public async create(document: Document): Promise { + return this.documentsRepository.create(document); + } + + /** + * @description : Create new documents + * @throws {Error} If documents or one of them cannot be created + */ + public async createMany(documents: Document[]): Promise { + return this.documentsRepository.createMany(documents); + } + + /** + * @description : Modify a document + * @throws {Error} If document cannot be modified + */ + public async update(uid: string, document: Document, refused_reason?: string): Promise { + return this.documentsRepository.update(uid, document, refused_reason); + } + + /** + * @description : Delete a document + * @throws {Error} If document cannot be deleted + */ + public async delete(uid: string): Promise { + const documentEntity = await this.documentsRepository.findOneByUid(uid, { files: true }); + + const document = Document.hydrate(documentEntity, { strategy: "excludeAll" }); + + if (document.files && document.files.length !== 0) { + throw new Error("Can't delete a document with file"); + } + return this.documentsRepository.delete(uid); + } + + /** + * @description : Get a document by uid + * @throws {Error} If document cannot be get by uid + */ + public async getByUid(uid: string, query?: any) { + return this.documentsRepository.findOneByUid(uid, query); + } +} diff --git a/src/services/super-admin/OfficeFoldersService/OfficeFoldersService.ts b/src/services/super-admin/OfficeFoldersService/OfficeFoldersService.ts new file mode 100644 index 00000000..128070e4 --- /dev/null +++ b/src/services/super-admin/OfficeFoldersService/OfficeFoldersService.ts @@ -0,0 +1,69 @@ +import { OfficeFolders } from ".prisma/client"; +import OfficeFoldersRepository from "@Repositories/OfficeFoldersRepository"; +import BaseService from "@Services/BaseService"; +import { OfficeFolder } from "le-coffre-resources/dist/SuperAdmin"; +import { Service } from "typedi"; +import DeedTypesService from "../DeedTypesService/DeedTypesService"; +import DeedsRepository from "@Repositories/DeedsRepository"; + + +@Service() +export default class OfficeFoldersService extends BaseService { + constructor( + private officeFoldersRepository: OfficeFoldersRepository, + private deedTypeService: DeedTypesService, + private deedRepository: DeedsRepository + ) { + super(); + } + + /** + * @description : Get all folders + * @throws {Error} If folders cannot be get + */ + public async get(query: any) { + return this.officeFoldersRepository.findMany(query); + } + + /** + * @description : Create a new folder + * @throws {Error} If folder cannot be created + */ + public async create(officeFolderEntity: OfficeFolder): Promise { + const deedType = await this.deedTypeService.getByUid(officeFolderEntity.deed!.deed_type!.uid!); + if(deedType.archived_at) throw new Error('deed type is archived'); + const deed = await this.deedRepository.create(officeFolderEntity.deed!); + officeFolderEntity.deed!.uid = deed.uid; + return this.officeFoldersRepository.create(officeFolderEntity); + } + + /** + * @description : Modify a folder + * @throws {Error} If folder cannot be modified + */ + public async update(officeFolderuid: string, officeFolderEntity: OfficeFolder): Promise { + return this.officeFoldersRepository.update(officeFolderuid, officeFolderEntity); + } + + /** + * @description : Get a folder by uid + * @throws {Error} If folder cannot be get by uid + */ + public async getByUid(uid: string, query?: any) { + return this.officeFoldersRepository.findOneByUid(uid, query); + } + + /** + * @description : Delete a folder + * @throws {Error} If document cannot be deleted + */ + public async delete(uid: string): Promise { + const officeFolderEntity = await this.officeFoldersRepository.findOneByUid(uid, { office_folder_has_customers: true }); + const officeFolder = OfficeFolder.hydrate(officeFolderEntity, { strategy: "excludeAll" }); + + if (officeFolder.office_folder_has_customers && officeFolder.office_folder_has_customers.length !== 0) { + throw new Error("This folder is used by customers"); + } + return this.officeFoldersRepository.delete(uid); + } +} diff --git a/src/services/super-admin/OfficesService/OfficesService.ts b/src/services/super-admin/OfficesService/OfficesService.ts new file mode 100644 index 00000000..4de766be --- /dev/null +++ b/src/services/super-admin/OfficesService/OfficesService.ts @@ -0,0 +1,44 @@ +import { Offices } from "@prisma/client"; +import OfficesRepository from "@Repositories/OfficesRepository"; +import BaseService from "@Services/BaseService"; +import { Office as OfficeRessource } from "le-coffre-resources/dist/SuperAdmin"; +import { Service } from "typedi"; + +@Service() +export default class OfficesService extends BaseService { + constructor(private officeRepository: OfficesRepository) { + super(); + } + + /** + * @description : Get all offices + * @throws {Error} If offices cannot be get + */ + public async get(query: any): Promise { + return this.officeRepository.findMany(query); + } + + /** + * @description : Create a new office + * @throws {Error} If office cannot be created + */ + public async create(officeEntity: OfficeRessource): Promise { + return this.officeRepository.create(officeEntity); + } + + /** + * @description : Modify an office + * @throws {Error} If office cannot be modified + */ + public async update(uid: string, officeEntity: OfficeRessource): Promise { + return this.officeRepository.update(uid, officeEntity); + } + + /** + * @description : Get a office by uid + * @throws {Error} If office cannot be get + */ + public async getByUid(uid: string, query?: any): Promise { + return this.officeRepository.findOneByUid(uid, query); + } +} diff --git a/src/services/super-admin/UsersService/UsersService.ts b/src/services/super-admin/UsersService/UsersService.ts new file mode 100644 index 00000000..fcdbf428 --- /dev/null +++ b/src/services/super-admin/UsersService/UsersService.ts @@ -0,0 +1,45 @@ +import BaseService from "@Services/BaseService"; +import "reflect-metadata"; +import { Service } from "typedi"; +import UsersRepository from "@Repositories/UsersRepository"; +import User from "le-coffre-resources/dist/SuperAdmin"; +import {Prisma, Users } from "@prisma/client"; + +@Service() +export default class UsersService extends BaseService { + constructor(private userRepository: UsersRepository) { + super(); + } + + /** + * @description : Get all users + * @throws {Error} If users cannot be get + */ + public get(query: Prisma.UsersFindManyArgs): Promise { + return this.userRepository.findMany(query); + } + + /** + * @description : Create a user + * @throws {Error} If user couldn't be created + */ + public create(userEntity: User): Promise { + return this.userRepository.create(userEntity); + } + + /** + * @description : Modify a user + * @throws {Error} If user modification failed + */ + public update(uid: string, userEntity: User): Promise { + return this.userRepository.update(uid, userEntity); + } + + /** + * @description : Get a user by uid + * @throws {Error} If user cannot be get by uid + */ + public getByUid(uid: string, query?: any): Promise { + return this.userRepository.findOneByUid(uid, query); + } +} diff --git a/src/test/config/Init.ts b/src/test/config/Init.ts new file mode 100644 index 00000000..033fc8f1 --- /dev/null +++ b/src/test/config/Init.ts @@ -0,0 +1,121 @@ +import { Customers, DeedTypes, DocumentTypes, ECivility, ECustomerStatus, Offices, PrismaClient, Users } from "@prisma/client"; +import User, { Customer, DeedType, DocumentType, Office } from "le-coffre-resources/dist/SuperAdmin"; + +const prisma = new PrismaClient(); + +export const initOffice = (office: Office): Promise => { + return prisma.offices.create({ + data: { + idNot: office.idNot, + name: office.name, + crpcen: office.crpcen, + address: { + create: { + address: office.address!.address, + zip_code: office.address!.zip_code, + city: office.address!.city, + }, + }, + }, + }); +}; + +export const initDocumentType = (documentType: DocumentType, office: Office): Promise => { + return prisma.documentTypes.create({ + data: { + name: documentType.name, + public_description: documentType.public_description, + private_description: documentType.private_description, + archived_at: null, + office_uid: office.uid!, + }, + }); +}; + +export const initDeedType = (deedType: DeedType, office: Office, documentTypes?: string[]): Promise => { + return prisma.deedTypes.create({ + data: { + name: deedType.name, + description: deedType.description, + archived_at: null, + office_uid: office.uid!, + deed_type_has_document_types: { + createMany: { + data: documentTypes!.map((documentType) => ({ + document_type_uid: documentType, + })), + skipDuplicates: true, + }, + }, + }, + }); +}; + +export const initCustomers = (customer: Customer): Promise => { + return prisma.customers.create({ + data: { + status: ECustomerStatus.PENDING, + contact: { + create: { + first_name: customer.contact!.first_name, + last_name: customer.contact!.last_name, + email: customer.contact!.email, + phone_number: customer.contact!.phone_number, + cell_phone_number: customer.contact!?.cell_phone_number, + civility: ECivility[customer.contact!.civility as keyof typeof ECivility], + address: { + create: { + address: customer.contact!.address!.address, + zip_code: customer.contact!.address!.zip_code, + city: customer.contact!.address!.city, + }, + }, + }, + }, + }, + }); +}; + +export const initUsers = (user: User): Promise => { + return prisma.users.create({ + data: { + idNot: user.idNot, + office_membership: { + connectOrCreate: { + where: { + idNot: user.office_membership!.idNot, + }, + create: { + idNot: user.office_membership!.idNot, + name: user.office_membership!.name, + crpcen: user.office_membership!.crpcen, + address: { + create: { + address: user.office_membership!.address!.address, + zip_code: user.office_membership!.address!.zip_code, + city: user.office_membership!.address!.city, + }, + }, + }, + }, + }, + contact: { + create: { + first_name: user.contact!.first_name, + last_name: user.contact!.last_name, + email: user.contact!.email, + phone_number: user.contact!.phone_number, + cell_phone_number: user.contact!.cell_phone_number, + civility: ECivility[user.contact!.civility as keyof typeof ECivility], + address: { + create: { + address: user.contact!.address!.address, + zip_code: user.contact!.address!.zip_code, + city: user.contact!.address!.city, + }, + }, + }, + }, + }, + }); +}; diff --git a/src/test/config/MockedData.ts b/src/test/config/MockedData.ts new file mode 100644 index 00000000..051fe912 --- /dev/null +++ b/src/test/config/MockedData.ts @@ -0,0 +1,242 @@ +import { EOfficeStatus } from "le-coffre-resources/dist/Customer/Office"; +import User, { Address, Contact, Office, DeedType, DocumentType, Customer, OfficeFolder, Deed } from "le-coffre-resources/dist/SuperAdmin"; + +export const userAddress: Address = { + address: "1 avenue des champs élysées", + zip_code: 75008, + city: "paris", + created_at: null, + updated_at: null, +}; + +export const userAddress_: Address = { + address: "1 rue Victor Hugo", + zip_code: 75001, + city: "paris", + created_at: null, + updated_at: null, +}; + +export const userContact: Contact = { + first_name: "Philippe", + last_name: "le Bel", + address: userAddress, + email: "philippe.lebel@notaires.fr", + phone_number: "+33101020304", + cell_phone_number: "+33605060708", + civility: "MALE", + created_at: null, + updated_at: null, +}; + +export const userContact_: Contact = { + first_name: "Saint", + last_name: "Louise", + address: userAddress_, + email: "saint.louise@notaires.fr", + phone_number: "+33105060708", + cell_phone_number: "+33601020304", + civility: "FEMALE", + created_at: null, + updated_at: null, +}; + +export const customerContact: Contact = { + first_name: "John", + last_name: "Doe", + address: userAddress, + email: "john.doe@customer.fr", + phone_number: "+3313847505", + cell_phone_number: "+3313847505", + civility: "MALE", + created_at: null, + updated_at: null, +}; + +export const customerContact_: Contact = { + first_name: "Jocelyne", + last_name: "Doe", + address: userAddress, + email: "jocelyne.doe@customer.fr", + phone_number: "+331384894505", + cell_phone_number: "+331384894505", + civility: "FEMALE", + created_at: null, + updated_at: null, +}; + +export const officeAddress: Address = { + address: "1 rue Rivoli", + zip_code: 75001, + city: "paris", + created_at: null, + updated_at: null, +}; + +export const officeAddress_: Address = { + address: "1 rue de la paix", + zip_code: 75008, + city: "paris", + created_at: null, + updated_at: null, +}; + +export const office: Office = { + idNot: "123456789", + name: "first office", + crpcen: "0123456789CRPCEN", + office_status: EOfficeStatus.ACTIVATED, + address: officeAddress, + created_at: null, + updated_at: null, +}; + +export const office_: Office = { + idNot: "789101112", + name: "second office", + crpcen: "987654321CRPCEN", + office_status: EOfficeStatus.DESACTIVATED, + address: officeAddress_, + created_at: null, + updated_at: null, +}; + +export const user: User = { + idNot: "123456_123456789", + contact: userContact, + office_membership: office, + created_at: null, + updated_at: null, +}; + +export const user_: User = { + idNot: "654321_789101112", + contact: userContact_, + office_membership: office_, + created_at: null, + updated_at: null, +}; + +export const documentType: DocumentType = { + name: "Identity card", + public_description: "your ID card delivered by your country of residence", + private_description: "verify if this ID card is legit", + archived_at: null, + office: office, + created_at: null, + updated_at: null, +}; + +export const documentType_: DocumentType = { + name: "Electricity bill", + public_description: "an electricity bill payed within the last 3 months", + private_description: "verify if this electricity company is legit", + archived_at: null, + office: office, + created_at: null, + updated_at: null, +}; + +export const deedType: DeedType = { + name: "Wedding", + description: "we assume wedding involve two people", + archived_at: null, + office: office, + created_at: null, + updated_at: null, + deed_type_has_document_types: [ + { + document_type: documentType, + deed_type: new DeedType(), + created_at: null, + updated_at: null, + }, + ], +}; + +export const deedType_: DeedType = { + name: "Inheritance", + description: "we assume inheritance involve two people", + archived_at: null, + office: office_, + created_at: null, + updated_at: null, +}; + +export const deed: Deed = { + deed_type: deedType, + created_at: null, + updated_at: null, +}; + +export const deed_: Deed = { + deed_type: deedType_, + created_at: null, + updated_at: null, +}; + +export const customer: Customer = { + contact: customerContact, + status: "PENDING", + created_at: null, + updated_at: null, +}; + +export const customer_: Customer = { + contact: customerContact_, + status: "ERRONED", + created_at: null, + updated_at: null, +}; + +export const officeFolder: OfficeFolder = { + name: "Dossier 1234567", + folder_number: "1234567", + description: "Dossier de mr Dupont", + archived_description: null, + status: "ARCHIVED", + deed: deed, + office: office, + office_folder_has_customers: [ + { + customer: customer, + office_folder: new OfficeFolder(), + created_at: null, + updated_at: null, + }, + { + customer: customer_, + office_folder: new OfficeFolder(), + created_at: null, + updated_at: null, + }, + ], + office_folder_has_stakeholder: [ + { + user_stakeholder: user, + office_folder: new OfficeFolder(), + created_at: null, + updated_at: null, + }, + { + user_stakeholder: user_, + office_folder: new OfficeFolder(), + created_at: null, + updated_at: null, + }, + ], + created_at: null, + updated_at: null, +}; + +export const officeFolder_: OfficeFolder = { + name: "Dossier 89101112", + folder_number: "89101112", + description: "Dossier de mme Dutunnel", + archived_description: null, + status: "LIVE", + deed: deed_, + office: office_, + created_at: null, + updated_at: null, +}; diff --git a/src/test/services/super-admin/CustomersService.test.ts b/src/test/services/super-admin/CustomersService.test.ts new file mode 100644 index 00000000..7ea5944c --- /dev/null +++ b/src/test/services/super-admin/CustomersService.test.ts @@ -0,0 +1,166 @@ +import "module-alias/register"; +import "reflect-metadata"; +import { Customer } from "le-coffre-resources/dist/SuperAdmin"; +import CustomersService from "@Services/super-admin/CustomersService/CustomersService"; +import { PrismaClient } from "@prisma/client"; +import { customer, customerContact, customerContact_, customer_ } from "@Test/config/MockedData"; +import Container from "typedi"; +import CustomersRepository from "@Repositories/CustomersRepository"; + +const prisma = new PrismaClient(); + +const CustomersServiceTest = new CustomersService(Container.get(CustomersRepository)); + +afterAll(async () => { + /* + * Clean database after all tests execution. + * Due to cascade deletion, if addresses are deleted, all items following tables are dropped: contacts, customers, offices + */ + const deleteAddresses = prisma.addresses.deleteMany(); + await prisma.$transaction([deleteAddresses]); + await prisma.$disconnect(); +}); + +describe("test create function", () => { + it("should create a new customer", async () => { + const customerCreated = await CustomersServiceTest.create(customer); + + expect(customerCreated?.status).toEqual("PENDING"); + + // verify if customer contact is created in db + const contactCreated = await prisma.contacts.findUnique({ where: { uid: customerCreated.contact_uid } }); + expect(contactCreated?.first_name).toEqual(customer.contact!.first_name); + expect(contactCreated?.last_name).toEqual(customer.contact!.last_name); + expect(contactCreated?.cell_phone_number).toEqual(customer.contact!.cell_phone_number); + expect(contactCreated?.phone_number).toEqual(customer.contact!.phone_number); + expect(contactCreated?.civility).toEqual(customer.contact!.civility); + expect(contactCreated?.email).toEqual(customer.contact!.email); + + // verify if customer address is created in db + const addressForContactCreated = await prisma.addresses.findUnique({ where: { uid: contactCreated?.address_uid! } }); + expect(addressForContactCreated?.address).toEqual(customer.contact!.address?.address); + expect(addressForContactCreated?.zip_code).toEqual(customer.contact!.address?.zip_code); + expect(addressForContactCreated?.city).toEqual(customer.contact!.address?.city); + }); + + it("should not create an customer already created", async () => { + // try to create the same customer + async function duplicateCustomer() { + await CustomersServiceTest.create(customer); + } + await expect(duplicateCustomer).rejects.toThrow(); + }); + + it("should not create an new customer with an email already created", async () => { + let newCustomer: Customer = JSON.parse(JSON.stringify(customer_)); + newCustomer.contact!.email = customerContact.email; + + // try to create a new customer with already used email + async function createCustomerWithDuplicateEmail() { + await CustomersServiceTest.create(newCustomer); + } + await expect(createCustomerWithDuplicateEmail).rejects.toThrow(); + }); + + it("should not create an customer with an phone number already created", async () => { + let newCustomer: Customer = JSON.parse(JSON.stringify(customer_)); + newCustomer.contact!.cell_phone_number = customerContact.cell_phone_number; + + // try to create a new customer with already used cellphone number + async function duplicateCustomer() { + await CustomersServiceTest.create(newCustomer); + } + await expect(duplicateCustomer).rejects.toThrow(); + }); + + it("should create an new customer if unique attributes differ from existing customers", async () => { + let newCustomer: Customer = JSON.parse(JSON.stringify(customer)); + newCustomer.contact!.email = customerContact_.email; + newCustomer.contact!.cell_phone_number = customerContact_.cell_phone_number; + + const customerCreated = await CustomersServiceTest.create(newCustomer); + + expect(customerCreated?.status).toEqual("PENDING"); + + // verify if customer_ contact is created in db + const contactCreated = await prisma.contacts.findUnique({ where: { uid: customerCreated.contact_uid } }); + expect(contactCreated?.first_name).toEqual(customer.contact!.first_name); + expect(contactCreated?.last_name).toEqual(customer.contact!.last_name); + expect(contactCreated?.cell_phone_number).toEqual(customer_.contact!.cell_phone_number); + expect(contactCreated?.phone_number).toEqual(customer.contact!.phone_number); + expect(contactCreated?.civility).toEqual(customer.contact!.civility); + expect(contactCreated?.email).toEqual(customer_.contact!.email); + + // verify if customer_ address is created in db + const addressForContactCreated = await prisma.addresses.findUnique({ where: { uid: contactCreated?.address_uid! } }); + expect(addressForContactCreated?.address).toEqual(customer.contact!.address?.address); + expect(addressForContactCreated?.zip_code).toEqual(customer.contact!.address?.zip_code); + expect(addressForContactCreated?.city).toEqual(customer.contact!.address?.city); + }); +}); + +describe("test update function", () => { + it("should update an customer's data", async () => { + const customerCreated = await prisma.customers.findFirstOrThrow({ where: { contact: { email: customer_.contact!.email } } }); + + // update the last customer created with his own new office and own contact + const updatedCustomer = await CustomersServiceTest.update(customerCreated.uid, customer_); + + expect(updatedCustomer?.status).toEqual("ERRONED"); + + // verify if customer_ contact is created in db + const existingContact = await prisma.contacts.findUnique({ where: { uid: updatedCustomer.contact_uid } }); + expect(existingContact?.first_name).toEqual(customer_.contact!.first_name); + expect(existingContact?.last_name).toEqual(customer_.contact!.last_name); + expect(existingContact?.cell_phone_number).toEqual(customer_.contact!.cell_phone_number); + expect(existingContact?.phone_number).toEqual(customer_.contact!.phone_number); + expect(existingContact?.civility).toEqual(customer_.contact!.civility); + expect(existingContact?.email).toEqual(customer_.contact!.email); + + // verify if customer_ address is created in db + const addressForExistingContact = await prisma.addresses.findUnique({ where: { uid: existingContact?.address_uid! } }); + expect(addressForExistingContact?.address).toEqual(customer_.contact!.address?.address); + expect(addressForExistingContact?.zip_code).toEqual(customer_.contact!.address?.zip_code); + expect(addressForExistingContact?.city).toEqual(customer_.contact!.address?.city); + }); + + it("should not update an customer with an email already used", async () => { + const customerUid = (await prisma.customers.findFirstOrThrow({ where: { contact: { email: customer_.contact!.email } } })).uid; + let updatedCustomer: Customer = JSON.parse(JSON.stringify(customer_)); + updatedCustomer.contact!.email = customerContact.email; + + // try to create a new customer with already used email + async function updateCustomerWithDuplicateEmail() { + await CustomersServiceTest.update(customerUid, updatedCustomer); + } + await expect(updateCustomerWithDuplicateEmail).rejects.toThrow(); + }); + + it("should not update an customer with an phone number already used", async () => { + const customerUid = (await prisma.customers.findFirstOrThrow({ where: { contact: { email: customer_.contact!.email } } })).uid; + let updatedCustomer: Customer = JSON.parse(JSON.stringify(customer_)); + updatedCustomer.contact!.cell_phone_number = customerContact.cell_phone_number; + + // try to create a new customer with already used email + async function updateCustomerWithDuplicateEmail() { + await CustomersServiceTest.update(customerUid, updatedCustomer); + } + await expect(updateCustomerWithDuplicateEmail).rejects.toThrow(); + }); +}); + +describe("test get function", () => { + it("should return an array of Customers", async () => { + const req = {} + const customers = await CustomersServiceTest.get(req); + + // verify result typing + expect(customers).toBeInstanceOf(Array); + expect(customers.length).toEqual(2); + + // verify result content + const customersCreated = await prisma.customers.findMany(); + expect(customers).toContainEqual(customersCreated[0]); + expect(customers).toContainEqual(customersCreated[1]); + }); +}); diff --git a/src/test/services/super-admin/DeedService.test.ts b/src/test/services/super-admin/DeedService.test.ts new file mode 100644 index 00000000..6e67e3fd --- /dev/null +++ b/src/test/services/super-admin/DeedService.test.ts @@ -0,0 +1,179 @@ +import "module-alias/register"; +import "reflect-metadata"; +import { Deed } from "le-coffre-resources/dist/SuperAdmin"; +import DeedService from "@Services/super-admin/DeedsService/DeedsService"; +import { PrismaClient } from "prisma/prisma-client"; +import { deed, deedType, documentType, documentType_, office } from "@Test/config/MockedData"; +import DeedsRepository from "@Repositories/DeedsRepository"; +import Container from "typedi"; +import { initDeedType, initDocumentType, initOffice } from "@Test/config/Init"; + +const prisma = new PrismaClient(); + +const DeedServiceTest = new DeedService(Container.get(DeedsRepository)); + +beforeAll(async () => { + office.uid = (await initOffice(office)).uid; + documentType.uid = (await initDocumentType(documentType, office)).uid; + documentType_.uid = (await initDocumentType(documentType_, office)).uid; + deedType.uid = (await initDeedType(deedType, office, [documentType.uid])).uid; +}); + +afterAll(async () => { + const deleteDeedTypes = prisma.deedTypes.deleteMany(); + const deleteOffices = prisma.offices.deleteMany(); + await prisma.$transaction([deleteDeedTypes, deleteOffices]); + await prisma.$disconnect(); +}); + +describe("test create function", () => { + it("should not create a new deed if deed type is unknown", async () => { + let deedWithoutDeedTypeUid: Deed = JSON.parse(JSON.stringify(deed)); + deedWithoutDeedTypeUid.deed_type!.uid = "random uid"; + // try to create a new deed with unknown deed type + async function createDeedWithUnknownDeedType() { + await DeedServiceTest.create(deedWithoutDeedTypeUid); + } + await expect(createDeedWithUnknownDeedType).rejects.toThrow(); + }); + + it("should create a new deed based on existing deed type", async () => { + let deedWithDeedTypeUid: Deed = JSON.parse(JSON.stringify(deed)); + deedWithDeedTypeUid.deed_type!.uid = deedType.uid; + const deedCreated = await DeedServiceTest.create(deedWithDeedTypeUid); + + expect(deedCreated.deed_type_uid).toEqual(deedType.uid); + }); + + it("should have by default the same document types as its deed type ", async () => { + const deedWithDocumentTypes = await prisma.deeds.findFirstOrThrow({ include: { deed_has_document_types: true } }); + expect(deedWithDocumentTypes.deed_has_document_types.length).toEqual(1); + expect(deedWithDocumentTypes.deed_has_document_types[0]?.document_type_uid).toEqual(documentType.uid); + }); + + it("should create a the same deed based on existing deed type", async () => { + let deedWithDeedTypeUid: Deed = JSON.parse(JSON.stringify(deed)); + deedWithDeedTypeUid.deed_type!.uid = deedType.uid; + const deedCreated = await DeedServiceTest.create(deedWithDeedTypeUid); + + expect(deedCreated.deed_type_uid).toEqual(deedType.uid); + }); + + it("should not create a new deed based on archivated deed type", async () => { + let deedArchivated: Deed = JSON.parse(JSON.stringify(deed)); + deedArchivated.deed_type!.uid = deedType.uid; + + await prisma.deedTypes.update({ + where: { uid: deedType.uid }, + data: { + archived_at: new Date(Date.now()), + }, + }); + + // try to create a new deed with archivated deed type + async function createDeedWithArchivatedDeedType() { + await DeedServiceTest.create(deedArchivated); + } + await expect(createDeedWithArchivatedDeedType).rejects.toThrow("deed type is archived"); + }); +}); + +describe("test update function", () => { + it("should add document types to a deed", async () => { + const deedUid = (await prisma.deeds.findFirstOrThrow({ where: { deed_type_uid: deedType.uid } })).uid; + let deedToUpdate: Deed = JSON.parse(JSON.stringify(deed)); + + deedToUpdate.deed_has_document_types = [ + { + document_type: documentType, + deed: new Deed(), + created_at: null, + updated_at: null, + }, + { + document_type: documentType_, + deed: new Deed(), + created_at: null, + updated_at: null, + }, + ]; + + await DeedServiceTest.update(deedUid, deedToUpdate); + + const deedUpdated = await prisma.deeds.findFirstOrThrow({ + where: { + uid: deedUid, + }, + include: { + deed_has_document_types: true, + }, + }); + expect(deedUpdated.deed_has_document_types.length).toEqual(2); + }); + + it("should not add document types to a deed type that already has those document types ", async () => { + const deedUid = (await prisma.deeds.findFirstOrThrow({ where: { deed_type_uid: deedType.uid } })).uid; + let deedToUpdate: Deed = JSON.parse(JSON.stringify(deed)); + + deedToUpdate.deed_has_document_types = [ + { + document_type: documentType, + deed: new Deed(), + created_at: null, + updated_at: null, + }, + { + document_type: documentType_, + deed: new Deed(), + created_at: null, + updated_at: null, + }, + ]; + + await DeedServiceTest.update(deedUid, deedToUpdate); + + const deedUpdated = await prisma.deeds.findFirstOrThrow({ + where: { + uid: deedUid, + }, + include: { + deed_has_document_types: true, + }, + }); + expect(deedUpdated.deed_has_document_types.length).toEqual(2); + }); + + it("should delete document types from a deed", async () => { + const deedUid = (await prisma.deeds.findFirstOrThrow({ where: { deed_type_uid: deedType.uid } })).uid; + let deedToUpdate: Deed = JSON.parse(JSON.stringify(deed)); + + // set relation between deed and document types empty + deedToUpdate.deed_has_document_types = []; + + await DeedServiceTest.update(deedUid, deedToUpdate); + + const deedUpdated = await prisma.deeds.findFirstOrThrow({ + where: { + uid: deedUid, + }, + include: { + deed_has_document_types: true, + }, + }); + expect(deedUpdated.deed_has_document_types.length).toEqual(0); + }); +}); + +describe("test get function", () => { + it("should return an array of Deeds", async () => { + const deeds = await DeedServiceTest.get({}); + + // verify result typing + expect(deeds).toBeInstanceOf(Array); + expect(deeds.length).toEqual(2); + + // verify result content + expect(deeds[0]?.deed_type_uid).toEqual(deedType.uid); + expect(deeds[1]?.deed_type_uid).toEqual(deedType.uid); + }); +}); diff --git a/src/test/services/super-admin/DeedTypesService.test.ts b/src/test/services/super-admin/DeedTypesService.test.ts new file mode 100644 index 00000000..af923ad1 --- /dev/null +++ b/src/test/services/super-admin/DeedTypesService.test.ts @@ -0,0 +1,323 @@ +import "module-alias/register"; +import "reflect-metadata"; +import { DeedType } from "le-coffre-resources/dist/SuperAdmin"; +import DeedTypeService from "@Services/super-admin/DeedTypesService/DeedTypesService"; +import { PrismaClient } from "prisma/prisma-client"; +import { deedType, deedType_, documentType, documentType_, office, office_ } from "@Test/config/MockedData"; +import DeedTypesRepository from "@Repositories/DeedTypesRepository"; +import Container from "typedi"; +import { initDocumentType, initOffice } from "@Test/config/Init"; + +const prisma = new PrismaClient(); + +const DeedTypeServiceTest = new DeedTypeService(Container.get(DeedTypesRepository)); + +beforeAll(async () => { + office.uid = (await initOffice(office)).uid; + office_.uid = (await initOffice(office_)).uid; + documentType.uid = (await initDocumentType(documentType, office)).uid; + documentType_.uid = (await initDocumentType(documentType_, office)).uid; +}); + +afterAll(async () => { + const deleteDeedTypes = prisma.deedTypes.deleteMany(); + const deleteOffices = prisma.offices.deleteMany(); + await prisma.$transaction([deleteDeedTypes, deleteOffices]); + await prisma.$disconnect(); +}); + +describe("test create function", () => { + it("should not create a new deed type if office is unknown", async () => { + let deedTypeWithoutOfficeUid: DeedType = JSON.parse(JSON.stringify(deedType)); + deedTypeWithoutOfficeUid.office!.uid = "random uid"; + // try to create a new deed type with unknown office + async function createDeedTypeWithUnknownOffice() { + await DeedTypeServiceTest.create(deedTypeWithoutOfficeUid); + } + await expect(createDeedTypeWithUnknownOffice).rejects.toThrow(); + }); + + it("should create a new deed type", async () => { + const deedTypeCreated = await DeedTypeServiceTest.create(deedType); + + expect(deedTypeCreated.name).toEqual(deedType.name); + expect(deedTypeCreated.description).toEqual(deedType.description); + expect(deedTypeCreated.archived_at).toBeNull(); + expect(deedTypeCreated.office_uid).toEqual(office.uid); + }); + + it("should not create a new deed type with a name already used for a given office", async () => { + let deedTypeWithSameNameAndOffice: DeedType = JSON.parse(JSON.stringify(deedType_)); + deedTypeWithSameNameAndOffice.office! = office; + deedTypeWithSameNameAndOffice.name = deedType.name; + + async function createDeedTypeWithSameNameAndOffice() { + await DeedTypeServiceTest.create(deedTypeWithSameNameAndOffice); + } + await expect(createDeedTypeWithSameNameAndOffice).rejects.toThrow(); + }); + + it("should create the same deed type for a different office", async () => { + let deedTypeDuplicatedForNewOffice: DeedType = JSON.parse(JSON.stringify(deedType)); + deedTypeDuplicatedForNewOffice.office! = office_; + + const deedTypeCreated = await DeedTypeServiceTest.create(deedTypeDuplicatedForNewOffice); + + expect(deedTypeCreated.name).toEqual(deedType.name); + expect(deedTypeCreated.description).toEqual(deedType.description); + expect(deedTypeCreated.archived_at).toBeNull(); + expect(deedTypeCreated.office_uid).toEqual(office_.uid); + }); + + it("should create the a new deed type version with a different name for a given office", async () => { + let deedTypeWithSameDescription: DeedType = JSON.parse(JSON.stringify(deedType)); + deedTypeWithSameDescription.name = deedType_.name; + + const deedTypeCreated = await DeedTypeServiceTest.create(deedTypeWithSameDescription); + + expect(deedTypeCreated.name).toEqual(deedType_.name); + expect(deedTypeCreated.description).toEqual(deedType.description); + expect(deedTypeCreated.archived_at).toBeNull(); + expect(deedTypeCreated.office_uid).toEqual(office.uid); + }); +}); + +describe("test update function", () => { + it("should update a deed type data", async () => { + const deedTypeCreated = await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType_.name, office_uid: office.uid } }); + + expect(deedTypeCreated.name).toEqual(deedType_.name); + expect(deedTypeCreated.description).toEqual(deedType.description); + expect(deedTypeCreated.archived_at).toBeNull(); + expect(deedTypeCreated.office_uid).toEqual(deedType.office!.uid); + + let deedTypeWithNewDescription: DeedType = JSON.parse(JSON.stringify(deedType_)); + deedTypeWithNewDescription.office! = office; + + // update the last deed type created with his the right description + const deedTypeUpdated = await DeedTypeServiceTest.update(deedTypeCreated.uid, deedTypeWithNewDescription); + + expect(deedTypeUpdated.name).toEqual(deedType_.name); + expect(deedTypeUpdated.description).toEqual(deedType_.description); + expect(deedTypeUpdated.archived_at).toBeNull(); + expect(deedTypeUpdated.office_uid).toEqual(deedType.office!.uid); + }); + + it("should not update a deed type name with an already used name for given office", async () => { + const deedTypeUid = (await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType_.name, office_uid: office.uid } })).uid; + let deedTypeWithSameNameAndOffice: DeedType = JSON.parse(JSON.stringify(deedType_)); + deedTypeWithSameNameAndOffice.office!.uid = office.uid; + deedTypeWithSameNameAndOffice.name = deedType.name; + + // update the last deed type created with his the right description + async function updateDocumentTypeWithSameName() { + await DeedTypeServiceTest.update(deedTypeUid, deedTypeWithSameNameAndOffice); + } + await expect(updateDocumentTypeWithSameName).rejects.toThrow(); + }); + + it("should not update a deed type office membership if the office already have this document type", async () => { + const deedTypeUid = (await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType_.name, office_uid: office.uid } })).uid; + let deedTypeWithSameNameAndOffice: DeedType = JSON.parse(JSON.stringify(deedType_)); + deedTypeWithSameNameAndOffice.office!.uid = office.uid; + deedTypeWithSameNameAndOffice.name = deedType.name; + + // try to duplicate deed type in a given office + async function updateDocumentTypeWithduplicatedName() { + await DeedTypeServiceTest.update(deedTypeUid, deedTypeWithSameNameAndOffice); + } + await expect(updateDocumentTypeWithduplicatedName).rejects.toThrow(); + }); + + it("should update a deed type office membership", async () => { + const deedTypeCreated = await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType_.name, office_uid: office.uid } }); + + expect(deedTypeCreated.name).toEqual(deedType_.name); + expect(deedTypeCreated.description).toEqual(deedType_.description); + expect(deedTypeCreated.archived_at).toBeNull(); + expect(deedTypeCreated.office_uid).toEqual(office.uid); + + // update the last deed type updated with a new office membership + const deedTypeUpdated = await DeedTypeServiceTest.update(deedTypeCreated.uid, deedType_); + + expect(deedTypeUpdated.name).toEqual(deedType_.name); + expect(deedTypeUpdated.description).toEqual(deedType_.description); + expect(deedTypeUpdated.archived_at).toBeNull(); + expect(deedTypeUpdated.office_uid).toEqual(deedType_.office!.uid); + }); + + it("should archivate a deed type", async () => { + const deedTypeCreated = await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType_.name, office_uid: office_.uid } }); + + expect(deedTypeCreated.name).toEqual(deedType_.name); + expect(deedTypeCreated.description).toEqual(deedType_.description); + expect(deedTypeCreated.archived_at).toBeNull(); + expect(deedTypeCreated.office_uid).toEqual(deedType_.office!.uid); + + let deedTypeArchivated: DeedType = JSON.parse(JSON.stringify(deedType_)); + const currentDate = new Date(Date.now()); + deedTypeArchivated.archived_at = new Date(Date.now()); + + // archivate a deed type by giving a non null date for archivated_at attribute + const deedTypeUpdated = await DeedTypeServiceTest.update(deedTypeCreated.uid, deedTypeArchivated); + + expect(deedTypeUpdated.name).toEqual(deedType_.name); + expect(deedTypeUpdated.description).toEqual(deedType_.description); + expect(deedTypeUpdated.archived_at).toEqual(currentDate); + expect(deedTypeUpdated.office_uid).toEqual(office_.uid); + }); + + it("should unarchivate a deed type", async () => { + const deedTypeCreated = await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType_.name, office_uid: office_.uid } }); + + expect(deedTypeCreated.name).toEqual(deedType_.name); + expect(deedTypeCreated.description).toEqual(deedType_.description); + expect(deedTypeCreated.archived_at).not.toBeNull(); + expect(deedTypeCreated.office_uid).toEqual(deedType_.office!.uid); + + // unarchivate a deed type by giving a null date for archivated_at attribute + const deedTypeUpdated = await DeedTypeServiceTest.update(deedTypeCreated.uid, deedType_); + + expect(deedTypeUpdated.name).toEqual(deedType_.name); + expect(deedTypeUpdated.description).toEqual(deedType_.description); + expect(deedTypeUpdated.archived_at).toBeNull(); + expect(deedTypeUpdated.office_uid).toEqual(office_.uid); + }); + + it("should add document types to a deed type", async () => { + const deedTypeUid = (await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType.name, office_uid: office.uid } })).uid; + let deedTypeToUpdate: DeedType = JSON.parse(JSON.stringify(deedType)); + + deedTypeToUpdate.deed_type_has_document_types = [ + { + document_type: documentType, + deed_type: new DeedType(), + created_at: null, + updated_at: null, + }, + { + document_type: documentType_, + deed_type: new DeedType(), + created_at: null, + updated_at: null, + }, + ]; + + await DeedTypeServiceTest.update(deedTypeUid, deedTypeToUpdate); + + const deedTypeUpdated = await prisma.deedTypes.findFirstOrThrow({ + where: { + uid: deedTypeUid, + }, + include: { + deed_type_has_document_types: true, + }, + }); + expect(deedTypeUpdated.deed_type_has_document_types.length).toEqual(2); + }); + + it("should not add document types to a deed type that already has those document types ", async () => { + const deedTypeUid = (await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType.name, office_uid: office.uid } })).uid; + let deedTypeToUpdate: DeedType = JSON.parse(JSON.stringify(deedType)); + + deedTypeToUpdate.deed_type_has_document_types = [ + { + document_type: documentType, + deed_type: new DeedType(), + created_at: null, + updated_at: null, + }, + { + document_type: documentType_, + deed_type: new DeedType(), + created_at: null, + updated_at: null, + }, + ]; + + await DeedTypeServiceTest.update(deedTypeUid, deedTypeToUpdate); + + const deedTypeUpdated = await prisma.deedTypes.findFirstOrThrow({ + where: { + uid: deedTypeUid, + }, + include: { + deed_type_has_document_types: true, + }, + }); + expect(deedTypeUpdated.deed_type_has_document_types.length).toEqual(2); + }); + + it("should delete document types from a deed", async () => { + const deedTypeUid = (await prisma.deedTypes.findFirstOrThrow({ where: { name: deedType.name, office_uid: office.uid } })).uid; + let deedTypeToUpdate: DeedType = JSON.parse(JSON.stringify(deedType)); + + // set relation between deed and document types empty + deedTypeToUpdate.deed_type_has_document_types = []; + + await DeedTypeServiceTest.update(deedTypeUid, deedTypeToUpdate); + + const deedTypeUpdated = await prisma.deedTypes.findFirstOrThrow({ + where: { + uid: deedTypeUid, + }, + include: { + deed_type_has_document_types: true, + }, + }); + expect(deedTypeUpdated.deed_type_has_document_types.length).toEqual(0); + }); +}); + +describe("test get function", () => { + it("should return an array of DeedTypes", async () => { + const deedTypes = await DeedTypeServiceTest.get({ orderBy: [{ name: "asc" }, { created_at: "asc" }] }); + + // verify result typing + expect(deedTypes).toBeInstanceOf(Array); + expect(deedTypes.length).toEqual(3); + + // verify result content + expect(deedTypes[0]?.name).toEqual(deedType_.name); + expect(deedTypes[0]?.description).toEqual(deedType_.description); + expect(deedTypes[0]?.archived_at).toBeNull(); + expect(deedTypes[0]?.office_uid).toEqual(office_.uid); + + expect(deedTypes[1]?.name).toEqual(deedType.name); + expect(deedTypes[1]?.description).toEqual(deedType.description); + expect(deedTypes[1]?.archived_at).toBeNull(); + expect(deedTypes[1]?.office_uid).toEqual(office.uid); + + expect(deedTypes[2]?.name).toEqual(deedType.name); + expect(deedTypes[2]?.description).toEqual(deedType.description); + expect(deedTypes[2]?.archived_at).toBeNull(); + expect(deedTypes[2]?.office_uid).toEqual(office_.uid); + }); + + it("should return an array of DeedTypes per offices", async () => { + const deedTypesForFirstOffice = await DeedTypeServiceTest.get({ where: { office: {uid: office.uid} }, orderBy: { name: "asc" } }); + + expect(deedTypesForFirstOffice.length).toEqual(1); + + // verify result content + expect(deedTypesForFirstOffice[0]?.name).toEqual(deedType.name); + expect(deedTypesForFirstOffice[0]?.description).toEqual(deedType.description); + expect(deedTypesForFirstOffice[0]?.archived_at).toBeNull(); + expect(deedTypesForFirstOffice[0]?.office_uid).toEqual(office.uid); + + const deedTypesForSecondOffice = await DeedTypeServiceTest.get({ where: { office: {uid: office_.uid} }, orderBy: { name: "asc" } }); + + expect(deedTypesForSecondOffice.length).toEqual(2); + + // verify result content + expect(deedTypesForSecondOffice[0]?.name).toEqual(deedType_.name); + expect(deedTypesForSecondOffice[0]?.description).toEqual(deedType_.description); + expect(deedTypesForSecondOffice[0]?.archived_at).toBeNull(); + expect(deedTypesForSecondOffice[0]?.office_uid).toEqual(office_.uid); + + expect(deedTypesForSecondOffice[1]?.name).toEqual(deedType.name); + expect(deedTypesForSecondOffice[1]?.description).toEqual(deedType.description); + expect(deedTypesForSecondOffice[1]?.archived_at).toBeNull(); + expect(deedTypesForSecondOffice[1]?.office_uid).toEqual(office_.uid); + }); +}); diff --git a/src/test/services/super-admin/DocumentTypesService.test.ts b/src/test/services/super-admin/DocumentTypesService.test.ts new file mode 100644 index 00000000..b6d98045 --- /dev/null +++ b/src/test/services/super-admin/DocumentTypesService.test.ts @@ -0,0 +1,272 @@ +import "module-alias/register"; +import "reflect-metadata"; +import { DocumentType } from "le-coffre-resources/dist/SuperAdmin"; +import DocumentTypesService from "@Services/super-admin/DocumentTypesService/DocumentTypesService"; +import { PrismaClient } from "prisma/prisma-client"; +import { documentType, documentType_, office, office_ } from "@Test/config/MockedData"; +import DocumentTypesRepository from "@Repositories/DocumentTypesRepository"; +import Container from "typedi"; +import { initOffice } from "@Test/config/Init"; + +const prisma = new PrismaClient(); + +const DocumentTypesServiceTest = new DocumentTypesService(Container.get(DocumentTypesRepository)); + +beforeAll(async () => { + office.uid = (await initOffice(office)).uid; + office_.uid = (await initOffice(office_)).uid; +}); + +afterAll(async () => { + const deleteDocumentTypes = prisma.documentTypes.deleteMany(); + const deleteOffices = prisma.offices.deleteMany(); + await prisma.$transaction([deleteDocumentTypes, deleteOffices]); + await prisma.$disconnect(); +}); + +describe("test create function", () => { + it("should not create a new document type if office is unknown", async () => { + let documentTypeWithoutOfficeUid: DocumentType = JSON.parse(JSON.stringify(documentType)); + documentTypeWithoutOfficeUid.office!.uid = "random uid"; + // try to create a new document type with unknown office + async function createDocumentTypeWithUnknownOffice() { + await DocumentTypesServiceTest.create(documentTypeWithoutOfficeUid); + } + await expect(createDocumentTypeWithUnknownOffice).rejects.toThrow(); + }); + + it("should create a new document type", async () => { + let documentTypeWithOfficeUid: DocumentType = JSON.parse(JSON.stringify(documentType)); + documentTypeWithOfficeUid.office!.uid = office.uid; + const documentTypeCreated = await DocumentTypesServiceTest.create(documentTypeWithOfficeUid); + + expect(documentTypeCreated.name).toEqual(documentType.name); + expect(documentTypeCreated.public_description).toEqual(documentType.public_description); + expect(documentTypeCreated.private_description).toEqual(documentType.private_description); + expect(documentTypeCreated.archived_at).toBeNull(); + expect(documentTypeCreated.office_uid).toEqual(office.uid); + }); + + it("should not create a new document type with a name already used for a given office", async () => { + let documentTypeWithSameNameAndOffice: DocumentType = JSON.parse(JSON.stringify(documentType_)); + documentTypeWithSameNameAndOffice.office!.uid = office.uid; + documentTypeWithSameNameAndOffice.name = documentType.name; + + async function createDocumentTypeWithSameNameAndOffice() { + await DocumentTypesServiceTest.create(documentTypeWithSameNameAndOffice); + } + await expect(createDocumentTypeWithSameNameAndOffice).rejects.toThrow(); + }); + + it("should create the same document type for a different office", async () => { + let documentTypeDuplicatedForNewOffice: DocumentType = JSON.parse(JSON.stringify(documentType)); + documentTypeDuplicatedForNewOffice.office!.uid = office_.uid; + + const documentTypeCreated = await DocumentTypesServiceTest.create(documentTypeDuplicatedForNewOffice); + + expect(documentTypeCreated.name).toEqual(documentType.name); + expect(documentTypeCreated.public_description).toEqual(documentType.public_description); + expect(documentTypeCreated.private_description).toEqual(documentType.private_description); + expect(documentTypeCreated.archived_at).toBeNull(); + expect(documentTypeCreated.office_uid).toEqual(office_.uid); + }); + + it("should create a new document type version with a different name for a given office", async () => { + let documentTypeWithSameDescription: DocumentType = JSON.parse(JSON.stringify(documentType)); + documentTypeWithSameDescription.office!.uid = office.uid; + documentTypeWithSameDescription.name = documentType_.name; + + const documentTypeCreated = await DocumentTypesServiceTest.create(documentTypeWithSameDescription); + + expect(documentTypeCreated.name).toEqual(documentType_.name); + expect(documentTypeCreated.public_description).toEqual(documentType.public_description); + expect(documentTypeCreated.private_description).toEqual(documentType.private_description); + expect(documentTypeCreated.archived_at).toBeNull(); + expect(documentTypeCreated.office_uid).toEqual(office.uid); + }); +}); + +describe("test update function", () => { + it("should update a document type", async () => { + const documentTypeCreated = await prisma.documentTypes.findFirstOrThrow({ + where: { name: documentType_.name, office_uid: office.uid }, + }); + expect(documentTypeCreated.name).toEqual(documentType_.name); + expect(documentTypeCreated.public_description).toEqual(documentType.public_description); + expect(documentTypeCreated.private_description).toEqual(documentType.private_description); + expect(documentTypeCreated.archived_at).toBeNull(); + expect(documentTypeCreated.office_uid).toEqual(office.uid); + + let documentTypeWithNewDescription: DocumentType = JSON.parse(JSON.stringify(documentType_)); + documentTypeWithNewDescription.office!.uid = office.uid; + + // update the last document type created with his the right descriptions + const documentTypeUpdated = await DocumentTypesServiceTest.update(documentTypeCreated.uid, documentTypeWithNewDescription); + expect(documentTypeUpdated.name).toEqual(documentType_.name); + expect(documentTypeUpdated.public_description).toEqual(documentType_.public_description); + expect(documentTypeUpdated.private_description).toEqual(documentType_.private_description); + expect(documentTypeUpdated.archived_at).toBeNull(); + expect(documentTypeUpdated.office_uid).toEqual(office.uid); + }); + + it("should not update a document type name with an already used name for given office", async () => { + const documentTypeUid = ( + await prisma.documentTypes.findFirstOrThrow({ where: { name: documentType_.name, office_uid: office.uid } }) + ).uid; + let documentTypeWithSameNameAndOffice: DocumentType = JSON.parse(JSON.stringify(documentType_)); + documentTypeWithSameNameAndOffice.office!.uid = office.uid; + documentTypeWithSameNameAndOffice.name = documentType.name; + + // update the last document type created with his the right description + async function updateDocumentTypeWithSameName() { + await DocumentTypesServiceTest.update(documentTypeUid, documentTypeWithSameNameAndOffice); + } + await expect(updateDocumentTypeWithSameName).rejects.toThrow(); + }); + + it("should not update a document type office membership if the office already has this document type", async () => { + const documentTypeUid = ( + await prisma.documentTypes.findFirstOrThrow({ where: { name: documentType_.name, office_uid: office.uid } }) + ).uid; + let documentTypeWithSameNameAndOffice: DocumentType = JSON.parse(JSON.stringify(documentType_)); + documentTypeWithSameNameAndOffice.office!.uid = office.uid; + documentTypeWithSameNameAndOffice.name = documentType.name; + + // try to duplicate document type in a given office + async function updateDocumentTypeWithduplicatedName() { + await DocumentTypesServiceTest.update(documentTypeUid, documentTypeWithSameNameAndOffice); + } + await expect(updateDocumentTypeWithduplicatedName).rejects.toThrow(); + }); + + it("should update a document type office membership", async () => { + const documentTypeCreated = await prisma.documentTypes.findFirstOrThrow({ + where: { name: documentType_.name, office_uid: office.uid }, + }); + + expect(documentTypeCreated.name).toEqual(documentType_.name); + expect(documentTypeCreated.public_description).toEqual(documentType_.public_description); + expect(documentTypeCreated.private_description).toEqual(documentType_.private_description); + expect(documentTypeCreated.archived_at).toBeNull(); + expect(documentTypeCreated.office_uid).toEqual(office.uid); + + let documentTypeTransferedToNewOffice: DocumentType = JSON.parse(JSON.stringify(documentType_)); + documentTypeTransferedToNewOffice.office!.uid = office_.uid; + + // update the last document type updated with a new office membership + const documentTypeUpdated = await DocumentTypesServiceTest.update(documentTypeCreated.uid, documentTypeTransferedToNewOffice); + + expect(documentTypeUpdated.name).toEqual(documentType_.name); + expect(documentTypeUpdated.public_description).toEqual(documentType_.public_description); + expect(documentTypeUpdated.private_description).toEqual(documentType_.private_description); + expect(documentTypeUpdated.archived_at).toBeNull(); + expect(documentTypeUpdated.office_uid).toEqual(office_.uid); + }); + + it("should archivate a document type", async () => { + const documentTypeCreated = await prisma.documentTypes.findFirstOrThrow({ + where: { name: documentType_.name, office_uid: office_.uid }, + }); + + expect(documentTypeCreated.name).toEqual(documentType_.name); + expect(documentTypeCreated.public_description).toEqual(documentType_.public_description); + expect(documentTypeCreated.private_description).toEqual(documentType_.private_description); + expect(documentTypeCreated.archived_at).toBeNull(); + expect(documentTypeCreated.office_uid).toEqual(office_.uid); + + let documentTypeArchivated: DocumentType = JSON.parse(JSON.stringify(documentType_)); + documentTypeArchivated.office!.uid = office_.uid; + const currentDate = new Date(Date.now()); + documentTypeArchivated.archived_at = currentDate; + // archivate a document type by giving a non null date for archivated_at attribute + const documentTypeUpdated = await DocumentTypesServiceTest.update(documentTypeCreated.uid, documentTypeArchivated); + expect(documentTypeUpdated.name).toEqual(documentType_.name); + expect(documentTypeUpdated.public_description).toEqual(documentType_.public_description); + expect(documentTypeUpdated.private_description).toEqual(documentType_.private_description); + expect(documentTypeUpdated.archived_at).toEqual(currentDate); + expect(documentTypeUpdated.office_uid).toEqual(office_.uid); + }); + + it("should unarchivate a document type", async () => { + const documentTypeCreated = await prisma.documentTypes.findFirstOrThrow({ + where: { name: documentType_.name, office_uid: office_.uid }, + }); + + expect(documentTypeCreated.name).toEqual(documentType_.name); + expect(documentTypeCreated.public_description).toEqual(documentType_.public_description); + expect(documentTypeCreated.private_description).toEqual(documentType_.private_description); + expect(documentTypeCreated.archived_at).not.toBeNull(); + expect(documentTypeCreated.office_uid).toEqual(office_.uid); + + let documentTypeUnarchivated: DocumentType = JSON.parse(JSON.stringify(documentType_)); + documentTypeUnarchivated.office!.uid = office_.uid; + + // unarchivate a document type by giving a null date for archivated_at attribute + const documentTypeUpdated = await DocumentTypesServiceTest.update(documentTypeCreated.uid, documentTypeUnarchivated); + + expect(documentTypeUpdated.name).toEqual(documentType_.name); + expect(documentTypeUpdated.public_description).toEqual(documentType_.public_description); + expect(documentTypeUpdated.private_description).toEqual(documentType_.private_description); + expect(documentTypeUpdated.archived_at).toBeNull(); + expect(documentTypeUpdated.office_uid).toEqual(office_.uid); + }); +}); + +describe("test get function", () => { + it("should return an array of DocumentTypes", async () => { + const documentTypes = await DocumentTypesServiceTest.get({ orderBy: [{ name: "asc" }, { created_at: "asc" }] }); + + // verify result typing + expect(documentTypes).toBeInstanceOf(Array); + expect(documentTypes.length).toEqual(3); + + // verify result content + expect(documentTypes[0]?.name).toEqual(documentType_.name); + expect(documentTypes[0]?.public_description).toEqual(documentType_.public_description); + expect(documentTypes[0]?.private_description).toEqual(documentType_.private_description); + expect(documentTypes[0]?.archived_at).toBeNull(); + expect(documentTypes[0]?.office_uid).toEqual(office_.uid); + + expect(documentTypes[1]?.name).toEqual(documentType.name); + expect(documentTypes[1]?.public_description).toEqual(documentType.public_description); + expect(documentTypes[1]?.private_description).toEqual(documentType.private_description); + expect(documentTypes[1]?.archived_at).toBeNull(); + expect(documentTypes[1]?.office_uid).toEqual(office.uid); + + expect(documentTypes[2]?.name).toEqual(documentType.name); + expect(documentTypes[2]?.public_description).toEqual(documentType.public_description); + expect(documentTypes[2]?.private_description).toEqual(documentType.private_description); + expect(documentTypes[2]?.archived_at).toBeNull(); + expect(documentTypes[2]?.office_uid).toEqual(office_.uid); + }); + + it("should return an array of DocumentTypes per offices", async () => { + const documentTypesForFirstOffice = await DocumentTypesServiceTest.get({ where: { office: {uid : office.uid }}, orderBy: { name: "asc" } }); + + expect(documentTypesForFirstOffice.length).toEqual(1); + + // verify result content + expect(documentTypesForFirstOffice[0]?.name).toEqual(documentType.name); + expect(documentTypesForFirstOffice[0]?.public_description).toEqual(documentType.public_description); + expect(documentTypesForFirstOffice[0]?.private_description).toEqual(documentType.private_description); + expect(documentTypesForFirstOffice[0]?.archived_at).toBeNull(); + expect(documentTypesForFirstOffice[0]?.office_uid).toEqual(office.uid); + + const documentTypesForSecondOffice = await DocumentTypesServiceTest.get({ where: { office: {uid : office_.uid }}, orderBy: { name: "asc" } }); + + expect(documentTypesForSecondOffice.length).toEqual(2); + + // verify result content + expect(documentTypesForSecondOffice[0]?.name).toEqual(documentType_.name); + expect(documentTypesForSecondOffice[0]?.public_description).toEqual(documentType_.public_description); + expect(documentTypesForSecondOffice[0]?.private_description).toEqual(documentType_.private_description); + expect(documentTypesForSecondOffice[0]?.archived_at).toBeNull(); + expect(documentTypesForSecondOffice[0]?.office_uid).toEqual(office_.uid); + + expect(documentTypesForSecondOffice[1]?.name).toEqual(documentType.name); + expect(documentTypesForSecondOffice[1]?.public_description).toEqual(documentType.public_description); + expect(documentTypesForSecondOffice[1]?.private_description).toEqual(documentType.private_description); + expect(documentTypesForSecondOffice[1]?.archived_at).toBeNull(); + expect(documentTypesForSecondOffice[1]?.office_uid).toEqual(office_.uid); + }); +}); diff --git a/src/test/services/super-admin/OfficeFolderService.test.ts b/src/test/services/super-admin/OfficeFolderService.test.ts new file mode 100644 index 00000000..c0c52549 --- /dev/null +++ b/src/test/services/super-admin/OfficeFolderService.test.ts @@ -0,0 +1,287 @@ +import "module-alias/register"; +import "reflect-metadata"; +import { OfficeFolderHasCustomers, OfficeFolderHasStakeholders, PrismaClient } from "prisma/prisma-client"; +import { customer, customer_, deedType, documentType, documentType_, office, officeFolder, officeFolder_, user, user_ } from "@Test/config/MockedData"; +import Container from "typedi"; +import OfficeFoldersRepository from "@Repositories/OfficeFoldersRepository"; +import OfficeFolderService from "@Services/super-admin/OfficeFoldersService/OfficeFoldersService"; +import { initCustomers, initDeedType, initDocumentType, initOffice, initUsers } from "@Test/config/Init"; +import { OfficeFolder } from "le-coffre-resources/dist/SuperAdmin"; +import DeedTypesService from "@Services/super-admin/DeedTypesService/DeedTypesService"; +import DeedsRepository from "@Repositories/DeedsRepository"; + +const prisma = new PrismaClient(); + +const OfficeFolderServiceTest = new OfficeFolderService(Container.get(OfficeFoldersRepository), Container.get(DeedTypesService), Container.get(DeedsRepository)); + +beforeAll(async () => { + office.uid = (await initOffice(office)).uid; + documentType.uid = (await initDocumentType(documentType, office)).uid; + documentType_.uid = (await initDocumentType(documentType_, office)).uid; + deedType.uid = (await initDeedType(deedType, office, [documentType.uid])).uid; + user.uid = (await initUsers(user)).uid; + user_.uid = (await initUsers(user_)).uid; + customer.uid = (await initCustomers(customer)).uid; + customer_.uid = (await initCustomers(customer_)).uid; +}); + +afterAll(async () => { + /* + * Clean database after all tests execution. + * Due to cascade deletion, if addresses are deleted, all items following tables are dropped: contacts, customers, offices + */ + const deleteDeedTypes = prisma.deedTypes.deleteMany(); + const deleteAddresses = prisma.addresses.deleteMany(); + await prisma.$transaction([deleteDeedTypes, deleteAddresses]); + await prisma.$disconnect(); +}); + +describe("test create function", () => { + it("should not create a new office folder if deed type is unknown", async () => { + let officeFolderWithoutDeedTypeUid: OfficeFolder = JSON.parse(JSON.stringify(officeFolder)); + officeFolderWithoutDeedTypeUid.deed!.deed_type!.uid = "random uid"; + // try to create a new deed with unknown deed type + async function createOfficeFolderWithUnknownDeedType() { + await OfficeFolderServiceTest.create(officeFolderWithoutDeedTypeUid); + } + await expect(createOfficeFolderWithUnknownDeedType).rejects.toThrow(); + }); + + it("should not create a new office folder if deed type is archived", async () => { + let officeFolderWithArchivatedDeedType: OfficeFolder = JSON.parse(JSON.stringify(officeFolder)); + // try to create a new deed with unknown deed type + async function createOfficeFolderWithArchivedDeedType() { + await OfficeFolderServiceTest.create(officeFolderWithArchivatedDeedType); + } + await expect(createOfficeFolderWithArchivedDeedType).rejects.toThrow("deed type is archived"); + }); + + it("should create a new office folder based on existing deed type", async () => { + const officeFolderCreated = await OfficeFolderServiceTest.create(officeFolder); + + const deedCreated = await prisma.deeds.findUniqueOrThrow({ where: { uid: officeFolderCreated.deed_uid } }); + + expect(officeFolderCreated.name).toEqual(officeFolder.name); + expect(officeFolderCreated.folder_number).toEqual(officeFolder.folder_number); + expect(officeFolderCreated.description).toEqual(officeFolder.description); + expect(officeFolderCreated.archived_description).toEqual(null); + expect(officeFolderCreated.status).toEqual("LIVE"); + expect(officeFolderCreated.office_uid).toEqual(officeFolder.office!.uid); + expect(deedCreated.deed_type_uid).toEqual(officeFolder.deed!.deed_type!.uid); + }); + + it("should contains stakeholders", async () => { + const officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({ + include: { office_folder_has_stakeholder: true }, + }); + const stakeholderRelation = await prisma.officeFolderHasStakeholders.findUniqueOrThrow({ + where: { + office_folder_uid_user_stakeholder_uid: { + user_stakeholder_uid: user.uid!, + office_folder_uid: officeFolderCreated.uid, + }, + }, + }); + const stakeholderRelation_ = await prisma.officeFolderHasStakeholders.findUniqueOrThrow({ + where: { + office_folder_uid_user_stakeholder_uid: { + user_stakeholder_uid: user_.uid!, + office_folder_uid: officeFolderCreated.uid, + }, + }, + }); + expect(officeFolderCreated.office_folder_has_stakeholder.length).toEqual(2); + const stakeholder: OfficeFolderHasStakeholders = { + uid: stakeholderRelation.uid, + office_folder_uid: officeFolderCreated.uid, + user_stakeholder_uid: user.uid!, + created_at: officeFolderCreated.created_at, + updated_at: officeFolderCreated.updated_at, + }; + const stakeholder_: OfficeFolderHasStakeholders = { + uid: stakeholderRelation_.uid, + office_folder_uid: officeFolderCreated.uid, + user_stakeholder_uid: user_.uid!, + created_at: officeFolderCreated.created_at, + updated_at: officeFolderCreated.updated_at, + }; + expect(officeFolderCreated.office_folder_has_stakeholder).toEqual(expect.arrayContaining([stakeholder, stakeholder_])); + }); + + it("should not create a new office folder with folder number already created", async () => { + let officeFolderWithSameFolderNumber: OfficeFolder = JSON.parse(JSON.stringify(officeFolder_)); + officeFolderWithSameFolderNumber.folder_number = officeFolder.folder_number; + // try to create a new deed with unknown deed type + async function createOfficeFolderWithSameFolderNumber() { + await OfficeFolderServiceTest.create(officeFolderWithSameFolderNumber); + } + await expect(createOfficeFolderWithSameFolderNumber).rejects.toThrow(); + }); + + it("should not create a new office folder if deed type is archived", async () => { + await prisma.deedTypes.update({ where: { uid: deedType.uid }, data: { archived_at: new Date(Date.now()) } }); + // try to create a new deed with archivated deed type + async function createDeedWithArchivatedDeedType() { + await OfficeFolderServiceTest.create(officeFolder); + } + await expect(createDeedWithArchivatedDeedType).rejects.toThrow("deed type is archived"); + }); +}); + +describe("test update function", () => { + it("should add customers", async () => { + let officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({ + include: { office_folder_has_customers: true }, + }); + + expect(officeFolderCreated.office_folder_has_customers).toEqual([]); + // mocked data contains the customers + await OfficeFolderServiceTest.update(officeFolderCreated.uid, officeFolder); + + const customerRelation = await prisma.officeFolderHasCustomers.findUniqueOrThrow({ + where: { + office_folder_uid_customer_uid: { + customer_uid: customer.uid!, + office_folder_uid: officeFolderCreated.uid, + }, + }, + }); + const customerRelation_ = await prisma.officeFolderHasCustomers.findUniqueOrThrow({ + where: { + office_folder_uid_customer_uid: { + customer_uid: customer_.uid!, + office_folder_uid: officeFolderCreated.uid, + }, + }, + }); + + officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({ + include: { office_folder_has_customers: true }, + }); + + expect(officeFolderCreated.office_folder_has_customers.length).toEqual(2); + const officeFolderHasCustomer: OfficeFolderHasCustomers = { + uid: customerRelation.uid, + office_folder_uid: officeFolderCreated.uid, + customer_uid: customer.uid!, + created_at: customerRelation.created_at, + updated_at: customerRelation.updated_at, + }; + const officeFolderHasCustomer_: OfficeFolderHasCustomers = { + uid: customerRelation_.uid, + office_folder_uid: officeFolderCreated.uid, + customer_uid: customer_.uid!, + created_at: customerRelation_.created_at, + updated_at: customerRelation_.updated_at, + }; + expect(officeFolderCreated.office_folder_has_customers).toEqual( + expect.arrayContaining([officeFolderHasCustomer, officeFolderHasCustomer_]), + ); + }); + + it("should remove customers", async () => { + let officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({ + include: { office_folder_has_customers: true }, + }); + + expect(officeFolderCreated.office_folder_has_customers.length).toEqual(2); + + let officeFolderWithLessCustomers: OfficeFolder = JSON.parse(JSON.stringify(officeFolder)); + officeFolderWithLessCustomers.office_folder_has_customers!.pop(); + // mocked data contains the customers + await OfficeFolderServiceTest.update(officeFolderCreated.uid, officeFolderWithLessCustomers); + + const customerRelation = await prisma.officeFolderHasCustomers.findUniqueOrThrow({ + where: { + office_folder_uid_customer_uid: { + customer_uid: customer.uid!, + office_folder_uid: officeFolderCreated.uid, + }, + }, + }); + + officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({ + include: { office_folder_has_customers: true }, + }); + + expect(officeFolderCreated.office_folder_has_customers.length).toEqual(1); + const officeFolderHasCustomer: OfficeFolderHasCustomers = { + uid: customerRelation.uid, + office_folder_uid: officeFolderCreated.uid, + customer_uid: customer.uid!, + created_at: customerRelation.created_at, + updated_at: customerRelation.updated_at, + }; + expect(officeFolderCreated.office_folder_has_customers).toEqual([officeFolderHasCustomer]); + }); + it("should remove stakeholders", async () => { + let officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({ + include: { office_folder_has_stakeholder: true }, + }); + + expect(officeFolderCreated.office_folder_has_stakeholder.length).toEqual(2); + + let officeFolderWithLessStakeholders: OfficeFolder = JSON.parse(JSON.stringify(officeFolder)); + officeFolderWithLessStakeholders.office_folder_has_stakeholder!.pop(); + // mocked data contains the customers + await OfficeFolderServiceTest.update(officeFolderCreated.uid, officeFolderWithLessStakeholders); + + const stakeholderRelation = await prisma.officeFolderHasStakeholders.findUniqueOrThrow({ + where: { + office_folder_uid_user_stakeholder_uid: { + user_stakeholder_uid: user.uid!, + office_folder_uid: officeFolderCreated.uid, + }, + }, + }); + + officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({ + include: { office_folder_has_stakeholder: true }, + }); + + expect(officeFolderCreated.office_folder_has_stakeholder.length).toEqual(1); + const officeFolderHasStakeholder: OfficeFolderHasStakeholders = { + uid: stakeholderRelation.uid, + office_folder_uid: officeFolderCreated.uid, + user_stakeholder_uid: user.uid!, + created_at: stakeholderRelation.created_at, + updated_at: stakeholderRelation.updated_at, + }; + expect(officeFolderCreated.office_folder_has_stakeholder).toEqual([officeFolderHasStakeholder]); + }); + it("should archivate an office folder", async () => { + const officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({}); + let officeFolderArchived: OfficeFolder = JSON.parse(JSON.stringify(officeFolder)); + // mocked data for this office folder is "ARCHIVATED" by default + officeFolderArchived.archived_description = "folder complete"; + + const officeFolderUpdated = await OfficeFolderServiceTest.update(officeFolderCreated.uid, officeFolderArchived); + + expect(officeFolderUpdated.archived_description).toEqual(officeFolderArchived.archived_description); + expect(officeFolderUpdated.status).toEqual("ARCHIVED"); + }); + it("should unarchivate an office folder", async () => { + const officeFolderCreated = await prisma.officeFolders.findFirstOrThrow({}); + + expect(officeFolderCreated.archived_description).toEqual("folder complete"); + expect(officeFolderCreated.status).toEqual("ARCHIVED"); + + let officeFolderUnarchived: OfficeFolder = JSON.parse(JSON.stringify(officeFolder)); + officeFolderUnarchived.status = "LIVE"; + + const officeFolderUpdated = await OfficeFolderServiceTest.update(officeFolderCreated.uid, officeFolderUnarchived); + + expect(officeFolderUpdated.archived_description).toBeNull(); + expect(officeFolderUpdated.status).toEqual("LIVE"); + }); +}); + +describe("test get function", () => { + it("should return an array of officeFolders", async () => { + const officeFolders = await OfficeFolderServiceTest.get({}); + + // verify result typing + expect(officeFolders).toBeInstanceOf(Array); + expect(officeFolders.length).toEqual(1); + }); +}); diff --git a/src/test/services/super-admin/UsersService.test.ts b/src/test/services/super-admin/UsersService.test.ts new file mode 100644 index 00000000..5b7d6708 --- /dev/null +++ b/src/test/services/super-admin/UsersService.test.ts @@ -0,0 +1,225 @@ +import "module-alias/register"; +import "reflect-metadata"; +import User from "le-coffre-resources/dist/SuperAdmin"; +import UsersService from "@Services/super-admin/UsersService/UsersService"; +import { PrismaClient } from "@prisma/client"; +import { user, userContact, userContact_, user_ } from "@Test/config/MockedData"; +import UsersRepository from "@Repositories/UsersRepository"; +import Container from "typedi"; + +const prisma = new PrismaClient(); + +const UsersServiceTest = new UsersService(Container.get(UsersRepository)); + +afterAll(async () => { + /* + * Clean database after all tests execution. + * Due to cascade deletion, if addresses are deleted, all items following tables are dropped: contacts, users, offices + */ + const deleteAddresses = prisma.addresses.deleteMany(); + await prisma.$transaction([deleteAddresses]); + await prisma.$disconnect(); +}); + +describe("test create function", () => { + it("should create a new user", async () => { + const userCreated = await UsersServiceTest.create(user); + + expect(userCreated?.idNot).toEqual(user.idNot); + + // verify if user contact is created in db + const contactCreated = await prisma.contacts.findUnique({ where: { uid: userCreated.contact_uid } }); + expect(contactCreated?.first_name).toEqual(user.contact!.first_name); + expect(contactCreated?.last_name).toEqual(user.contact!.last_name); + expect(contactCreated?.cell_phone_number).toEqual(user.contact!.cell_phone_number); + expect(contactCreated?.phone_number).toEqual(user.contact!.phone_number); + expect(contactCreated?.civility).toEqual(user.contact!.civility); + expect(contactCreated?.email).toEqual(user.contact!.email); + + // verify if user address is created in db + const addressForContactCreated = await prisma.addresses.findUnique({ where: { uid: contactCreated?.address_uid! } }); + expect(addressForContactCreated?.address).toEqual(user.contact!.address?.address); + expect(addressForContactCreated?.zip_code).toEqual(user.contact!.address?.zip_code); + expect(addressForContactCreated?.city).toEqual(user.contact!.address?.city); + + // verify if user office is created in db + const officeCreated = await prisma.offices.findUnique({ where: { uid: userCreated.office_uid } }); + expect(officeCreated?.idNot).toEqual(user.office_membership!!.idNot); + expect(officeCreated?.name).toEqual(user.office_membership!!.name); + expect(officeCreated?.crpcen).toEqual(user.office_membership!!.crpcen); + expect(officeCreated?.office_status).toEqual("DESACTIVATED"); + + // verify if user office's address is created in db + const addressForOfficeCreated = await prisma.addresses.findUnique({ where: { uid: officeCreated?.address_uid! } }); + expect(addressForOfficeCreated?.address).toEqual(user.office_membership!.address!.address); + expect(addressForOfficeCreated?.zip_code).toEqual(user.office_membership!.address!.zip_code); + expect(addressForOfficeCreated?.city).toEqual(user.office_membership!.address!.city); + }); + + it("should not create an user already created", async () => { + // try to create the same user + async function duplicateUser() { + await UsersServiceTest.create(user); + } + await expect(duplicateUser).rejects.toThrow(); + }); + + it("should not create an new user with an email already created", async () => { + let newUser: User = JSON.parse(JSON.stringify(user_)); + newUser.contact!.email = userContact.email; + + // try to create a new user with already used email + async function createUserWithDuplicateEmail() { + await UsersServiceTest.create(newUser); + } + await expect(createUserWithDuplicateEmail).rejects.toThrow(); + }); + + it("should not create an user with an phone number already created", async () => { + let newUser: User = JSON.parse(JSON.stringify(user_)); + newUser.contact!.cell_phone_number = userContact.cell_phone_number; + + // try to create a new user with already used cellphone number + async function duplicateUser() { + await UsersServiceTest.create(newUser); + } + await expect(duplicateUser).rejects.toThrow(); + }); + + it("should create an new user if unique attributes differ from existing users", async () => { + let newUser: User = JSON.parse(JSON.stringify(user)); + newUser.idNot = user_.idNot; + newUser.contact!.email = userContact_.email; + newUser.contact!.cell_phone_number = userContact_.cell_phone_number; + + const userCreated = await UsersServiceTest.create(newUser); + + expect(userCreated?.idNot).toEqual(user_.idNot); + + // verify if user_ contact is created in db + const contactCreated = await prisma.contacts.findUnique({ where: { uid: userCreated.contact_uid } }); + expect(contactCreated?.first_name).toEqual(user.contact!.first_name); + expect(contactCreated?.last_name).toEqual(user.contact!.last_name); + expect(contactCreated?.cell_phone_number).toEqual(user_.contact!.cell_phone_number); + expect(contactCreated?.phone_number).toEqual(user.contact!.phone_number); + expect(contactCreated?.civility).toEqual(user.contact!.civility); + expect(contactCreated?.email).toEqual(user_.contact!.email); + + // verify if user_ address is created in db + const addressForContactCreated = await prisma.addresses.findUnique({ where: { uid: contactCreated?.address_uid! } }); + expect(addressForContactCreated?.address).toEqual(user.contact!.address?.address); + expect(addressForContactCreated?.zip_code).toEqual(user.contact!.address?.zip_code); + expect(addressForContactCreated?.city).toEqual(user.contact!.address?.city); + + // verify if user joined the existing office + const officeJoined = await prisma.offices.findUnique({ where: { uid: userCreated.office_uid } }); + expect(officeJoined?.idNot).toEqual(user.office_membership!!.idNot); + expect(officeJoined?.name).toEqual(user.office_membership!!.name); + expect(officeJoined?.crpcen).toEqual(user.office_membership!!.crpcen); + expect(officeJoined?.office_status).toEqual("DESACTIVATED"); + }); +}); + +describe("test update function", () => { + it("should update an user's data", async () => { + const userCreated = await prisma.users.findFirstOrThrow({ where: { idNot: user_.idNot } }); + + const officeJoined = await prisma.offices.findUnique({ where: { uid: userCreated.office_uid } }); + expect(officeJoined?.idNot).toEqual(user.office_membership!!.idNot); + expect(officeJoined?.name).toEqual(user.office_membership!!.name); + expect(officeJoined?.crpcen).toEqual(user.office_membership!!.crpcen); + expect(officeJoined?.office_status).toEqual("DESACTIVATED"); + + // update the last user created with his own new office and own contact + const updatedUser = await UsersServiceTest.update(userCreated.uid, user_); + + expect(updatedUser?.idNot).toEqual(user_.idNot); + + // verify if user_ contact is created in db + const existingContact = await prisma.contacts.findUnique({ where: { uid: updatedUser.contact_uid } }); + expect(existingContact?.first_name).toEqual(user_.contact!.first_name); + expect(existingContact?.last_name).toEqual(user_.contact!.last_name); + expect(existingContact?.cell_phone_number).toEqual(user_.contact!.cell_phone_number); + expect(existingContact?.phone_number).toEqual(user_.contact!.phone_number); + expect(existingContact?.civility).toEqual(user_.contact!.civility); + expect(existingContact?.email).toEqual(user_.contact!.email); + + // verify if user_ address is created in db + const addressForExistingContact = await prisma.addresses.findUnique({ where: { uid: existingContact?.address_uid! } }); + expect(addressForExistingContact?.address).toEqual(user_.contact!.address?.address); + expect(addressForExistingContact?.zip_code).toEqual(user_.contact!.address?.zip_code); + expect(addressForExistingContact?.city).toEqual(user_.contact!.address?.city); + + // verify if user_ joined the new office + const officeCreated = await prisma.offices.findUnique({ where: { uid: updatedUser.office_uid } }); + expect(officeCreated?.idNot).toEqual(user_.office_membership!.idNot); + expect(officeCreated?.name).toEqual(user_.office_membership!.name); + expect(officeCreated?.crpcen).toEqual(user_.office_membership!.crpcen); + expect(officeCreated?.office_status).toEqual("DESACTIVATED"); + + // verify is user_ office's address is created in db + const addressForOfficeCreated = await prisma.addresses.findUnique({ where: { uid: officeCreated?.address_uid! } }); + expect(addressForOfficeCreated?.address).toEqual(user_.office_membership!.address!.address); + expect(addressForOfficeCreated?.zip_code).toEqual(user_.office_membership!.address!.zip_code); + expect(addressForOfficeCreated?.city).toEqual(user_.office_membership!.address!.city); + }); + + it("should not update an user with an email already used", async () => { + const userUid = (await prisma.users.findFirstOrThrow({ where: { idNot: user_.idNot } })).uid; + let updatedUser: User = JSON.parse(JSON.stringify(user_)); + updatedUser.contact!.email = userContact.email; + + // try to create a new user with already used email + async function updateUserWithDuplicateEmail() { + await UsersServiceTest.update(userUid, updatedUser); + } + await expect(updateUserWithDuplicateEmail).rejects.toThrow(); + }); + + it("should not update an user with an phone number already used", async () => { + const userUid = (await prisma.users.findFirstOrThrow({ where: { idNot: user_.idNot } })).uid; + let updatedUser: User = JSON.parse(JSON.stringify(user_)); + updatedUser.contact!.cell_phone_number = userContact.cell_phone_number; + + // try to create a new user with already used email + async function updateUserWithDuplicateEmail() { + await UsersServiceTest.update(userUid, updatedUser); + } + await expect(updateUserWithDuplicateEmail).rejects.toThrow(); + }); +}); + +describe("test get function", () => { + it("should return an array of Users", async () => { + const req = {}; + const users = await UsersServiceTest.get(req); + + // verify result typing + expect(users).toBeInstanceOf(Array); + expect(users.length).toEqual(2); + + // verify result content + const usersCreated = await prisma.users.findMany(); + expect(users).toContainEqual(usersCreated[0]); + expect(users).toContainEqual(usersCreated[1]); + }); + + it("should return an array of Users per offices", async () => { + const officesCreated = await prisma.offices.findMany(); + const reqForFirstOffice = { where: { office_uid: officesCreated[0]?.uid } }; + const usersForFirstOffice = await UsersServiceTest.get(reqForFirstOffice); + + expect(usersForFirstOffice.length).toEqual(1); + + // verify result content + expect(usersForFirstOffice[0]?.idNot).toEqual(user.idNot); + + const reqForSecondOffice = { where: { office_uid: officesCreated[1]?.uid } }; + const usersForSecondOffice = await UsersServiceTest.get(reqForSecondOffice); + + expect(usersForSecondOffice.length).toEqual(1); + + // verify result content + expect(usersForSecondOffice[0]?.idNot).toEqual(user_.idNot); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 0d461c21..b0dd3f39 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,9 @@ { "compilerOptions": { "incremental": false, - "target": "es5", - "module": "CommonJS", + // "module": "es2022", + "target": "es2017", + "module": "commonjs", "lib": [ "dom", "dom.iterable", @@ -67,7 +68,10 @@ ], "@ControllerPattern/*": [ "src/common/system/controller-pattern/*" - ] + ], + "@Test/*":[ + "src/test/*" + ], }, // "rootDirs": [], // "typeRoots": [], @@ -91,8 +95,8 @@ "include": [ "**/*.ts", "**/*.tsx", - "src/app/api/UsersController.ts" - ], + "src/app/api/admin/UsersController.ts" +, "src/common/databases/seeders/seeder.ts" ], "exclude": [ "node_modules" ]