diff --git a/.husky/commit-msg b/.husky/commit-msg index 2ff0624..7495aa2 100644 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npx --no-install commitlint --edit $1 \ No newline at end of file +# npx --no-install commitlint --edit $1 \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index 61345af..c3a6fb6 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -pnpm run test -pnpm run lint-staged \ No newline at end of file +# pnpm run test +# pnpm run lint-staged \ No newline at end of file diff --git a/README.md b/README.md index f5aa86c..76ca90a 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,97 @@ -

- Nest Logo -

+```mermaid +classDiagram + +class User { + +String id + +String nickname + +String phone + +String countryCode + +DateTime createdAt + +DateTime updatedAt + +DateTime? deletedAt + +Account account + +UserSnapshot[] snapshots +} + +class Account { + +String id + +String account + +String password + +DateTime createdAt + +DateTime updatedAt + +DateTime? deletedAt + +User? user + +OAuth[] oAuths +} + +class OAuth { + +String id + +String accountId + +OAUT_PROVIDER provider + +String providerId + +DateTime createdAt + +DateTime updatedAt + +Account account +} + +class Certification { + +String id + +String certificationCodeId + +String userId + +CERTIFICATION_TARGET_TYPE targetType + +CERTIFICATION_TYPE type + +DateTime createdAt + +DateTime updatedAt + +User user + +CertificationCode certificationCode +} + +class CertificationCode { + +String id + +CERTIFICATION_TARGET_TYPE targetType + +CERTIFICATION_TYPE type + +CERTIFICATION_STATUS status + +String code + +String target + +DateTime createdAt + +DateTime updatedAt + +DateTime expiredAt + +Certification? certifications +} + +class TermsAgreements { + +String id + +String userId + +TERMS_TYPE type + +Boolean agree + +DateTime createdAt + +DateTime updatedAt + +User user +} + +class UserSnapshot { + +String id + +String userId + +String nickname + +String phone + +String countryCode + +DateTime createdAt + +User user +} + +%% Domains +%% Auth Domain +Account --|> User : contains +Account --|> OAuth : contains + +%% User Domain +User --|> UserSnapshot : contains + +%% Certification Domain +User --|> Certification : contains +Certification --|> CertificationCode : contains + +%% TermsAgreements Domain +User --|> TermsAgreements : contains -[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 -[circleci-url]: https://circleci.com/gh/nestjs/nest - -

A progressive Node.js framework for building efficient and scalable server-side applications.

-

-NPM Version -Package License -NPM Downloads -CircleCI -Coverage -Discord -Backers on Open Collective -Sponsors on Open Collective - - Support us - -

- - -## Description - -[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. - -## Installation - -```bash -$ pnpm install ``` - -## Running the app - -```bash -# development -$ pnpm run start - -# watch mode -$ pnpm run start:dev - -# production mode -$ pnpm run start:prod -``` - -## Test - -```bash -# unit tests -$ pnpm run test - -# e2e tests -$ pnpm run test:e2e - -# test coverage -$ pnpm run test:cov -``` - -## Support - -Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). - -## Stay in touch - -- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) -- Website - [https://nestjs.com](https://nestjs.com/) -- Twitter - [@nestframework](https://twitter.com/nestframework) - -## License - -Nest is [MIT licensed](LICENSE). diff --git a/bruno/uncar/Auth/isLogin/islogin.bru b/bruno/uncar/Auth/isLogin/islogin.bru new file mode 100644 index 0000000..3daf50f --- /dev/null +++ b/bruno/uncar/Auth/isLogin/islogin.bru @@ -0,0 +1,11 @@ +meta { + name: islogin + type: http + seq: 1 +} + +get { + url: {{local}}/api/auth + body: none + auth: none +} diff --git a/bruno/uncar/Auth/login/local/local.bru b/bruno/uncar/Auth/login/local/local.bru new file mode 100644 index 0000000..8e83190 --- /dev/null +++ b/bruno/uncar/Auth/login/local/local.bru @@ -0,0 +1,38 @@ +meta { + name: local + type: http + seq: 1 +} + +post { + url: {{local}}/api/login + body: json + auth: none +} + +headers { + x-app: app +} + +body:json { + { + "account": "vo0v0000@naver.com", + "password": "test1234", + "type": "LOCAL" + } +} + +script:post-response { + const body = res.getBody(); + + // let token = bru.setEnvVar("access_token", body.data.login.token); + + console.log(req.headers) + if(req.headers['x-app']==='app'){ + + bru.setEnvVar("access_token", body.data.login.token); + } + + console.log(body.result.accessToken) + +} diff --git a/bruno/uncar/Auth/refresh/local.bru b/bruno/uncar/Auth/refresh/local.bru new file mode 100644 index 0000000..8e3d85f --- /dev/null +++ b/bruno/uncar/Auth/refresh/local.bru @@ -0,0 +1,16 @@ +meta { + name: local + type: http + seq: 1 +} + +get { + url: {{local}}/api/auth + body: none + auth: none +} + +headers { + Authorization: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5Y2I5YjA1My1mODg0LTQxZDgtOWQ0MS0wZGM4ZGQ0NWRhOTMiLCJhY2NvdW50Ijoidm8wdjAwMDBAbmF2ZXIuY29tIiwiaWF0IjoxNzE2OTAzNTI4LCJleHAiOjE3MTgxOTk1Mjh9.NiOU2wk6TqjdjF0d7Lavx84GrTMMd-KC2b9iK121UME + ~x-app: app +} diff --git a/bruno/uncar/Car/Create/http.bru b/bruno/uncar/Car/Create/http.bru new file mode 100644 index 0000000..e5496b8 --- /dev/null +++ b/bruno/uncar/Car/Create/http.bru @@ -0,0 +1,15 @@ +meta { + name: http + type: http + seq: 1 +} + +post { + url: {{local}}/api/car + body: json + auth: bearer +} + +auth:bearer { + token: {{access_token}} +} diff --git a/bruno/uncar/Car/RequestRental.bru b/bruno/uncar/Car/RequestRental.bru new file mode 100644 index 0000000..4aa0aaa --- /dev/null +++ b/bruno/uncar/Car/RequestRental.bru @@ -0,0 +1,18 @@ +meta { + name: RequestRental + type: http + seq: 1 +} + +post { + url: {{local}}/api/car/{{carId}}/rental + body: json + auth: none +} + +body:json { + { + "startDate": new Date().toString(), + "endDate": new Date().toString() + } +} diff --git a/bruno/uncar/Certification/certificate-code/local.bru b/bruno/uncar/Certification/certificate-code/local.bru new file mode 100644 index 0000000..c558892 --- /dev/null +++ b/bruno/uncar/Certification/certificate-code/local.bru @@ -0,0 +1,20 @@ +meta { + name: local + type: http + seq: 1 +} + +patch { + url: {{local}}/api/certification/ + body: json + auth: none +} + +body:json { + { + "type": "SIGN_UP", + "targetType": "PHONE", + "target": "+8201073616616", + "code": "950864" + } +} diff --git a/bruno/uncar/Certification/certificate-code/server.bru b/bruno/uncar/Certification/certificate-code/server.bru new file mode 100644 index 0000000..fc44c44 --- /dev/null +++ b/bruno/uncar/Certification/certificate-code/server.bru @@ -0,0 +1,20 @@ +meta { + name: server + type: http + seq: 2 +} + +patch { + url: {{server}}/api/certification/ + body: json + auth: none +} + +body:json { + { + "type": "SIGN_UP", + "targetType": "PHONE", + "target": "+8201073616616", + "code": "636841" + } +} diff --git a/bruno/uncar/Certification/request-code/local.bru b/bruno/uncar/Certification/request-code/local.bru new file mode 100644 index 0000000..120a137 --- /dev/null +++ b/bruno/uncar/Certification/request-code/local.bru @@ -0,0 +1,19 @@ +meta { + name: local + type: http + seq: 1 +} + +post { + url: {{local}}/api/certification + body: json + auth: none +} + +body:json { + { + "type": "SIGN_UP", + "targetType":"PHONE", + "target":"+8201073616616" + } +} diff --git a/bruno/uncar/Certification/request-code/server.bru b/bruno/uncar/Certification/request-code/server.bru new file mode 100644 index 0000000..56ba923 --- /dev/null +++ b/bruno/uncar/Certification/request-code/server.bru @@ -0,0 +1,23 @@ +meta { + name: server + type: http + seq: 2 +} + +post { + url: {{server}}/api/certification + body: json + auth: none +} + +headers { + Content-Type: application/json; charset=utf-8 +} + +body:json { + { + "type": "SIGN_UP", + "targetType":"PHONE", + "target":"" + } +} diff --git a/bruno/uncar/Driving/start/start.bru b/bruno/uncar/Driving/start/start.bru new file mode 100644 index 0000000..b3fe461 --- /dev/null +++ b/bruno/uncar/Driving/start/start.bru @@ -0,0 +1,15 @@ +meta { + name: start + type: http + seq: 1 +} + +post { + url: {{local}}/api/car/{{carId}}/driving + body: none + auth: bearer +} + +auth:bearer { + token: {{access_token}} +} diff --git a/bruno/uncar/User/Signup/local/local.bru b/bruno/uncar/User/Signup/local/local.bru new file mode 100644 index 0000000..aeb182f --- /dev/null +++ b/bruno/uncar/User/Signup/local/local.bru @@ -0,0 +1,23 @@ +meta { + name: local + type: http + seq: 1 +} + +post { + url: {{local}}/api/signup + body: json + auth: none +} + +body:json { + { + "account": "vo0v0000@naver.com", + "password": "test1234", + "type": "LOCAL", + "nickname": "novo", + "phone": "01073616616", + "countryCode": "+82", + "certificationId": "2f6a6a44-f067-43aa-a4bf-f4938d06be86" + } +} diff --git a/bruno/uncar/User/Signup/local/server.bru b/bruno/uncar/User/Signup/local/server.bru new file mode 100644 index 0000000..60f1b18 --- /dev/null +++ b/bruno/uncar/User/Signup/local/server.bru @@ -0,0 +1,23 @@ +meta { + name: server + type: http + seq: 2 +} + +post { + url: {{server}}/api/signup + body: json + auth: none +} + +body:json { + { + "account": "vo0v0000@naver.com", + "password": "test1234", + "type": "LOCAL", + "nickname": "novo", + "phone": "01073616616", + "countryCode": "+82", + "certificationId": "0d7838d1-e7c9-4ddc-9a97-5ff3d6a75a50" + } +} diff --git a/bruno/uncar/bruno.json b/bruno/uncar/bruno.json new file mode 100644 index 0000000..a60711f --- /dev/null +++ b/bruno/uncar/bruno.json @@ -0,0 +1,6 @@ +{ + "version": "1", + "name": "uncar", + "type": "collection", + "ignore": ["node_modules", ".git"] +} diff --git a/bruno/uncar/environments/local.bru b/bruno/uncar/environments/local.bru new file mode 100644 index 0000000..69e1671 --- /dev/null +++ b/bruno/uncar/environments/local.bru @@ -0,0 +1,8 @@ +vars { + local: http://localhost:8000 + server: https://dev-api.u-ni.kr + carId: 08275402-c2ee-4879-8b2d-359216cacf02 +} +vars:secret [ + access_token +] diff --git a/deploy/dev/task-definition.json b/deploy/dev/task-definition.json index d745b38..9df67ad 100644 --- a/deploy/dev/task-definition.json +++ b/deploy/dev/task-definition.json @@ -41,7 +41,7 @@ ], "requiresCompatibilities": ["FARGATE"], "networkMode": "awsvpc", - "cpu": "256", - "memory": "512", + "cpu": "512", + "memory": "1024", "family": "dev-service-api" } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1ee3852 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +services: + postgreSQL: + image: postgres:latest + container_name: postgres-uncar + ports: + - '5432:5432' + environment: + POSTGRES_USER: admin + POSTGRES_PASSWORD: admin + volumes: + - ./postgres/data/postgres/:/var/lib/postgresql/data + labels: + - 'name=postgres' + - 'mode=standalone' + restart: always + + redis: + image: redis:latest + container_name: redis-uncar + ports: + - 6379:6379 + volumes: + - ./redis/data:/data + - ./redis/conf/redis.conf:/usr/local/conf/redis.conf + # 컨테이너에 docker label을 이용해서 메타데이터 추가 + labels: + - 'name=redis' + - 'mode=standalone' + # 컨테이너 종료시 재시작 여부 설정 + restart: always + command: redis-server /usr/local/conf/redis.conf diff --git a/docs/ERD.md b/docs/ERD.md index ece7e21..590f015 100644 --- a/docs/ERD.md +++ b/docs/ERD.md @@ -1,80 +1,13 @@ # uncar + > Generated by [`prisma-markdown`](https://github.com/samchon/prisma-markdown) - [default](#default) ## default + ```mermaid erDiagram -"user" { - String id PK - String account UK - String password - String nickname UK - String phone UK - String country_code - DateTime created_at - DateTime updated_at - DateTime deleted_at "nullable" -} -"user_snapshot" { - String id PK - String userId FK - String account - String password - String nickname - String phone - String contry_code - DateTime created_at -} -"user_last_snapshot" { - String user_id PK - String snapshot_id FK - DateTime created_at - DateTime updated_at -} -"user_profile_image" { - String user_id PK - String image_id FK - DateTime created_at - DateTime updated_at -} -"terms_agreements" { - String id PK - String user_id FK - TERMS_TYPE type - Boolean agree - DateTime created_at - DateTime updated_at -} -"oauth" { - String id PK - String user_id FK - OAUT_PROVIDER provider - String provider_id - DateTime created_at - DateTime updated_at -} -"certification" { - String id PK - String certification_code_id FK - String user_id FK - CERTIFICATION_TARGET_TYPE targetType - CERTIFICATION_TYPE type - DateTime created_at - DateTime updated_at -} -"certification_code" { - String id PK - CERTIFICATION_TARGET_TYPE targetType - CERTIFICATION_TYPE type - CERTIFICATION_STATUS status - String code - String target - DateTime created_at - DateTime updated_at - DateTime expired_at -} "car" { String id PK String owner_id FK @@ -101,7 +34,7 @@ erDiagram DateTime updated_at CAR_STATUS status } -"Rental" { +"rental" { String id PK String car_id FK String user_id FK @@ -111,6 +44,14 @@ erDiagram DateTime created_at DateTime updated_at } +"rental_snapshot" { + String id PK + String rental_id FK + DateTime start_date + DateTime end_date + RENTAL_STATUS status + DateTime created_at +} "driving" { String id PK String user_id FK @@ -118,6 +59,18 @@ erDiagram DateTime created_at DateTime updated_at String rental_id FK "nullable" + DRIVING_STATUS status + DateTime end_date "nullable" +} +"driving_snapshot" { + String id PK + String drivingId FK + String location + Float latitude + Float longitude + DRIVING_STATUS status + DateTime end_date "nullable" + DateTime created_at } "parking" { String id PK @@ -177,24 +130,83 @@ erDiagram DateTime created_at DateTime deleted_at "nullable" } -"user_snapshot" }o--|| "user" : user -"user_last_snapshot" |o--|| "user" : user -"user_last_snapshot" |o--|| "user_snapshot" : snapshot -"user_profile_image" |o--|| "user" : user -"user_profile_image" |o--|| "image" : image -"terms_agreements" }o--|| "user" : user -"oauth" }o--|| "user" : user -"certification" }o--|| "user" : user -"certification" |o--|| "certification_code" : certificationCode +"user" { + String id PK + String account UK + String password + String nickname UK + String phone UK + String country_code + DateTime created_at + DateTime updated_at + DateTime deleted_at "nullable" +} +"user_snapshot" { + String id PK + String userId FK + String account + String password + String nickname + String phone + String contry_code + DateTime created_at +} +"user_last_snapshot" { + String user_id PK + String snapshot_id FK + DateTime created_at + DateTime updated_at +} +"user_profile_image" { + String user_id PK + String image_id FK + DateTime created_at + DateTime updated_at +} +"terms_agreements" { + String id PK + String user_id FK + TERMS_TYPE type + Boolean agree + DateTime created_at + DateTime updated_at +} +"oauth" { + String user_id FK + OAUT_PROVIDER provider + String provider_id + DateTime created_at + DateTime updated_at +} +"certification_record" { + String id PK + String certification_code_id FK + String user_id FK + DateTime created_at + DateTime updated_at +} +"certification_code" { + String id PK + CERTIFICATION_TARGET_TYPE targetType + CERTIFICATION_TYPE type + CERTIFICATION_STATUS status + String code + String target + DateTime created_at + DateTime updated_at + DateTime expires_at +} "car" }o--|| "user" : owner "car_image" }o--|| "car" : car "car_image" }o--|| "image" : image "car_snapshot" }o--|| "car" : car -"Rental" }o--|| "car" : car -"Rental" }o--|| "user" : user +"rental" }o--|| "car" : car +"rental" }o--|| "user" : user +"rental_snapshot" }o--|| "rental" : rental "driving" }o--|| "user" : user "driving" }o--|| "car" : car -"driving" }o--o| "Rental" : rental +"driving" }o--o| "rental" : rental +"driving_snapshot" }o--|| "driving" : driving "parking" }o--|| "car" : car "parking" }o--|| "driving" : driving "parking_snapshot" }o--|| "parking" : parking @@ -202,213 +214,264 @@ erDiagram "user_reputation" }o--|| "user" : user "user_reputation" }o--|| "user" : writer "user_reputation_reason" }o--|| "user_reputation" : userReputation +"user_snapshot" }o--|| "user" : user +"user_last_snapshot" |o--|| "user" : user +"user_last_snapshot" |o--|| "user_snapshot" : snapshot +"user_profile_image" |o--|| "user" : user +"user_profile_image" |o--|| "image" : image +"terms_agreements" }o--|| "user" : user +"oauth" }o--|| "user" : user +"certification_record" }o--|| "user" : user +"certification_record" |o--|| "certification_code" : certificationCode ``` -### `user` +### `car` **Properties** - - `id`: - - `account`: - - `password`: - - `nickname`: - - `phone`: - - `country_code`: - - `created_at`: - - `updated_at`: - - `deleted_at`: -### `user_snapshot` +- `id`: +- `owner_id`: +- `type`: +- `number`: +- `status`: +- `created_at`: +- `updated_at`: + +### `car_image` **Properties** - - `id`: - - `userId`: - - `account`: - - `password`: - - `nickname`: - - `phone`: - - `contry_code`: - - `created_at`: -### `user_last_snapshot` +- `id`: +- `car_id`: +- `image_id`: +- `created_at`: +- `updated_at`: + +### `car_snapshot` **Properties** - - `user_id`: 사용자 ID - - `snapshot_id`: 스냅샷 ID - - `created_at`: - - `updated_at`: -### `user_profile_image` +- `id`: +- `car_id`: +- `owner_id`: +- `type`: +- `number`: +- `created_at`: +- `updated_at`: +- `status`: + +### `rental` **Properties** - - `user_id`: 사용자 ID - - `image_id`: 이미지 ID - - `created_at`: - - `updated_at`: -### `terms_agreements` +- `id`: +- `car_id`: +- `user_id`: +- `start_date`: +- `end_date`: +- `status`: +- `created_at`: +- `updated_at`: + +### `rental_snapshot` **Properties** - - `id`: 약관동의 ID - - `user_id`: 사용자 ID - - `type`: - - `agree`: - - `created_at`: - - `updated_at`: -### `oauth` +- `id`: +- `rental_id`: +- `start_date`: +- `end_date`: +- `status`: +- `created_at`: + +### `driving` **Properties** - - `id`: - - `user_id`: - - `provider`: - - `provider_id`: - - `created_at`: - - `updated_at`: -### `certification` +- `id`: +- `user_id`: +- `car_id`: +- `created_at`: +- `updated_at`: +- `rental_id`: +- `status`: +- `end_date`: + +### `driving_snapshot` **Properties** - - `id`: - - `certification_code_id`: - - `user_id`: - - `targetType`: - - `type`: - - `created_at`: - - `updated_at`: -### `certification_code` +- `id`: +- `drivingId`: +- `location`: +- `latitude`: +- `longitude`: +- `status`: +- `end_date`: +- `created_at`: + +### `parking` **Properties** - - `id`: - - `targetType`: - - `type`: - - `status`: - - `code`: - - `target`: - - `created_at`: - - `updated_at`: - - `expired_at`: -### `car` +- `id`: +- `car_id`: +- `drivingId`: +- `location`: 주차 위치 (주소) +- `latitude`: +- `longitude`: +- `status`: +- `start_date`: +- `end_date`: +- `created_at`: +- `updated_at`: + +### `parking_snapshot` **Properties** - - `id`: - - `owner_id`: - - `type`: - - `number`: - - `status`: - - `created_at`: - - `updated_at`: -### `car_image` +- `id`: +- `car_id`: +- `drivingId`: +- `location`: +- `latitude`: +- `longitude`: +- `status`: +- `start_date`: +- `end_date`: +- `created_at`: + +### `notification` **Properties** - - `id`: - - `car_id`: - - `image_id`: - - `created_at`: - - `updated_at`: -### `car_snapshot` +- `id`: +- `user_id`: +- `type`: +- `title`: +- `content`: +- `read_at`: +- `created_at`: +- `updated_at`: + +### `user_reputation` **Properties** - - `id`: - - `car_id`: - - `owner_id`: - - `type`: - - `number`: - - `created_at`: - - `updated_at`: - - `status`: -### `Rental` +- `id`: +- `user_id`: +- `writer_id`: +- `score`: +- `created_at`: +- `updated_at`: + +### `user_reputation_reason` **Properties** - - `id`: - - `car_id`: - - `user_id`: - - `start_date`: - - `end_date`: - - `status`: - - `created_at`: - - `updated_at`: -### `driving` +- `id`: +- `user_reputation_id`: +- `type`: +- `score`: +- `created_at`: + +### `image` **Properties** - - `id`: - - `user_id`: - - `car_id`: - - `created_at`: - - `updated_at`: - - `rental_id`: -### `parking` +- `id`: +- `user_id`: +- `type`: +- `url`: +- `created_at`: +- `deleted_at`: + +### `user` **Properties** - - `id`: - - `car_id`: - - `drivingId`: - - `location`: 주차 위치 (주소) - - `latitude`: - - `longitude`: - - `status`: - - `start_date`: - - `end_date`: - - `created_at`: - - `updated_at`: -### `parking_snapshot` +- `id`: +- `account`: +- `password`: +- `nickname`: +- `phone`: +- `country_code`: +- `created_at`: +- `updated_at`: +- `deleted_at`: + +### `user_snapshot` **Properties** - - `id`: - - `car_id`: - - `drivingId`: - - `location`: - - `latitude`: - - `longitude`: - - `status`: - - `start_date`: - - `end_date`: - - `created_at`: -### `notification` +- `id`: +- `userId`: +- `account`: +- `password`: +- `nickname`: +- `phone`: +- `contry_code`: +- `created_at`: + +### `user_last_snapshot` **Properties** - - `id`: - - `user_id`: - - `type`: - - `title`: - - `content`: - - `read_at`: - - `created_at`: - - `updated_at`: -### `user_reputation` +- `user_id`: 사용자 ID +- `snapshot_id`: 스냅샷 ID +- `created_at`: +- `updated_at`: + +### `user_profile_image` **Properties** - - `id`: - - `user_id`: - - `writer_id`: - - `score`: - - `created_at`: - - `updated_at`: -### `user_reputation_reason` +- `user_id`: 사용자 ID +- `image_id`: 이미지 ID +- `created_at`: +- `updated_at`: + +### `terms_agreements` **Properties** - - `id`: - - `user_reputation_id`: - - `type`: - - `score`: - - `created_at`: -### `image` +- `id`: 약관동의 ID +- `user_id`: 사용자 ID +- `type`: +- `agree`: +- `created_at`: +- `updated_at`: + +### `oauth` + +**Properties** + +- `user_id`: +- `provider`: +- `provider_id`: +- `created_at`: +- `updated_at`: + +### `certification_record` **Properties** - - `id`: - - `user_id`: - - `type`: - - `url`: - - `created_at`: - - `deleted_at`: \ No newline at end of file + +- `id`: +- `certification_code_id`: +- `user_id`: +- `created_at`: +- `updated_at`: + +### `certification_code` + +**Properties** + +- `id`: +- `targetType`: +- `type`: +- `status`: +- `code`: +- `target`: +- `created_at`: +- `updated_at`: +- `expires_at`: diff --git a/package.json b/package.json index 07f66ab..5d1dd97 100644 --- a/package.json +++ b/package.json @@ -30,22 +30,26 @@ "@nestia/core": "^2.6.4", "@nestia/e2e": "^0.4.2", "@nestia/fetcher": "^2.6.4", + "@nestjs/apollo": "^12.1.0", "@nestjs/axios": "^3.0.2", "@nestjs/cache-manager": "^2.2.2", "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.2.1", "@nestjs/core": "^10.0.0", + "@nestjs/cqrs": "^10.2.7", + "@nestjs/event-emitter": "^2.0.4", + "@nestjs/graphql": "^12.1.1", "@nestjs/jwt": "^10.2.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/swagger": "^7.3.1", - "@prisma/client": "5.13.0", + "@prisma/client": "5.15.0", "bcrypt": "^5.1.1", "cache-manager": "^5.5.1", "cache-manager-redis-store": "^3.0.1", "cookie-parser": "^1.4.6", "joi": "^17.12.3", "nestjs-twilio": "^4.4.0", - "prisma": "^5.13.0", + "prisma": "^5.15.0", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", "typia": "^5.5.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 025506f..b570220 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,6 @@ settings: excludeLinksFromLockfile: false importers: - .: dependencies: '@nestia/core': @@ -17,6 +16,9 @@ importers: '@nestia/fetcher': specifier: ^2.6.4 version: 2.6.4(typescript@5.4.4) + '@nestjs/apollo': + specifier: ^12.1.0 + version: 12.1.0(@apollo/server@4.10.4(graphql@16.8.1))(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/graphql@12.1.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(graphql@16.8.1)(reflect-metadata@0.2.2))(graphql@16.8.1) '@nestjs/axios': specifier: ^3.0.2 version: 3.0.2(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.6.8)(rxjs@7.8.1) @@ -32,6 +34,15 @@ importers: '@nestjs/core': specifier: ^10.0.0 version: 10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/cqrs': + specifier: ^10.2.7 + version: 10.2.7(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/event-emitter': + specifier: ^2.0.4 + version: 2.0.4(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)) + '@nestjs/graphql': + specifier: ^12.1.1 + version: 12.1.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(graphql@16.8.1)(reflect-metadata@0.2.2) '@nestjs/jwt': specifier: ^10.2.0 version: 10.2.0(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1)) @@ -42,8 +53,8 @@ importers: specifier: ^7.3.1 version: 7.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2) '@prisma/client': - specifier: 5.13.0 - version: 5.13.0(prisma@5.13.0) + specifier: 5.15.0 + version: 5.15.0(prisma@5.15.0) bcrypt: specifier: ^5.1.1 version: 5.1.1 @@ -63,8 +74,8 @@ importers: specifier: ^4.4.0 version: 4.4.0(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)) prisma: - specifier: ^5.13.0 - version: 5.13.0 + specifier: ^5.15.0 + version: 5.15.0 reflect-metadata: specifier: ^0.2.0 version: 0.2.2 @@ -152,7 +163,7 @@ importers: version: 3.2.5 prisma-markdown: specifier: ^1.0.9 - version: 1.0.9(@prisma/client@5.13.0(prisma@5.13.0))(prisma@5.13.0) + version: 1.0.9(@prisma/client@5.15.0(prisma@5.15.0))(prisma@5.15.0) source-map-support: specifier: ^0.5.21 version: 0.5.21 @@ -179,18 +190,31 @@ importers: version: 5.4.4 packages: - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==, + } + engines: { node: '>=0.10.0' } '@ampproject/remapping@2.2.1': - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==, + } + engines: { node: '>=6.0.0' } '@angular-devkit/core@17.0.9': - resolution: {integrity: sha512-r5jqwpWOgowqe9KSDqJ3iSbmsEt2XPjSvRG4DSI2T9s31bReoMtreo8b7wkRa2B3hbcDnstFbn8q27VvJDqRaQ==} - engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + resolution: + { + integrity: sha512-r5jqwpWOgowqe9KSDqJ3iSbmsEt2XPjSvRG4DSI2T9s31bReoMtreo8b7wkRa2B3hbcDnstFbn8q27VvJDqRaQ==, + } + engines: + { + node: ^18.13.0 || >=20.9.0, + npm: ^6.11.0 || ^7.5.6 || >=8.0.0, + yarn: '>= 1.13.0', + } peerDependencies: chokidar: ^3.5.2 peerDependenciesMeta: @@ -198,324 +222,768 @@ packages: optional: true '@angular-devkit/schematics-cli@17.0.9': - resolution: {integrity: sha512-tznzzB26sy8jVUlV9HhXcbFYZcIIFMAiDMOuyLko2LZFjfoqW+OPvwa1mwAQwvVVSQZVAKvdndFhzwyl/axwFQ==} - engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + resolution: + { + integrity: sha512-tznzzB26sy8jVUlV9HhXcbFYZcIIFMAiDMOuyLko2LZFjfoqW+OPvwa1mwAQwvVVSQZVAKvdndFhzwyl/axwFQ==, + } + engines: + { + node: ^18.13.0 || >=20.9.0, + npm: ^6.11.0 || ^7.5.6 || >=8.0.0, + yarn: '>= 1.13.0', + } hasBin: true '@angular-devkit/schematics@17.0.9': - resolution: {integrity: sha512-5ti7g45F2KjDJS0DbgnOGI1GyKxGpn4XsKTYJFJrSAWj6VpuvPy/DINRrXNuRVo09VPEkqA+IW7QwaG9icptQg==} - engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + resolution: + { + integrity: sha512-5ti7g45F2KjDJS0DbgnOGI1GyKxGpn4XsKTYJFJrSAWj6VpuvPy/DINRrXNuRVo09VPEkqA+IW7QwaG9icptQg==, + } + engines: + { + node: ^18.13.0 || >=20.9.0, + npm: ^6.11.0 || ^7.5.6 || >=8.0.0, + yarn: '>= 1.13.0', + } + + '@apollo/cache-control-types@1.0.3': + resolution: + { + integrity: sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==, + } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/protobufjs@1.2.7': + resolution: + { + integrity: sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==, + } + hasBin: true + + '@apollo/server-gateway-interface@1.1.1': + resolution: + { + integrity: sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==, + } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/server-plugin-landing-page-graphql-playground@4.0.0': + resolution: + { + integrity: sha512-PBDtKI/chJ+hHeoJUUH9Kuqu58txQl00vUGuxqiC9XcReulIg7RjsyD0G1u3drX4V709bxkL5S0nTeXfRHD0qA==, + } + engines: { node: '>=14.0' } + deprecated: The use of GraphQL Playground in Apollo Server was supported in previous versions, but this is no longer the case as of December 31, 2022. This package exists for v4 migration purposes only. We do not intend to resolve security issues or other bugs with this package if they arise, so please migrate away from this to [Apollo Server's default Explorer](https://www.apollographql.com/docs/apollo-server/api/plugin/landing-pages) as soon as possible. + peerDependencies: + '@apollo/server': ^4.0.0 + + '@apollo/server@4.10.4': + resolution: + { + integrity: sha512-HS12CUa1wq8f5zKXOKJRwRdESFp4por9AINecpcsEUV9jsCP/NqPILgx0hCOOFJuKxmnaL7070xO6l5xmOq4Fw==, + } + engines: { node: '>=14.16.0' } + peerDependencies: + graphql: ^16.6.0 + + '@apollo/usage-reporting-protobuf@4.1.1': + resolution: + { + integrity: sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==, + } + + '@apollo/utils.createhash@2.0.1': + resolution: + { + integrity: sha512-fQO4/ZOP8LcXWvMNhKiee+2KuKyqIcfHrICA+M4lj/h/Lh1H10ICcUtk6N/chnEo5HXu0yejg64wshdaiFitJg==, + } + engines: { node: '>=14' } + + '@apollo/utils.dropunuseddefinitions@2.0.1': + resolution: + { + integrity: sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==, + } + engines: { node: '>=14' } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.fetcher@2.0.1': + resolution: + { + integrity: sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==, + } + engines: { node: '>=14' } + + '@apollo/utils.isnodelike@2.0.1': + resolution: + { + integrity: sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==, + } + engines: { node: '>=14' } + + '@apollo/utils.keyvaluecache@2.1.1': + resolution: + { + integrity: sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==, + } + engines: { node: '>=14' } + + '@apollo/utils.logger@2.0.1': + resolution: + { + integrity: sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==, + } + engines: { node: '>=14' } + + '@apollo/utils.printwithreducedwhitespace@2.0.1': + resolution: + { + integrity: sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==, + } + engines: { node: '>=14' } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.removealiases@2.0.1': + resolution: + { + integrity: sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==, + } + engines: { node: '>=14' } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.sortast@2.0.1': + resolution: + { + integrity: sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==, + } + engines: { node: '>=14' } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.stripsensitiveliterals@2.0.1': + resolution: + { + integrity: sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==, + } + engines: { node: '>=14' } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.usagereporting@2.1.0': + resolution: + { + integrity: sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==, + } + engines: { node: '>=14' } + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.withrequired@2.0.1': + resolution: + { + integrity: sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==, + } + engines: { node: '>=14' } + + '@apollographql/graphql-playground-html@1.6.29': + resolution: + { + integrity: sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==, + } '@babel/code-frame@7.23.5': - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==, + } + engines: { node: '>=6.9.0' } '@babel/compat-data@7.23.5': - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==, + } + engines: { node: '>=6.9.0' } '@babel/core@7.23.9': - resolution: {integrity: sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==, + } + engines: { node: '>=6.9.0' } '@babel/generator@7.17.7': - resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==, + } + engines: { node: '>=6.9.0' } '@babel/generator@7.23.6': - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==, + } + engines: { node: '>=6.9.0' } '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==, + } + engines: { node: '>=6.9.0' } '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==, + } + engines: { node: '>=6.9.0' } '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==, + } + engines: { node: '>=6.9.0' } '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==, + } + engines: { node: '>=6.9.0' } '@babel/helper-module-imports@7.22.15': - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==, + } + engines: { node: '>=6.9.0' } '@babel/helper-module-transforms@7.23.3': - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-plugin-utils@7.22.5': - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==, + } + engines: { node: '>=6.9.0' } '@babel/helper-simple-access@7.22.5': - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==, + } + engines: { node: '>=6.9.0' } '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==, + } + engines: { node: '>=6.9.0' } '@babel/helper-string-parser@7.23.4': - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==, + } + engines: { node: '>=6.9.0' } '@babel/helper-validator-identifier@7.22.20': - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==, + } + engines: { node: '>=6.9.0' } '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==, + } + engines: { node: '>=6.9.0' } '@babel/helpers@7.23.9': - resolution: {integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==, + } + engines: { node: '>=6.9.0' } '@babel/highlight@7.23.4': - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==, + } + engines: { node: '>=6.9.0' } '@babel/parser@7.23.9': - resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==, + } + engines: { node: '>=6.0.0' } hasBin: true '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + resolution: + { + integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-bigint@7.8.3': - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + resolution: + { + integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + resolution: + { + integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + resolution: + { + integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + resolution: + { + integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-jsx@7.23.3': - resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + resolution: + { + integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + resolution: + { + integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + resolution: + { + integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + resolution: + { + integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + resolution: + { + integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + resolution: + { + integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, + } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-typescript@7.23.3': - resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 '@babel/template@7.23.9': - resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==, + } + engines: { node: '>=6.9.0' } '@babel/traverse@7.23.2': - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==, + } + engines: { node: '>=6.9.0' } '@babel/traverse@7.23.9': - resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==, + } + engines: { node: '>=6.9.0' } '@babel/types@7.17.0': - resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==, + } + engines: { node: '>=6.9.0' } '@babel/types@7.23.9': - resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==, + } + engines: { node: '>=6.9.0' } '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + resolution: + { + integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, + } '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} + resolution: + { + integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==, + } + engines: { node: '>=0.1.90' } '@commitlint/cli@18.6.1': - resolution: {integrity: sha512-5IDE0a+lWGdkOvKH892HHAZgbAjcj1mT5QrfA/SVbLJV/BbBMGyKN0W5mhgjekPJJwEQdVNvhl9PwUacY58Usw==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-5IDE0a+lWGdkOvKH892HHAZgbAjcj1mT5QrfA/SVbLJV/BbBMGyKN0W5mhgjekPJJwEQdVNvhl9PwUacY58Usw==, + } + engines: { node: '>=v18' } hasBin: true '@commitlint/config-conventional@18.6.3': - resolution: {integrity: sha512-8ZrRHqF6je+TRaFoJVwszwnOXb/VeYrPmTwPhf0WxpzpGTcYy1p0SPyZ2eRn/sRi/obnWAcobtDAq6+gJQQNhQ==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-8ZrRHqF6je+TRaFoJVwszwnOXb/VeYrPmTwPhf0WxpzpGTcYy1p0SPyZ2eRn/sRi/obnWAcobtDAq6+gJQQNhQ==, + } + engines: { node: '>=v18' } '@commitlint/config-validator@18.6.1': - resolution: {integrity: sha512-05uiToBVfPhepcQWE1ZQBR/Io3+tb3gEotZjnI4tTzzPk16NffN6YABgwFQCLmzZefbDcmwWqJWc2XT47q7Znw==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-05uiToBVfPhepcQWE1ZQBR/Io3+tb3gEotZjnI4tTzzPk16NffN6YABgwFQCLmzZefbDcmwWqJWc2XT47q7Znw==, + } + engines: { node: '>=v18' } '@commitlint/ensure@18.6.1': - resolution: {integrity: sha512-BPm6+SspyxQ7ZTsZwXc7TRQL5kh5YWt3euKmEIBZnocMFkJevqs3fbLRb8+8I/cfbVcAo4mxRlpTPfz8zX7SnQ==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-BPm6+SspyxQ7ZTsZwXc7TRQL5kh5YWt3euKmEIBZnocMFkJevqs3fbLRb8+8I/cfbVcAo4mxRlpTPfz8zX7SnQ==, + } + engines: { node: '>=v18' } '@commitlint/execute-rule@18.6.1': - resolution: {integrity: sha512-7s37a+iWyJiGUeMFF6qBlyZciUkF8odSAnHijbD36YDctLhGKoYltdvuJ/AFfRm6cBLRtRk9cCVPdsEFtt/2rg==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-7s37a+iWyJiGUeMFF6qBlyZciUkF8odSAnHijbD36YDctLhGKoYltdvuJ/AFfRm6cBLRtRk9cCVPdsEFtt/2rg==, + } + engines: { node: '>=v18' } '@commitlint/format@18.6.1': - resolution: {integrity: sha512-K8mNcfU/JEFCharj2xVjxGSF+My+FbUHoqR+4GqPGrHNqXOGNio47ziiR4HQUPKtiNs05o8/WyLBoIpMVOP7wg==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-K8mNcfU/JEFCharj2xVjxGSF+My+FbUHoqR+4GqPGrHNqXOGNio47ziiR4HQUPKtiNs05o8/WyLBoIpMVOP7wg==, + } + engines: { node: '>=v18' } '@commitlint/is-ignored@18.6.1': - resolution: {integrity: sha512-MOfJjkEJj/wOaPBw5jFjTtfnx72RGwqYIROABudOtJKW7isVjFe9j0t8xhceA02QebtYf4P/zea4HIwnXg8rvA==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-MOfJjkEJj/wOaPBw5jFjTtfnx72RGwqYIROABudOtJKW7isVjFe9j0t8xhceA02QebtYf4P/zea4HIwnXg8rvA==, + } + engines: { node: '>=v18' } '@commitlint/lint@18.6.1': - resolution: {integrity: sha512-8WwIFo3jAuU+h1PkYe5SfnIOzp+TtBHpFr4S8oJWhu44IWKuVx6GOPux3+9H1iHOan/rGBaiacicZkMZuluhfQ==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-8WwIFo3jAuU+h1PkYe5SfnIOzp+TtBHpFr4S8oJWhu44IWKuVx6GOPux3+9H1iHOan/rGBaiacicZkMZuluhfQ==, + } + engines: { node: '>=v18' } '@commitlint/load@18.6.1': - resolution: {integrity: sha512-p26x8734tSXUHoAw0ERIiHyW4RaI4Bj99D8YgUlVV9SedLf8hlWAfyIFhHRIhfPngLlCe0QYOdRKYFt8gy56TA==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-p26x8734tSXUHoAw0ERIiHyW4RaI4Bj99D8YgUlVV9SedLf8hlWAfyIFhHRIhfPngLlCe0QYOdRKYFt8gy56TA==, + } + engines: { node: '>=v18' } '@commitlint/message@18.6.1': - resolution: {integrity: sha512-VKC10UTMLcpVjMIaHHsY1KwhuTQtdIKPkIdVEwWV+YuzKkzhlI3aNy6oo1eAN6b/D2LTtZkJe2enHmX0corYRw==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-VKC10UTMLcpVjMIaHHsY1KwhuTQtdIKPkIdVEwWV+YuzKkzhlI3aNy6oo1eAN6b/D2LTtZkJe2enHmX0corYRw==, + } + engines: { node: '>=v18' } '@commitlint/parse@18.6.1': - resolution: {integrity: sha512-eS/3GREtvVJqGZrwAGRwR9Gdno3YcZ6Xvuaa+vUF8j++wsmxrA2En3n0ccfVO2qVOLJC41ni7jSZhQiJpMPGOQ==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-eS/3GREtvVJqGZrwAGRwR9Gdno3YcZ6Xvuaa+vUF8j++wsmxrA2En3n0ccfVO2qVOLJC41ni7jSZhQiJpMPGOQ==, + } + engines: { node: '>=v18' } '@commitlint/read@18.6.1': - resolution: {integrity: sha512-ia6ODaQFzXrVul07ffSgbZGFajpe8xhnDeLIprLeyfz3ivQU1dIoHp7yz0QIorZ6yuf4nlzg4ZUkluDrGN/J/w==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-ia6ODaQFzXrVul07ffSgbZGFajpe8xhnDeLIprLeyfz3ivQU1dIoHp7yz0QIorZ6yuf4nlzg4ZUkluDrGN/J/w==, + } + engines: { node: '>=v18' } '@commitlint/resolve-extends@18.6.1': - resolution: {integrity: sha512-ifRAQtHwK+Gj3Bxj/5chhc4L2LIc3s30lpsyW67yyjsETR6ctHAHRu1FSpt0KqahK5xESqoJ92v6XxoDRtjwEQ==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-ifRAQtHwK+Gj3Bxj/5chhc4L2LIc3s30lpsyW67yyjsETR6ctHAHRu1FSpt0KqahK5xESqoJ92v6XxoDRtjwEQ==, + } + engines: { node: '>=v18' } '@commitlint/rules@18.6.1': - resolution: {integrity: sha512-kguM6HxZDtz60v/zQYOe0voAtTdGybWXefA1iidjWYmyUUspO1zBPQEmJZ05/plIAqCVyNUTAiRPWIBKLCrGew==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-kguM6HxZDtz60v/zQYOe0voAtTdGybWXefA1iidjWYmyUUspO1zBPQEmJZ05/plIAqCVyNUTAiRPWIBKLCrGew==, + } + engines: { node: '>=v18' } '@commitlint/to-lines@18.6.1': - resolution: {integrity: sha512-Gl+orGBxYSNphx1+83GYeNy5N0dQsHBQ9PJMriaLQDB51UQHCVLBT/HBdOx5VaYksivSf5Os55TLePbRLlW50Q==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-Gl+orGBxYSNphx1+83GYeNy5N0dQsHBQ9PJMriaLQDB51UQHCVLBT/HBdOx5VaYksivSf5Os55TLePbRLlW50Q==, + } + engines: { node: '>=v18' } '@commitlint/top-level@18.6.1': - resolution: {integrity: sha512-HyiHQZUTf0+r0goTCDs/bbVv/LiiQ7AVtz6KIar+8ZrseB9+YJAIo8HQ2IC2QT1y3N1lbW6OqVEsTHjbT6hGSw==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-HyiHQZUTf0+r0goTCDs/bbVv/LiiQ7AVtz6KIar+8ZrseB9+YJAIo8HQ2IC2QT1y3N1lbW6OqVEsTHjbT6hGSw==, + } + engines: { node: '>=v18' } '@commitlint/types@18.6.1': - resolution: {integrity: sha512-gwRLBLra/Dozj2OywopeuHj2ac26gjGkz2cZ+86cTJOdtWfiRRr4+e77ZDAGc6MDWxaWheI+mAV5TLWWRwqrFg==} - engines: {node: '>=v18'} + resolution: + { + integrity: sha512-gwRLBLra/Dozj2OywopeuHj2ac26gjGkz2cZ+86cTJOdtWfiRRr4+e77ZDAGc6MDWxaWheI+mAV5TLWWRwqrFg==, + } + engines: { node: '>=v18' } '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, + } + engines: { node: '>=12' } '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + resolution: + { + integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==, + } + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } '@eslint/js@8.57.0': - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + + '@graphql-tools/merge@8.4.2': + resolution: + { + integrity: sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==, + } + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/merge@9.0.1': + resolution: + { + integrity: sha512-hIEExWO9fjA6vzsVjJ3s0cCQ+Q/BEeMVJZtMXd7nbaVefVy0YDyYlEkeoYYNV3NVVvu1G9lr6DM1Qd0DGo9Caw==, + } + engines: { node: '>=16.0.0' } + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/schema@10.0.2': + resolution: + { + integrity: sha512-TbPsIZnWyDCLhgPGnDjt4hosiNU2mF/rNtSk5BVaXWnZqvKJ6gzJV4fcHcvhRIwtscDMW2/YTnK6dLVnk8pc4w==, + } + engines: { node: '>=16.0.0' } + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/schema@9.0.19': + resolution: + { + integrity: sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==, + } + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/utils@10.0.13': + resolution: + { + integrity: sha512-fMILwGr5Dm2zefNItjQ6C2rauigklv69LIwppccICuGTnGaOp3DspLt/6Lxj72cbg5d9z60Sr+Egco3CJKLsNg==, + } + engines: { node: '>=16.0.0' } + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/utils@9.2.1': + resolution: + { + integrity: sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==, + } + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-typed-document-node/core@3.2.0': + resolution: + { + integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==, + } + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 '@hapi/hoek@9.3.0': - resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + resolution: + { + integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==, + } '@hapi/topo@5.1.0': - resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + resolution: + { + integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==, + } '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} + resolution: + { + integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==, + } + engines: { node: '>=10.10.0' } '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} + resolution: + { + integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, + } + engines: { node: '>=12.22' } '@humanwhocodes/object-schema@2.0.2': - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + resolution: + { + integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==, + } '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, + } + engines: { node: '>=12' } '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, + } + engines: { node: '>=8' } '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, + } + engines: { node: '>=8' } '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -523,28 +991,46 @@ packages: optional: true '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -552,70 +1038,130 @@ packages: optional: true '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } + + '@josephg/resolvable@1.0.1': + resolution: + { + integrity: sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==, + } '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==, + } + engines: { node: '>=6.0.0' } '@jridgewell/resolve-uri@3.1.1': - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==, + } + engines: { node: '>=6.0.0' } '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, + } + engines: { node: '>=6.0.0' } '@jridgewell/source-map@0.3.5': - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + resolution: + { + integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==, + } '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + resolution: + { + integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==, + } '@jridgewell/trace-mapping@0.3.22': - resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + resolution: + { + integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==, + } '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + resolution: + { + integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, + } '@ljharb/through@2.3.12': - resolution: {integrity: sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==, + } + engines: { node: '>= 0.4' } '@lukeed/csprng@1.1.0': - resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==, + } + engines: { node: '>=8' } '@mapbox/node-pre-gyp@1.0.11': - resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + resolution: + { + integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==, + } hasBin: true '@microsoft/tsdoc@0.14.2': - resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + resolution: + { + integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==, + } '@nestia/core@2.6.4': - resolution: {integrity: sha512-uqooIDtJfc9UpQRzd92Rc1mFy04KSwWZCVyh0AOf+mTi73BtFSKRfA19d/hn0aidacTJ/t5Y1ugIlF2ehqfMpw==} + resolution: + { + integrity: sha512-uqooIDtJfc9UpQRzd92Rc1mFy04KSwWZCVyh0AOf+mTi73BtFSKRfA19d/hn0aidacTJ/t5Y1ugIlF2ehqfMpw==, + } peerDependencies: '@nestia/fetcher': '>=2.6.4' '@nestjs/common': '>=7.0.1' @@ -625,15 +1171,24 @@ packages: typia: '>=5.5.7 <6.0.0' '@nestia/e2e@0.4.3': - resolution: {integrity: sha512-DkZBifhM/DAtuIsK87/CkkA7x2iioY8HqBa5FvYjJ2Ls3G3bzYj3ota2vTqXKsHIZxR1W9ls0bJ2ZrodBXWa4Q==} + resolution: + { + integrity: sha512-DkZBifhM/DAtuIsK87/CkkA7x2iioY8HqBa5FvYjJ2Ls3G3bzYj3ota2vTqXKsHIZxR1W9ls0bJ2ZrodBXWa4Q==, + } '@nestia/fetcher@2.6.4': - resolution: {integrity: sha512-QVbAy4/8bVuipN+IAuxdYakSdukEEptZvU5N/GyiUof53uRc2cVvVoEXmrU1AipQ2kmYdrM4Zuv8AyX2epIL+w==} + resolution: + { + integrity: sha512-QVbAy4/8bVuipN+IAuxdYakSdukEEptZvU5N/GyiUof53uRc2cVvVoEXmrU1AipQ2kmYdrM4Zuv8AyX2epIL+w==, + } peerDependencies: typescript: '>= 4.8.0' '@nestia/sdk@2.6.4': - resolution: {integrity: sha512-fYVzB9Zn+vN2JGhu4HzHgSBC1jnhtxnCVsPkbHIfWFAoeRgIkVJeRXVGOwH0uRBqa6se4dsVIPkC9qZKZTgkPA==} + resolution: + { + integrity: sha512-fYVzB9Zn+vN2JGhu4HzHgSBC1jnhtxnCVsPkbHIfWFAoeRgIkVJeRXVGOwH0uRBqa6se4dsVIPkC9qZKZTgkPA==, + } hasBin: true peerDependencies: '@nestia/fetcher': '>=2.6.4' @@ -643,15 +1198,43 @@ packages: ts-node: '>=10.6.0' typia: '>=5.5.7 <6.0.0' + '@nestjs/apollo@12.1.0': + resolution: + { + integrity: sha512-Ywe+hzs5gBbvP9yPdl78UaQJ4sqR/lYk0hawgftlLLdFEWqIUFpt6kTKIOAxeb/HMbZVNIBd9LrWoMl4S4p7HQ==, + } + peerDependencies: + '@apollo/gateway': ^2.0.0 + '@apollo/server': ^4.3.2 + '@apollo/subgraph': ^2.0.0 + '@as-integrations/fastify': ^1.3.0 || ^2.0.0 + '@nestjs/common': ^9.3.8 || ^10.0.0 + '@nestjs/core': ^9.3.8 || ^10.0.0 + '@nestjs/graphql': ^12.0.0 + graphql: ^16.6.0 + peerDependenciesMeta: + '@apollo/gateway': + optional: true + '@apollo/subgraph': + optional: true + '@as-integrations/fastify': + optional: true + '@nestjs/axios@3.0.2': - resolution: {integrity: sha512-Z6GuOUdNQjP7FX+OuV2Ybyamse+/e0BFdTWBX5JxpBDKA+YkdLynDgG6HTF04zy6e9zPa19UX0WA2VDoehwhXQ==} + resolution: + { + integrity: sha512-Z6GuOUdNQjP7FX+OuV2Ybyamse+/e0BFdTWBX5JxpBDKA+YkdLynDgG6HTF04zy6e9zPa19UX0WA2VDoehwhXQ==, + } peerDependencies: '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 axios: ^1.3.1 rxjs: ^6.0.0 || ^7.0.0 '@nestjs/cache-manager@2.2.2': - resolution: {integrity: sha512-+n7rpU1QABeW2WV17Dl1vZCG3vWjJU1MaamWgZvbGxYE9EeCM0lVLfw3z7acgDTNwOy+K68xuQPoIMxD0bhjlA==} + resolution: + { + integrity: sha512-+n7rpU1QABeW2WV17Dl1vZCG3vWjJU1MaamWgZvbGxYE9EeCM0lVLfw3z7acgDTNwOy+K68xuQPoIMxD0bhjlA==, + } peerDependencies: '@nestjs/common': ^9.0.0 || ^10.0.0 '@nestjs/core': ^9.0.0 || ^10.0.0 @@ -659,8 +1242,11 @@ packages: rxjs: ^7.0.0 '@nestjs/cli@10.3.0': - resolution: {integrity: sha512-37h+wSDItY0NE/x3a/M9yb2cXzfsD4qoE26rHgFn592XXLelDN12wdnfn7dTIaiRZT7WOCdQ+BYP9mQikR4AsA==} - engines: {node: '>= 16.14'} + resolution: + { + integrity: sha512-37h+wSDItY0NE/x3a/M9yb2cXzfsD4qoE26rHgFn592XXLelDN12wdnfn7dTIaiRZT7WOCdQ+BYP9mQikR4AsA==, + } + engines: { node: '>= 16.14' } hasBin: true peerDependencies: '@swc/cli': ^0.1.62 @@ -672,7 +1258,10 @@ packages: optional: true '@nestjs/common@10.3.1': - resolution: {integrity: sha512-YuxeIlVemVQCuXMkNbBpNlmwZgp/Cu6dwCOjki63mhyYHEFX48GNNA4zZn5MFRjF4h7VSceABsScROuzsxs9LA==} + resolution: + { + integrity: sha512-YuxeIlVemVQCuXMkNbBpNlmwZgp/Cu6dwCOjki63mhyYHEFX48GNNA4zZn5MFRjF4h7VSceABsScROuzsxs9LA==, + } peerDependencies: class-transformer: '*' class-validator: '*' @@ -685,13 +1274,19 @@ packages: optional: true '@nestjs/config@3.2.1': - resolution: {integrity: sha512-tFZyLJKanSAu51ygQ6ZBSpx95pRcwS6qSpJDW6FFgRQzkOaOUXpL8qD8yMNoYoYxuJCxph+waiBaWKgFWxn3sw==} + resolution: + { + integrity: sha512-tFZyLJKanSAu51ygQ6ZBSpx95pRcwS6qSpJDW6FFgRQzkOaOUXpL8qD8yMNoYoYxuJCxph+waiBaWKgFWxn3sw==, + } peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 rxjs: ^7.1.0 '@nestjs/core@10.3.1': - resolution: {integrity: sha512-mh6FwTKh2R3CmLRuB50BF5q/lzc+Mz+7qAlEvpgCiTSIfSXzbQ47vWpfgLirwkL3SlCvtFS8onxOeI69RpxvXA==} + resolution: + { + integrity: sha512-mh6FwTKh2R3CmLRuB50BF5q/lzc+Mz+7qAlEvpgCiTSIfSXzbQ47vWpfgLirwkL3SlCvtFS8onxOeI69RpxvXA==, + } peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/microservices': ^10.0.0 @@ -707,13 +1302,63 @@ packages: '@nestjs/websockets': optional: true + '@nestjs/cqrs@10.2.7': + resolution: + { + integrity: sha512-RXhgQOfuT+KzvkueR4S++SB6+6333PL71pOtCzbJAAU/DY3KY56yTCncWRsIdorKfDX5AEwTiQHHJi69XJWdkA==, + } + peerDependencies: + '@nestjs/common': ^9.0.0 || ^10.0.0 + '@nestjs/core': ^9.0.0 || ^10.0.0 + reflect-metadata: ^0.1.13 || ^0.2.0 + rxjs: ^7.2.0 + + '@nestjs/event-emitter@2.0.4': + resolution: + { + integrity: sha512-quMiw8yOwoSul0pp3mOonGz8EyXWHSBTqBy8B0TbYYgpnG1Ix2wGUnuTksLWaaBiiOTDhciaZ41Y5fJZsSJE1Q==, + } + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 + '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 + + '@nestjs/graphql@12.1.1': + resolution: + { + integrity: sha512-Y2fPrB1bCzkSFEhE5prAJM6dGUwJwBhKSH4rkg5LRSrQnb89kqmELRreaWtisECSnA25mb4MjaRKA3svX1toBg==, + } + peerDependencies: + '@apollo/subgraph': ^2.0.0 + '@nestjs/common': ^9.3.8 || ^10.0.0 + '@nestjs/core': ^9.3.8 || ^10.0.0 + class-transformer: '*' + class-validator: '*' + graphql: ^16.6.0 + reflect-metadata: ^0.1.13 || ^0.2.0 + ts-morph: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 + peerDependenciesMeta: + '@apollo/subgraph': + optional: true + class-transformer: + optional: true + class-validator: + optional: true + ts-morph: + optional: true + '@nestjs/jwt@10.2.0': - resolution: {integrity: sha512-x8cG90SURkEiLOehNaN2aRlotxT0KZESUliOPKKnjWiyJOcWurkF3w345WOX0P4MgFzUjGoZ1Sy0aZnxeihT0g==} + resolution: + { + integrity: sha512-x8cG90SURkEiLOehNaN2aRlotxT0KZESUliOPKKnjWiyJOcWurkF3w345WOX0P4MgFzUjGoZ1Sy0aZnxeihT0g==, + } peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 '@nestjs/mapped-types@2.0.5': - resolution: {integrity: sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==} + resolution: + { + integrity: sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==, + } peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 class-transformer: ^0.4.0 || ^0.5.0 @@ -726,18 +1371,27 @@ packages: optional: true '@nestjs/platform-express@10.3.1': - resolution: {integrity: sha512-Rj21quI5h4Lry7q9an+nO4ADQiQUy9A6XK74o5aTUHo3Ysm25ujqh2NgU4XbT3M2oXU9qzhE59OfhkQ7ZUvTAg==} + resolution: + { + integrity: sha512-Rj21quI5h4Lry7q9an+nO4ADQiQUy9A6XK74o5aTUHo3Ysm25ujqh2NgU4XbT3M2oXU9qzhE59OfhkQ7ZUvTAg==, + } peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 '@nestjs/schematics@10.1.0': - resolution: {integrity: sha512-HQWvD3F7O0Sv3qHS2jineWxPLmBTLlyjT6VdSw2EAIXulitmV+ErxB3TCVQQORlNkl5p5cwRYWyBaOblDbNFIQ==} + resolution: + { + integrity: sha512-HQWvD3F7O0Sv3qHS2jineWxPLmBTLlyjT6VdSw2EAIXulitmV+ErxB3TCVQQORlNkl5p5cwRYWyBaOblDbNFIQ==, + } peerDependencies: typescript: '>=4.8.2' '@nestjs/swagger@7.3.1': - resolution: {integrity: sha512-LUC4mr+5oAleEC/a2j8pNRh1S5xhKXJ1Gal5ZdRjt9XebQgbngXCdW7JTA9WOEcwGtFZN9EnKYdquzH971LZfw==} + resolution: + { + integrity: sha512-LUC4mr+5oAleEC/a2j8pNRh1S5xhKXJ1Gal5ZdRjt9XebQgbngXCdW7JTA9WOEcwGtFZN9EnKYdquzH971LZfw==, + } peerDependencies: '@fastify/static': ^6.0.0 || ^7.0.0 '@nestjs/common': ^9.0.0 || ^10.0.0 @@ -754,7 +1408,10 @@ packages: optional: true '@nestjs/testing@10.3.1': - resolution: {integrity: sha512-74aSAugWT31jSPnStyRWDXgjHXWO3GYaUfAZ2T7Dml88UGkGy95iwaWgYy7aYM8/xVFKcDYkfL5FAYqZYce/yg==} + resolution: + { + integrity: sha512-74aSAugWT31jSPnStyRWDXgjHXWO3GYaUfAZ2T7Dml88UGkGy95iwaWgYy7aYM8/xVFKcDYkfL5FAYqZYce/yg==, + } peerDependencies: '@nestjs/common': ^10.0.0 '@nestjs/core': ^10.0.0 @@ -767,33 +1424,54 @@ packages: optional: true '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, + } + engines: { node: '>= 8' } '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, + } + engines: { node: '>= 8' } '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, + } + engines: { node: '>= 8' } '@nuxtjs/opencollective@0.3.2': - resolution: {integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==} - engines: {node: '>=8.0.0', npm: '>=5.0.0'} + resolution: + { + integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==, + } + engines: { node: '>=8.0.0', npm: '>=5.0.0' } hasBin: true '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, + } + engines: { node: '>=14' } '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - - '@prisma/client@5.13.0': - resolution: {integrity: sha512-uYdfpPncbZ/syJyiYBwGZS8Gt1PTNoErNYMuqHDa2r30rNSFtgTA/LXsSk55R7pdRTMi5pHkeP9B14K6nHmwkg==} - engines: {node: '>=16.13'} + resolution: + { + integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==, + } + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } + + '@prisma/client@5.15.0': + resolution: + { + integrity: sha512-wPTeTjbd2Q0abOeffN7zCDCbkp9C9cF+e9HPiI64lmpehyq2TepgXE+sY7FXr7Rhbb21prLMnhXX27/E11V09w==, + } + engines: { node: '>=16.13' } peerDependencies: prisma: '*' peerDependenciesMeta: @@ -801,75 +1479,195 @@ packages: optional: true '@prisma/debug@5.12.1': - resolution: {integrity: sha512-kd/wNsR0klrv79o1ITsbWxYyh4QWuBidvxsXSParPsYSu0ircUmNk3q4ojsgNc3/81b0ozg76iastOG43tbf8A==} - - '@prisma/debug@5.13.0': - resolution: {integrity: sha512-699iqlEvzyCj9ETrXhs8o8wQc/eVW+FigSsHpiskSFydhjVuwTJEfj/nIYqTaWFYuxiWQRfm3r01meuW97SZaQ==} - - '@prisma/engines-version@5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b': - resolution: {integrity: sha512-AyUuhahTINGn8auyqYdmxsN+qn0mw3eg+uhkp8zwknXYIqoT3bChG4RqNY/nfDkPvzWAPBa9mrDyBeOnWSgO6A==} - - '@prisma/engines@5.13.0': - resolution: {integrity: sha512-hIFLm4H1boj6CBZx55P4xKby9jgDTeDG0Jj3iXtwaaHmlD5JmiDkZhh8+DYWkTGchu+rRF36AVROLnk0oaqhHw==} - - '@prisma/fetch-engine@5.13.0': - resolution: {integrity: sha512-Yh4W+t6YKyqgcSEB3odBXt7QyVSm0OQlBSldQF2SNXtmOgMX8D7PF/fvH6E6qBCpjB/yeJLy/FfwfFijoHI6sA==} + resolution: + { + integrity: sha512-kd/wNsR0klrv79o1ITsbWxYyh4QWuBidvxsXSParPsYSu0ircUmNk3q4ojsgNc3/81b0ozg76iastOG43tbf8A==, + } + + '@prisma/debug@5.15.0': + resolution: + { + integrity: sha512-QpEAOjieLPc/4sMny/WrWqtpIAmBYsgqwWlWwIctqZO0AbhQ9QcT6x2Ut3ojbDo/pFRCCA1Z1+xm2MUy7fAkZA==, + } + + '@prisma/engines-version@5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022': + resolution: + { + integrity: sha512-3BEgZ41Qb4oWHz9kZNofToRvNeS4LZYaT9pienR1gWkjhky6t6K1NyeWNBkqSj2llgraUNbgMOCQPY4f7Qp5wA==, + } + + '@prisma/engines@5.15.0': + resolution: + { + integrity: sha512-hXL5Sn9hh/ZpRKWiyPA5GbvF3laqBHKt6Vo70hYqqOhh5e0ZXDzHcdmxNvOefEFeqxra2DMz2hNbFoPvqrVe1w==, + } + + '@prisma/fetch-engine@5.15.0': + resolution: + { + integrity: sha512-z6AY5yyXxc20Klj7wwnfGP0iIUkVKzybqapT02zLYR/nf9ynaeN8bq73WRmi1TkLYn+DJ5Qy+JGu7hBf1pE78A==, + } '@prisma/generator-helper@5.12.1': - resolution: {integrity: sha512-TlaI4J6jDKO06P68ve5czz1SionzI5ciUIw2tWFO4FM4qPID5+7nrxTVlecFTUD7Nc+IaO1hYT1YBOPKLiUncQ==} - - '@prisma/get-platform@5.13.0': - resolution: {integrity: sha512-B/WrQwYTzwr7qCLifQzYOmQhZcFmIFhR81xC45gweInSUn2hTEbfKUPd2keAog+y5WI5xLAFNJ3wkXplvSVkSw==} + resolution: + { + integrity: sha512-TlaI4J6jDKO06P68ve5czz1SionzI5ciUIw2tWFO4FM4qPID5+7nrxTVlecFTUD7Nc+IaO1hYT1YBOPKLiUncQ==, + } + + '@prisma/get-platform@5.15.0': + resolution: + { + integrity: sha512-1GULDkW4+/VQb73vihxCBSc4Chc2x88MA+O40tcZFjmBzG4/fF44PaXFxUqKSFltxU9L9GIMLhh0Gfkk/pUbtg==, + } + + '@protobufjs/aspromise@1.1.2': + resolution: + { + integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==, + } + + '@protobufjs/base64@1.1.2': + resolution: + { + integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==, + } + + '@protobufjs/codegen@2.0.4': + resolution: + { + integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==, + } + + '@protobufjs/eventemitter@1.1.0': + resolution: + { + integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==, + } + + '@protobufjs/fetch@1.1.0': + resolution: + { + integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==, + } + + '@protobufjs/float@1.0.2': + resolution: + { + integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==, + } + + '@protobufjs/inquire@1.1.0': + resolution: + { + integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==, + } + + '@protobufjs/path@1.1.2': + resolution: + { + integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==, + } + + '@protobufjs/pool@1.1.0': + resolution: + { + integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==, + } + + '@protobufjs/utf8@1.1.0': + resolution: + { + integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==, + } '@redis/bloom@1.2.0': - resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==} + resolution: + { + integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==, + } peerDependencies: '@redis/client': ^1.0.0 '@redis/client@1.5.14': - resolution: {integrity: sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==, + } + engines: { node: '>=14' } '@redis/graph@1.1.1': - resolution: {integrity: sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==} + resolution: + { + integrity: sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==, + } peerDependencies: '@redis/client': ^1.0.0 '@redis/json@1.0.6': - resolution: {integrity: sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==} + resolution: + { + integrity: sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==, + } peerDependencies: '@redis/client': ^1.0.0 '@redis/search@1.1.6': - resolution: {integrity: sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==} + resolution: + { + integrity: sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==, + } peerDependencies: '@redis/client': ^1.0.0 '@redis/time-series@1.0.5': - resolution: {integrity: sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==} + resolution: + { + integrity: sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==, + } peerDependencies: '@redis/client': ^1.0.0 '@sideway/address@4.1.5': - resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + resolution: + { + integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==, + } '@sideway/formula@3.0.1': - resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + resolution: + { + integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==, + } '@sideway/pinpoint@2.0.0': - resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + resolution: + { + integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==, + } '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + resolution: + { + integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, + } '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + resolution: + { + integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==, + } '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + resolution: + { + integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, + } '@trivago/prettier-plugin-sort-imports@4.3.0': - resolution: {integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==} + resolution: + { + integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==, + } peerDependencies: '@vue/compiler-sfc': 3.x prettier: 2.x - 3.x @@ -878,137 +1676,281 @@ packages: optional: true '@tsconfig/node10@1.0.9': - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + resolution: + { + integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==, + } '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + resolution: + { + integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, + } '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + resolution: + { + integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, + } '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + resolution: + { + integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, + } '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + resolution: + { + integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, + } '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + resolution: + { + integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==, + } '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + resolution: + { + integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, + } '@types/babel__traverse@7.20.5': - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + resolution: + { + integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==, + } '@types/bcrypt@5.0.2': - resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==} + resolution: + { + integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==, + } '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + resolution: + { + integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==, + } '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + resolution: + { + integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, + } '@types/cookie-parser@1.4.7': - resolution: {integrity: sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==} + resolution: + { + integrity: sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==, + } '@types/cookiejar@2.1.5': - resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} + resolution: + { + integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==, + } '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + resolution: + { + integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==, + } '@types/eslint@8.56.2': - resolution: {integrity: sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==} + resolution: + { + integrity: sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==, + } '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + resolution: + { + integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==, + } '@types/express-serve-static-core@4.17.43': - resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} + resolution: + { + integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==, + } '@types/express@4.17.21': - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + resolution: + { + integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==, + } '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + resolution: + { + integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==, + } '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + resolution: + { + integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==, + } '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + resolution: + { + integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==, + } '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + resolution: + { + integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==, + } '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + resolution: + { + integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, + } '@types/jest@29.5.12': - resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} + resolution: + { + integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==, + } '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + resolution: + { + integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, + } '@types/jsonwebtoken@9.0.5': - resolution: {integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==} + resolution: + { + integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==, + } + + '@types/long@4.0.2': + resolution: + { + integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==, + } '@types/methods@1.1.4': - resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} + resolution: + { + integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==, + } '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + resolution: + { + integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==, + } '@types/mime@3.0.4': - resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} + resolution: + { + integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==, + } '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + resolution: + { + integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==, + } + + '@types/node-fetch@2.6.11': + resolution: + { + integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==, + } '@types/node@20.11.16': - resolution: {integrity: sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==} + resolution: + { + integrity: sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==, + } '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + resolution: + { + integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==, + } '@types/qs@6.9.11': - resolution: {integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==} + resolution: + { + integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==, + } '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + resolution: + { + integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==, + } '@types/semver@7.5.6': - resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + resolution: + { + integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==, + } '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + resolution: + { + integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==, + } '@types/serve-static@1.15.5': - resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} + resolution: + { + integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==, + } '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + resolution: + { + integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==, + } '@types/superagent@8.1.3': - resolution: {integrity: sha512-R/CfN6w2XsixLb1Ii8INfn+BT9sGPvw74OavfkW4SwY+jeUcAwLZv2+bXLJkndnimxjEBm0RPHgcjW9pLCa8cw==} + resolution: + { + integrity: sha512-R/CfN6w2XsixLb1Ii8INfn+BT9sGPvw74OavfkW4SwY+jeUcAwLZv2+bXLJkndnimxjEBm0RPHgcjW9pLCa8cw==, + } '@types/supertest@6.0.2': - resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==} + resolution: + { + integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==, + } '@types/uuid@9.0.8': - resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + resolution: + { + integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==, + } '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + resolution: + { + integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==, + } '@types/yargs@17.0.32': - resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + resolution: + { + integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==, + } '@typescript-eslint/eslint-plugin@7.5.0': - resolution: {integrity: sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==, + } + engines: { node: ^18.18.0 || >=20.0.0 } peerDependencies: '@typescript-eslint/parser': ^7.0.0 eslint: ^8.56.0 @@ -1018,8 +1960,11 @@ packages: optional: true '@typescript-eslint/parser@7.5.0': - resolution: {integrity: sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==, + } + engines: { node: ^18.18.0 || >=20.0.0 } peerDependencies: eslint: ^8.56.0 typescript: '*' @@ -1028,12 +1973,18 @@ packages: optional: true '@typescript-eslint/scope-manager@7.5.0': - resolution: {integrity: sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==, + } + engines: { node: ^18.18.0 || >=20.0.0 } '@typescript-eslint/type-utils@7.5.0': - resolution: {integrity: sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==, + } + engines: { node: ^18.18.0 || >=20.0.0 } peerDependencies: eslint: ^8.56.0 typescript: '*' @@ -1042,12 +1993,18 @@ packages: optional: true '@typescript-eslint/types@7.5.0': - resolution: {integrity: sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==, + } + engines: { node: ^18.18.0 || >=20.0.0 } '@typescript-eslint/typescript-estree@7.5.0': - resolution: {integrity: sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==, + } + engines: { node: ^18.18.0 || >=20.0.0 } peerDependencies: typescript: '*' peerDependenciesMeta: @@ -1055,105 +2012,192 @@ packages: optional: true '@typescript-eslint/utils@7.5.0': - resolution: {integrity: sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==, + } + engines: { node: ^18.18.0 || >=20.0.0 } peerDependencies: eslint: ^8.56.0 '@typescript-eslint/visitor-keys@7.5.0': - resolution: {integrity: sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==} - engines: {node: ^18.18.0 || >=20.0.0} + resolution: + { + integrity: sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==, + } + engines: { node: ^18.18.0 || >=20.0.0 } '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + resolution: + { + integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==, + } '@webassemblyjs/ast@1.11.6': - resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} + resolution: + { + integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==, + } '@webassemblyjs/floating-point-hex-parser@1.11.6': - resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + resolution: + { + integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==, + } '@webassemblyjs/helper-api-error@1.11.6': - resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + resolution: + { + integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==, + } '@webassemblyjs/helper-buffer@1.11.6': - resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==} + resolution: + { + integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==, + } '@webassemblyjs/helper-numbers@1.11.6': - resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + resolution: + { + integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==, + } '@webassemblyjs/helper-wasm-bytecode@1.11.6': - resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + resolution: + { + integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==, + } '@webassemblyjs/helper-wasm-section@1.11.6': - resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==} + resolution: + { + integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==, + } '@webassemblyjs/ieee754@1.11.6': - resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + resolution: + { + integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==, + } '@webassemblyjs/leb128@1.11.6': - resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + resolution: + { + integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==, + } '@webassemblyjs/utf8@1.11.6': - resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + resolution: + { + integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==, + } '@webassemblyjs/wasm-edit@1.11.6': - resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==} + resolution: + { + integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==, + } '@webassemblyjs/wasm-gen@1.11.6': - resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==} + resolution: + { + integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==, + } '@webassemblyjs/wasm-opt@1.11.6': - resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==} + resolution: + { + integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==, + } '@webassemblyjs/wasm-parser@1.11.6': - resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==} + resolution: + { + integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==, + } '@webassemblyjs/wast-printer@1.11.6': - resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==} + resolution: + { + integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==, + } '@xtuc/ieee754@1.2.0': - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + resolution: + { + integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==, + } '@xtuc/long@4.2.2': - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + resolution: + { + integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==, + } JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + resolution: + { + integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==, + } hasBin: true abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + resolution: + { + integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==, + } accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, + } + engines: { node: '>= 0.6' } acorn-import-assertions@1.9.0: - resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + resolution: + { + integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==, + } peerDependencies: acorn: ^8 acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + resolution: + { + integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, + } peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==, + } + engines: { node: '>=0.4.0' } acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==, + } + engines: { node: '>=0.4.0' } hasBin: true agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + resolution: + { + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, + } + engines: { node: '>= 6.0.0' } ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + resolution: + { + integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==, + } peerDependencies: ajv: ^8.0.0 peerDependenciesMeta: @@ -1161,430 +2205,791 @@ packages: optional: true ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + resolution: + { + integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==, + } peerDependencies: ajv: ^6.9.1 ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + resolution: + { + integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, + } ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + resolution: + { + integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==, + } ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==, + } + engines: { node: '>=6' } ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, + } + engines: { node: '>=8' } ansi-escapes@6.2.1: - resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==, + } + engines: { node: '>=14.16' } ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: '>=8' } ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==, + } + engines: { node: '>=12' } ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, + } + engines: { node: '>=4' } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: '>=8' } ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: '>=10' } ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, + } + engines: { node: '>=12' } anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, + } + engines: { node: '>= 8' } append-field@1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} + resolution: + { + integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==, + } aproba@2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + resolution: + { + integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==, + } are-we-there-yet@2.0.0: - resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==, + } + engines: { node: '>=10' } arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + resolution: + { + integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, + } argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + resolution: + { + integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==, + } array-ify@1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + resolution: + { + integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==, + } array-timsort@1.0.3: - resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + resolution: + { + integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==, + } array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, + } + engines: { node: '>=8' } arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==, + } + engines: { node: '>=0.10.0' } asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + resolution: + { + integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==, + } + + async-retry@1.3.3: + resolution: + { + integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==, + } asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } axios@1.6.8: - resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + resolution: + { + integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==, + } babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: '@babel/core': ^7.8.0 babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, + } + engines: { node: '>=8' } babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } babel-preset-current-node-syntax@1.0.1: - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + resolution: + { + integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==, + } peerDependencies: '@babel/core': ^7.0.0 babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: '@babel/core': ^7.0.0 + backo2@1.0.2: + resolution: + { + integrity: sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==, + } + balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + resolution: + { + integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, + } bcrypt@5.1.1: - resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==} - engines: {node: '>= 10.0.0'} + resolution: + { + integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==, + } + engines: { node: '>= 10.0.0' } binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==, + } + engines: { node: '>=8' } bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + resolution: + { + integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, + } body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + resolution: + { + integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==, + } + engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + resolution: + { + integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==, + } + engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + resolution: + { + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, + } braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==, + } + engines: { node: '>=8' } browserslist@4.22.3: - resolution: {integrity: sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + resolution: + { + integrity: sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==, + } + engines: { node: '>= 6' } bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + resolution: + { + integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, + } buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + resolution: + { + integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==, + } buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + resolution: + { + integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==, + } busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} + resolution: + { + integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==, + } + engines: { node: '>=10.16.0' } bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, + } + engines: { node: '>= 0.8' } cache-manager-redis-store@3.0.1: - resolution: {integrity: sha512-o560kw+dFqusC9lQJhcm6L2F2fMKobJ5af+FoR2PdnMVdpQ3f3Bz6qzvObTGyvoazQJxjQNWgMQeChP4vRTuXQ==} - engines: {node: '>= 16.18.0'} + resolution: + { + integrity: sha512-o560kw+dFqusC9lQJhcm6L2F2fMKobJ5af+FoR2PdnMVdpQ3f3Bz6qzvObTGyvoazQJxjQNWgMQeChP4vRTuXQ==, + } + engines: { node: '>= 16.18.0' } cache-manager@5.5.1: - resolution: {integrity: sha512-QYZFOjZTTennYdN3NNCKh+yq452+wQ4ChyL40jkEyghIgg5Ugwb4YO8ARIIF1fvTBkgDLlLTYFaxZVaPGmQ92A==} + resolution: + { + integrity: sha512-QYZFOjZTTennYdN3NNCKh+yq452+wQ4ChyL40jkEyghIgg5Ugwb4YO8ARIIF1fvTBkgDLlLTYFaxZVaPGmQ92A==, + } call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + resolution: + { + integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==, + } callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, + } + engines: { node: '>=6' } camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==, + } + engines: { node: '>=8' } camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, + } + engines: { node: '>=6' } camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, + } + engines: { node: '>=10' } caniuse-lite@1.0.30001583: - resolution: {integrity: sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==} + resolution: + { + integrity: sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==, + } chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, + } + engines: { node: '>=4' } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: '>=10' } chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + resolution: + { + integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==, + } + engines: { node: ^12.17.0 || ^14.13 || >=16.0.0 } char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, + } + engines: { node: '>=10' } chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + resolution: + { + integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==, + } chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} + resolution: + { + integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==, + } + engines: { node: '>= 8.10.0' } + + chokidar@3.6.0: + resolution: + { + integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, + } + engines: { node: '>= 8.10.0' } chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==, + } + engines: { node: '>=10' } chrome-trace-event@1.0.3: - resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==, + } + engines: { node: '>=6.0' } ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, + } + engines: { node: '>=8' } cjs-module-lexer@1.2.3: - resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + resolution: + { + integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==, + } cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==, + } + engines: { node: '>=8' } cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==, + } + engines: { node: '>=6' } cli-table3@0.6.3: - resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} - engines: {node: 10.* || >= 12.*} + resolution: + { + integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==, + } + engines: { node: 10.* || >= 12.* } cli-truncate@4.0.0: - resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==, + } + engines: { node: '>=18' } cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==, + } + engines: { node: '>= 10' } cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} + resolution: + { + integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==, + } + engines: { node: '>= 12' } cli@1.0.1: - resolution: {integrity: sha512-41U72MB56TfUMGndAKK8vJ78eooOD4Z5NOL4xEfjc0c23s+6EYKXlXsmACBVclLP1yOfWCgEganVzddVrSNoTg==} - engines: {node: '>=0.2.5'} + resolution: + { + integrity: sha512-41U72MB56TfUMGndAKK8vJ78eooOD4Z5NOL4xEfjc0c23s+6EYKXlXsmACBVclLP1yOfWCgEganVzddVrSNoTg==, + } + engines: { node: '>=0.2.5' } cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: '>=12' } clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} + resolution: + { + integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==, + } + engines: { node: '>=0.8' } cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==, + } + engines: { node: '>=0.10.0' } co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + resolution: + { + integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, + } + engines: { iojs: '>= 1.0.0', node: '>= 0.12.0' } collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + resolution: + { + integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, + } color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + resolution: + { + integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, + } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: '>=7.0.0' } color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + resolution: + { + integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, + } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } color-support@1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + resolution: + { + integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==, + } hasBin: true colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + resolution: + { + integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, + } combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: '>= 0.8' } commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==, + } + engines: { node: '>=14' } commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==, + } + engines: { node: '>=16' } commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + resolution: + { + integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, + } commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==, + } + engines: { node: '>= 6' } comment-json@4.2.3: - resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==, + } + engines: { node: '>= 6' } compare-func@2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + resolution: + { + integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==, + } component-emitter@1.3.1: - resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + resolution: + { + integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==, + } concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } concat-stream@1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} + resolution: + { + integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==, + } + engines: { '0': node >= 0.8 } consola@2.15.3: - resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} + resolution: + { + integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==, + } console-control-strings@1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + resolution: + { + integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==, + } content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==, + } + engines: { node: '>= 0.6' } content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, + } + engines: { node: '>= 0.6' } conventional-changelog-angular@7.0.0: - resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==, + } + engines: { node: '>=16' } conventional-changelog-conventionalcommits@7.0.2: - resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==, + } + engines: { node: '>=16' } conventional-commits-parser@5.0.0: - resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==, + } + engines: { node: '>=16' } hasBin: true convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } cookie-parser@1.4.6: - resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==, + } + engines: { node: '>= 0.8.0' } cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + resolution: + { + integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==, + } cookie@0.4.1: - resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==, + } + engines: { node: '>= 0.6' } cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==, + } + engines: { node: '>= 0.6' } cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + resolution: + { + integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==, + } core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + resolution: + { + integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==, + } cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==, + } + engines: { node: '>= 0.10' } cosmiconfig-typescript-loader@5.0.0: - resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} - engines: {node: '>=v16'} + resolution: + { + integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==, + } + engines: { node: '>=v16' } peerDependencies: '@types/node': '*' cosmiconfig: '>=8.2' typescript: '>=4' cosmiconfig@8.3.6: - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==, + } + engines: { node: '>=14' } peerDependencies: typescript: '>=4.9.5' peerDependenciesMeta: @@ -1592,26 +2997,57 @@ packages: optional: true create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } hasBin: true create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + resolution: + { + integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, + } + + cross-inspect@1.0.0: + resolution: + { + integrity: sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==, + } + engines: { node: '>=16.0.0' } cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, + } + engines: { node: '>= 8' } + + cssfilter@0.0.10: + resolution: + { + integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==, + } dargs@7.0.0: - resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==, + } + engines: { node: '>=8' } dayjs@1.11.10: - resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + resolution: + { + integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==, + } debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + resolution: + { + integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, + } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -1619,8 +3055,11 @@ packages: optional: true debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, + } + engines: { node: '>=6.0' } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -1628,15 +3067,24 @@ packages: optional: true decamelize-keys@1.1.1: - resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==, + } + engines: { node: '>=0.10.0' } decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==, + } + engines: { node: '>=0.10.0' } dedent@1.5.1: - resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + resolution: + { + integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==, + } peerDependencies: babel-plugin-macros: ^3.1.0 peerDependenciesMeta: @@ -1644,155 +3092,285 @@ packages: optional: true deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + resolution: + { + integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, + } deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, + } + engines: { node: '>=0.10.0' } defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + resolution: + { + integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==, + } define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==, + } + engines: { node: '>= 0.4' } delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: '>=0.4.0' } delegates@1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + resolution: + { + integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==, + } depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, + } + engines: { node: '>= 0.8' } destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + resolution: + { + integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==, + } + engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==, + } + engines: { node: '>=8' } detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, + } + engines: { node: '>=8' } detect-ts-node@1.0.5: - resolution: {integrity: sha512-lWACfJ+H6jpxT1uuIQi2KAIkczeHJcM4rmfbAR86gfmAlrJpCVZbnKB0fiqmH8TGw4dm9xrptfwNObEsDdvsFg==} + resolution: + { + integrity: sha512-lWACfJ+H6jpxT1uuIQi2KAIkczeHJcM4rmfbAR86gfmAlrJpCVZbnKB0fiqmH8TGw4dm9xrptfwNObEsDdvsFg==, + } dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + resolution: + { + integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==, + } diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} + resolution: + { + integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, + } + engines: { node: '>=0.3.1' } dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, + } + engines: { node: '>=8' } doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==, + } + engines: { node: '>=6.0.0' } dot-prop@5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==, + } + engines: { node: '>=8' } dotenv-expand@10.0.0: - resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==, + } + engines: { node: '>=12' } dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==, + } + engines: { node: '>=12' } drange@1.1.1: - resolution: {integrity: sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==, + } + engines: { node: '>=4' } + + dset@3.1.3: + resolution: + { + integrity: sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==, + } + engines: { node: '>=4' } eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + resolution: + { + integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, + } ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + resolution: + { + integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==, + } ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + resolution: + { + integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, + } electron-to-chromium@1.4.656: - resolution: {integrity: sha512-9AQB5eFTHyR3Gvt2t/NwR0le2jBSUNwCnMbUCejFWHD+so4tH40/dRLgoE+jxlPeWS43XJewyvCv+I8LPMl49Q==} + resolution: + { + integrity: sha512-9AQB5eFTHyR3Gvt2t/NwR0le2jBSUNwCnMbUCejFWHD+so4tH40/dRLgoE+jxlPeWS43XJewyvCv+I8LPMl49Q==, + } emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==, + } + engines: { node: '>=12' } emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + resolution: + { + integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==, + } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + resolution: + { + integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, + } encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==, + } + engines: { node: '>= 0.8' } enhanced-resolve@5.15.0: - resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==, + } + engines: { node: '>=10.13.0' } error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + resolution: + { + integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, + } es-errors@1.0.0: - resolution: {integrity: sha512-yHV74THqMJUyFKkHyN7hyENcEZM3Dj2a2IrdClY+IT4BFQHkIVwlh8s6uZfjsFydMdNHv0F5mWgAA3ajFbsvVQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-yHV74THqMJUyFKkHyN7hyENcEZM3Dj2a2IrdClY+IT4BFQHkIVwlh8s6uZfjsFydMdNHv0F5mWgAA3ajFbsvVQ==, + } + engines: { node: '>= 0.4' } es-module-lexer@1.4.1: - resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + resolution: + { + integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==, + } escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, + } + engines: { node: '>=6' } escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + resolution: + { + integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, + } escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + resolution: + { + integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, + } + engines: { node: '>=0.8.0' } escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, + } + engines: { node: '>=8' } escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, + } + engines: { node: '>=10' } escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==, + } + engines: { node: '>=12' } eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + resolution: + { + integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==, + } hasBin: true peerDependencies: eslint: '>=7.0.0' eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} - engines: {node: ^14.18.0 || >=16.0.0} + resolution: + { + integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==, + } + engines: { node: ^14.18.0 || >=16.0.0 } peerDependencies: '@types/eslint': '>=8.0.0' eslint: '>=8.0.0' @@ -1805,149 +3383,275 @@ packages: optional: true eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} + resolution: + { + integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==, + } + engines: { node: '>=8.0.0' } eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } hasBin: true espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: '>=4' } hasBin: true esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} + resolution: + { + integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==, + } + engines: { node: '>=0.10' } esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, + } + engines: { node: '>=4.0' } estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==, + } + engines: { node: '>=4.0' } estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, + } + engines: { node: '>=4.0' } esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: '>=0.10.0' } etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, + } + engines: { node: '>= 0.6' } + + eventemitter2@6.4.9: + resolution: + { + integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==, + } + + eventemitter3@3.1.2: + resolution: + { + integrity: sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==, + } eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + resolution: + { + integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==, + } events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} + resolution: + { + integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, + } + engines: { node: '>=0.8.x' } execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, + } + engines: { node: '>=10' } execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} + resolution: + { + integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==, + } + engines: { node: '>=16.17' } exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, + } + engines: { node: '>= 0.8.0' } expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} + resolution: + { + integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==, + } + engines: { node: '>= 0.10.0' } external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==, + } + engines: { node: '>=4' } fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + resolution: + { + integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, + } fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + resolution: + { + integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==, + } fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} + resolution: + { + integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==, + } + engines: { node: '>=8.6.0' } fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + resolution: + { + integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, + } fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + resolution: + { + integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, + } fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + resolution: + { + integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==, + } fastq@1.17.0: - resolution: {integrity: sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==} + resolution: + { + integrity: sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==, + } fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + resolution: + { + integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, + } figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==, + } + engines: { node: '>=8' } figures@5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==, + } + engines: { node: '>=14' } file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + resolution: + { + integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==, + } + engines: { node: ^10.12.0 || >=12.0.0 } fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, + } + engines: { node: '>=8' } finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==, + } + engines: { node: '>= 0.8' } find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, + } + engines: { node: '>=8' } find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, + } + engines: { node: '>=10' } flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + resolution: + { + integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==, + } + engines: { node: ^10.12.0 || >=12.0.0 } flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + resolution: + { + integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==, + } follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==, + } + engines: { node: '>=4.0' } peerDependencies: debug: '*' peerDependenciesMeta: @@ -1955,401 +3659,741 @@ packages: optional: true foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==, + } + engines: { node: '>=14' } fork-ts-checker-webpack-plugin@9.0.2: - resolution: {integrity: sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==} - engines: {node: '>=12.13.0', yarn: '>=1.0.0'} + resolution: + { + integrity: sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==, + } + engines: { node: '>=12.13.0', yarn: '>=1.0.0' } peerDependencies: typescript: '>3.6.0' webpack: ^5.11.0 form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, + } + engines: { node: '>= 6' } formidable@2.1.2: - resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} + resolution: + { + integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==, + } forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, + } + engines: { node: '>= 0.6' } fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==, + } + engines: { node: '>= 0.6' } fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==, + } + engines: { node: '>=12' } fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==, + } + engines: { node: '>= 8' } fs-monkey@1.0.5: - resolution: {integrity: sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==} + resolution: + { + integrity: sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==, + } fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + resolution: + { + integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, + } fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } gauge@3.0.2: - resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==, + } + engines: { node: '>=10' } generic-pool@3.9.0: - resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==, + } + engines: { node: '>= 4' } gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: '>=6.9.0' } get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } get-east-asian-width@1.2.0: - resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==, + } + engines: { node: '>=18' } get-function-location@2.0.0: - resolution: {integrity: sha512-dbLV+YYZWZS/zEOrGWH0a3ASX5ffYsAP43BUxF9dOWz2zKzqhrvojAqu3JrQQiTROFujsSnAWasYCRfsq0n6Ig==} - engines: {node: 6.* || 8.* || 10.* || >= 11} + resolution: + { + integrity: sha512-dbLV+YYZWZS/zEOrGWH0a3ASX5ffYsAP43BUxF9dOWz2zKzqhrvojAqu3JrQQiTROFujsSnAWasYCRfsq0n6Ig==, + } + engines: { node: 6.* || 8.* || 10.* || >= 11 } get-intrinsic@1.2.3: - resolution: {integrity: sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==, + } + engines: { node: '>= 0.4' } get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} + resolution: + { + integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, + } + engines: { node: '>=8.0.0' } get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, + } + engines: { node: '>=10' } get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==, + } + engines: { node: '>=16' } git-raw-commits@2.0.11: - resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==, + } + engines: { node: '>=10' } hasBin: true glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, + } + engines: { node: '>= 6' } glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, + } + engines: { node: '>=10.13.0' } glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + resolution: + { + integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==, + } glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==, + } + engines: { node: '>=16 || 14 >=14.17' } hasBin: true glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + resolution: + { + integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, + } glob@9.3.5: - resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==, + } + engines: { node: '>=16 || 14 >=14.17' } global-dirs@0.1.1: - resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==, + } + engines: { node: '>=4' } global-prefix@3.0.0: - resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==, + } + engines: { node: '>=6' } globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, + } + engines: { node: '>=4' } globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==, + } + engines: { node: '>=8' } globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, + } + engines: { node: '>=10' } gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + resolution: + { + integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==, + } graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + resolution: + { + integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, + } graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + resolution: + { + integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, + } + + graphql-tag@2.12.6: + resolution: + { + integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==, + } + engines: { node: '>=10' } + peerDependencies: + graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + + graphql-ws@5.14.3: + resolution: + { + integrity: sha512-F/i2xNIVbaEF2xWggID0X/UZQa2V8kqKDPO8hwmu53bVOcTL7uNkxnexeEgSCVxYBQUTUNEI8+e4LO1FOhKPKQ==, + } + engines: { node: '>=10' } + peerDependencies: + graphql: '>=0.11 <=16' + + graphql@16.8.1: + resolution: + { + integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==, + } + engines: { node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0 } hard-rejection@2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==, + } + engines: { node: '>=6' } has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, + } + engines: { node: '>=4' } has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: '>=8' } has-own-prop@2.0.0: - resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==, + } + engines: { node: '>=8' } has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + resolution: + { + integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==, + } has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==, + } + engines: { node: '>= 0.4' } has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==, + } + engines: { node: '>= 0.4' } has-unicode@2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + resolution: + { + integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==, + } hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==, + } + engines: { node: '>= 0.4' } hexoid@1.0.0: - resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==, + } + engines: { node: '>=8' } hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + resolution: + { + integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==, + } hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==, + } + engines: { node: '>=10' } html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + resolution: + { + integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, + } http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==, + } + engines: { node: '>= 0.8' } https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, + } + engines: { node: '>= 6' } human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} + resolution: + { + integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, + } + engines: { node: '>=10.17.0' } human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} + resolution: + { + integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==, + } + engines: { node: '>=16.17.0' } husky@9.0.11: - resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==, + } + engines: { node: '>=18' } hasBin: true iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, + } + engines: { node: '>=0.10.0' } ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + resolution: + { + integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, + } ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==, + } + engines: { node: '>= 4' } import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==, + } + engines: { node: '>=6' } import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==, + } + engines: { node: '>=8' } hasBin: true import2@1.0.3: - resolution: {integrity: sha512-X7KHNp1fovFaiah9Q+njdxXJKIV9/XippWGZwHL9ZdJYnQPBs+4wLd4PuCigbxz2IWNm5YvFycSjRA/1lgmdGw==} + resolution: + { + integrity: sha512-X7KHNp1fovFaiah9Q+njdxXJKIV9/XippWGZwHL9ZdJYnQPBs+4wLd4PuCigbxz2IWNm5YvFycSjRA/1lgmdGw==, + } imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: '>=0.8.19' } indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, + } + engines: { node: '>=8' } inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + resolution: + { + integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, + } inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + resolution: + { + integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, + } inquirer@8.2.6: - resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==, + } + engines: { node: '>=12.0.0' } inquirer@9.2.11: - resolution: {integrity: sha512-B2LafrnnhbRzCWfAdOXisUzL89Kg8cVJlYmhqoi3flSiV/TveO+nsXwgKr9h9PIo+J1hz7nBSk6gegRIMBBf7g==} - engines: {node: '>=14.18.0'} + resolution: + { + integrity: sha512-B2LafrnnhbRzCWfAdOXisUzL89Kg8cVJlYmhqoi3flSiV/TveO+nsXwgKr9h9PIo+J1hz7nBSk6gegRIMBBf7g==, + } + engines: { node: '>=14.18.0' } interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==, + } + engines: { node: '>= 0.10' } ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, + } + engines: { node: '>= 0.10' } is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + resolution: + { + integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, + } is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, + } + engines: { node: '>=8' } is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + resolution: + { + integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==, + } is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, + } + engines: { node: '>=0.10.0' } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: '>=8' } is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==, + } + engines: { node: '>=12' } is-fullwidth-code-point@5.0.0: - resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==, + } + engines: { node: '>=18' } is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, + } + engines: { node: '>=6' } is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, + } + engines: { node: '>=0.10.0' } is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==, + } + engines: { node: '>=8' } is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: '>=0.12.0' } is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==, + } + engines: { node: '>=8' } is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==, + } + engines: { node: '>=8' } is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==, + } + engines: { node: '>=0.10.0' } is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, + } + engines: { node: '>=8' } is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } is-text-path@2.0.0: - resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==, + } + engines: { node: '>=8' } is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==, + } + engines: { node: '>=10' } is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==, + } + engines: { node: '>=12' } isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + resolution: + { + integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==, + } isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, + } + engines: { node: '>=8' } istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, + } + engines: { node: '>=8' } istanbul-lib-instrument@6.0.1: - resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==, + } + engines: { node: '>=10' } istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, + } + engines: { node: '>=10' } istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, + } + engines: { node: '>=10' } istanbul-reports@3.1.6: - resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==, + } + engines: { node: '>=8' } + + iterall@1.3.0: + resolution: + { + integrity: sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==, + } iterare@1.2.1: - resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==, + } + engines: { node: '>=6' } jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==, + } + engines: { node: '>=14' } javascript-natural-sort@0.7.1: - resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} + resolution: + { + integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==, + } jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2358,8 +4402,11 @@ packages: optional: true jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } peerDependencies: '@types/node': '*' ts-node: '>=9.0.0' @@ -2370,48 +4417,81 @@ packages: optional: true jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-pnp-resolver@1.2.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, + } + engines: { node: '>=6' } peerDependencies: jest-resolve: '*' peerDependenciesMeta: @@ -2419,52 +4499,88 @@ packages: optional: true jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} + resolution: + { + integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==, + } + engines: { node: '>= 10.13.0' } jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } hasBin: true peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2473,384 +4589,731 @@ packages: optional: true jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + resolution: + { + integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==, + } hasBin: true joi@17.12.3: - resolution: {integrity: sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==} + resolution: + { + integrity: sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==, + } js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + resolution: + { + integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, + } hasBin: true js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + resolution: + { + integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, + } hasBin: true jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, + } + engines: { node: '>=4' } hasBin: true json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + resolution: + { + integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, + } json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + resolution: + { + integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, + } json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + resolution: + { + integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, + } json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + resolution: + { + integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, + } json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + resolution: + { + integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, + } json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: '>=6' } hasBin: true jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + resolution: + { + integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==, + } jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + resolution: + { + integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, + } jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} + resolution: + { + integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==, + } + engines: { '0': node >= 0.2.0 } jsonwebtoken@9.0.2: - resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} - engines: {node: '>=12', npm: '>=6'} + resolution: + { + integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==, + } + engines: { node: '>=12', npm: '>=6' } jwa@1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + resolution: + { + integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==, + } jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + resolution: + { + integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==, + } keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + resolution: + { + integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, + } kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, + } + engines: { node: '>=0.10.0' } kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, + } + engines: { node: '>=6' } leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, + } + engines: { node: '>=6' } levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, + } + engines: { node: '>= 0.8.0' } lilconfig@3.0.0: - resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==, + } + engines: { node: '>=14' } lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } lint-staged@15.2.2: - resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==} - engines: {node: '>=18.12.0'} + resolution: + { + integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==, + } + engines: { node: '>=18.12.0' } hasBin: true listr2@8.0.1: - resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==, + } + engines: { node: '>=18.0.0' } loader-runner@4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} - engines: {node: '>=6.11.5'} + resolution: + { + integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==, + } + engines: { node: '>=6.11.5' } locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, + } + engines: { node: '>=8' } locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, + } + engines: { node: '>=10' } lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + resolution: + { + integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==, + } lodash.clonedeep@4.5.0: - resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + resolution: + { + integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==, + } lodash.includes@4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + resolution: + { + integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==, + } lodash.isboolean@3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + resolution: + { + integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==, + } lodash.isfunction@3.0.9: - resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + resolution: + { + integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==, + } lodash.isinteger@4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + resolution: + { + integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==, + } lodash.isnumber@3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + resolution: + { + integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==, + } lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + resolution: + { + integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==, + } lodash.isstring@4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + resolution: + { + integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==, + } lodash.kebabcase@4.1.1: - resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + resolution: + { + integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==, + } lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + resolution: + { + integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==, + } lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + resolution: + { + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, + } lodash.mergewith@4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + resolution: + { + integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==, + } + + lodash.omit@4.5.0: + resolution: + { + integrity: sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==, + } lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + resolution: + { + integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==, + } lodash.snakecase@4.1.1: - resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + resolution: + { + integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==, + } + + lodash.sortby@4.7.0: + resolution: + { + integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==, + } lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + resolution: + { + integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==, + } lodash.uniq@4.5.0: - resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + resolution: + { + integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==, + } lodash.upperfirst@4.3.1: - resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + resolution: + { + integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==, + } lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + resolution: + { + integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, + } log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==, + } + engines: { node: '>=10' } log-update@6.0.0: - resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==, + } + engines: { node: '>=18' } + + loglevel@1.9.1: + resolution: + { + integrity: sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==, + } + engines: { node: '>= 0.6.0' } + + long@4.0.0: + resolution: + { + integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==, + } lru-cache@10.2.0: - resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} - engines: {node: 14 || >=16.14} + resolution: + { + integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==, + } + engines: { node: 14 || >=16.14 } lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, + } + engines: { node: '>=10' } + + lru-cache@7.18.3: + resolution: + { + integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==, + } + engines: { node: '>=12' } magic-string@0.30.5: - resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==, + } + engines: { node: '>=12' } make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==, + } + engines: { node: '>=8' } make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, + } + engines: { node: '>=10' } make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + resolution: + { + integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, + } makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + resolution: + { + integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, + } map-obj@1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==, + } + engines: { node: '>=0.10.0' } map-obj@4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==, + } + engines: { node: '>=8' } media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==, + } + engines: { node: '>= 0.6' } memfs@3.5.3: - resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} - engines: {node: '>= 4.0.0'} + resolution: + { + integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==, + } + engines: { node: '>= 4.0.0' } meow@12.1.1: - resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} - engines: {node: '>=16.10'} + resolution: + { + integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==, + } + engines: { node: '>=16.10' } meow@8.1.2: - resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==, + } + engines: { node: '>=10' } merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + resolution: + { + integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==, + } merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, + } + engines: { node: '>= 8' } methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==, + } + engines: { node: '>= 0.6' } micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==, + } + engines: { node: '>=8.6' } mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: '>= 0.6' } mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: '>= 0.6' } mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, + } + engines: { node: '>=4' } hasBin: true mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} + resolution: + { + integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==, + } + engines: { node: '>=4.0.0' } hasBin: true mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: '>=6' } mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, + } + engines: { node: '>=12' } min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==, + } + engines: { node: '>=4' } minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } minimatch@8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==, + } + engines: { node: '>=16 || 14 >=14.17' } minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==, + } + engines: { node: '>=16 || 14 >=14.17' } minimist-options@4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==, + } + engines: { node: '>= 6' } minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + resolution: + { + integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, + } minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==, + } + engines: { node: '>=8' } minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==, + } + engines: { node: '>=8' } minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==, + } + engines: { node: '>=8' } minipass@7.0.4: - resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==, + } + engines: { node: '>=16 || 14 >=14.17' } minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==, + } + engines: { node: '>= 8' } mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + resolution: + { + integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==, + } hasBin: true mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==, + } + engines: { node: '>=10' } hasBin: true ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + resolution: + { + integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, + } ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } multer@1.4.4-lts.1: - resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} - engines: {node: '>= 6.0.0'} + resolution: + { + integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==, + } + engines: { node: '>= 6.0.0' } multer@1.4.5-lts.1: - resolution: {integrity: sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==} - engines: {node: '>= 6.0.0'} + resolution: + { + integrity: sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==, + } + engines: { node: '>= 6.0.0' } mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + resolution: + { + integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==, + } mute-stream@1.0.0: - resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + resolution: + { + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, + } negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, + } + engines: { node: '>= 0.6' } neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + resolution: + { + integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==, + } nestia@5.3.0: - resolution: {integrity: sha512-1xtpWDer2r3IVbfP7tUlYqO1ocQ6oKyA80s0fbXTX0lgnUZCZBlYVmYbnzF/FsLDpKyfvF+ZJEGsZsRcUZ4aiA==} + resolution: + { + integrity: sha512-1xtpWDer2r3IVbfP7tUlYqO1ocQ6oKyA80s0fbXTX0lgnUZCZBlYVmYbnzF/FsLDpKyfvF+ZJEGsZsRcUZ4aiA==, + } hasBin: true nestjs-twilio@4.4.0: - resolution: {integrity: sha512-TtT+mgVaIsiGNX1J8zkjVhIBxJPsChfU8gfu6dbPyEtde9ewgb5sxhAreOE6STT5U95OiSAlFcqKoqlARCIFxA==} + resolution: + { + integrity: sha512-TtT+mgVaIsiGNX1J8zkjVhIBxJPsChfU8gfu6dbPyEtde9ewgb5sxhAreOE6STT5U95OiSAlFcqKoqlARCIFxA==, + } peerDependencies: '@nestjs/common': '>=9.0.0' '@nestjs/core': '>=9.0.0' node-abort-controller@3.1.1: - resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + resolution: + { + integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==, + } node-addon-api@5.1.0: - resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + resolution: + { + integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==, + } node-emoji@1.11.0: - resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + resolution: + { + integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==, + } node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} + resolution: + { + integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==, + } + engines: { node: 4.x || >=6.0.0 } peerDependencies: encoding: ^0.1.0 peerDependenciesMeta: @@ -2858,625 +5321,1147 @@ packages: optional: true node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + resolution: + { + integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, + } node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + resolution: + { + integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==, + } nopt@5.0.0: - resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==, + } + engines: { node: '>=6' } hasBin: true normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + resolution: + { + integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==, + } normalize-package-data@3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==, + } + engines: { node: '>=10' } normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, + } + engines: { node: '>=0.10.0' } npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, + } + engines: { node: '>=8' } npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } npmlog@5.0.1: - resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + resolution: + { + integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==, + } object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: '>=0.10.0' } object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + resolution: + { + integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==, + } on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, + } + engines: { node: '>= 0.8' } once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: '>=6' } onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, + } + engines: { node: '>=12' } optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==, + } + engines: { node: '>= 0.8.0' } ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==, + } + engines: { node: '>=10' } os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==, + } + engines: { node: '>=0.10.0' } p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, + } + engines: { node: '>=6' } p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: '>=10' } p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: '>=8' } p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, + } + engines: { node: '>=10' } p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + } + engines: { node: '>=6' } parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, + } + engines: { node: '>=6' } parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, + } + engines: { node: '>=8' } parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, + } + engines: { node: '>= 0.8' } path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: '>=8' } path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, + } + engines: { node: '>=0.10.0' } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: '>=8' } path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, + } + engines: { node: '>=12' } path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } path-scurry@1.10.1: - resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==, + } + engines: { node: '>=16 || 14 >=14.17' } path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + resolution: + { + integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==, + } path-to-regexp@3.2.0: - resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} + resolution: + { + integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==, + } path-to-regexp@6.2.1: - resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + resolution: + { + integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==, + } path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, + } + engines: { node: '>=8' } picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + resolution: + { + integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, + } picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, + } + engines: { node: '>=8.6' } picomatch@3.0.1: - resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==, + } + engines: { node: '>=10' } pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} + resolution: + { + integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==, + } + engines: { node: '>=0.10' } hasBin: true pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, + } + engines: { node: '>= 6' } pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, + } + engines: { node: '>=8' } pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==, + } + engines: { node: '>=4' } prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, + } + engines: { node: '>= 0.8.0' } prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==, + } + engines: { node: '>=6.0.0' } prettier@3.2.5: - resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==, + } + engines: { node: '>=14' } hasBin: true pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } prisma-markdown@1.0.9: - resolution: {integrity: sha512-Y/aWUgDnzYt7JFjhUOmLzNs+09eoITq8ZK9CmG3L6TTKc/prYr+2EClD4jRcfEgyElfJlvH2/4QeZponu9D92Q==} + resolution: + { + integrity: sha512-Y/aWUgDnzYt7JFjhUOmLzNs+09eoITq8ZK9CmG3L6TTKc/prYr+2EClD4jRcfEgyElfJlvH2/4QeZponu9D92Q==, + } hasBin: true peerDependencies: '@prisma/client': '>= 5.0.0' prisma: '>= 5.0.0' - prisma@5.13.0: - resolution: {integrity: sha512-kGtcJaElNRAdAGsCNykFSZ7dBKpL14Cbs+VaQ8cECxQlRPDjBlMHNFYeYt0SKovAVy2Y65JXQwB3A5+zIQwnTg==} - engines: {node: '>=16.13'} + prisma@5.15.0: + resolution: + { + integrity: sha512-JA81ACQSCi3a7NUOgonOIkdx8PAVkO+HbUOxmd00Yb8DgIIEpr2V9+Qe/j6MLxIgWtE/OtVQ54rVjfYRbZsCfw==, + } + engines: { node: '>=16.13' } hasBin: true process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + resolution: + { + integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==, + } promise-coalesce@1.1.2: - resolution: {integrity: sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg==, + } + engines: { node: '>=16' } prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, + } + engines: { node: '>= 6' } proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, + } + engines: { node: '>= 0.10' } proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + resolution: + { + integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, + } punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: '>=6' } pure-rand@6.0.4: - resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==} + resolution: + { + integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==, + } qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==, + } + engines: { node: '>=0.6' } qs@6.11.2: - resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==, + } + engines: { node: '>=0.6' } querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + resolution: + { + integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==, + } queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, + } quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==, + } + engines: { node: '>=8' } randexp@0.5.3: - resolution: {integrity: sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==, + } + engines: { node: '>=4' } randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + resolution: + { + integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==, + } range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, + } + engines: { node: '>= 0.6' } raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==, + } + engines: { node: '>= 0.8' } raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==, + } + engines: { node: '>= 0.8' } react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + resolution: + { + integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==, + } read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==, + } + engines: { node: '>=8' } read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==, + } + engines: { node: '>=8' } readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + resolution: + { + integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==, + } readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, + } + engines: { node: '>= 6' } readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + resolution: + { + integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, + } + engines: { node: '>=8.10.0' } rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==, + } + engines: { node: '>= 0.10' } redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==, + } + engines: { node: '>=8' } redis@4.6.13: - resolution: {integrity: sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==} + resolution: + { + integrity: sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==, + } reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + resolution: + { + integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==, + } repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} + resolution: + { + integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==, + } + engines: { node: '>=0.10' } require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: '>=0.10.0' } require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, + } + engines: { node: '>=0.10.0' } requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resolution: + { + integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, + } resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, + } + engines: { node: '>=8' } resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, + } + engines: { node: '>=4' } resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, + } + engines: { node: '>=8' } resolve-global@1.0.0: - resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==, + } + engines: { node: '>=8' } resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==, + } + engines: { node: '>=10' } resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + resolution: + { + integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, + } hasBin: true restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==, + } + engines: { node: '>=8' } restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } ret@0.2.2: - resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==, + } + engines: { node: '>=4' } + + retry@0.13.1: + resolution: + { + integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==, + } + engines: { node: '>= 4' } reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + resolution: + { + integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, + } + engines: { iojs: '>=1.0.0', node: '>=0.10.0' } rfdc@1.3.1: - resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + resolution: + { + integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==, + } rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + resolution: + { + integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, + } hasBin: true rimraf@4.4.1: - resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==, + } + engines: { node: '>=14' } hasBin: true run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==, + } + engines: { node: '>=0.12.0' } run-async@3.0.0: - resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==, + } + engines: { node: '>=0.12.0' } run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, + } rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + resolution: + { + integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==, + } safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + resolution: + { + integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, + } safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} - engines: {node: '>= 10.13.0'} + resolution: + { + integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==, + } + engines: { node: '>= 10.13.0' } scmp@2.1.0: - resolution: {integrity: sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==} + resolution: + { + integrity: sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==, + } semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + resolution: + { + integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==, + } hasBin: true semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } hasBin: true semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==, + } + engines: { node: '>=10' } hasBin: true semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==, + } + engines: { node: '>=10' } hasBin: true send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==, + } + engines: { node: '>= 0.8.0' } serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + resolution: + { + integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==, + } serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==, + } + engines: { node: '>= 0.8.0' } set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + resolution: + { + integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==, + } set-function-length@1.2.0: - resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==, + } + engines: { node: '>= 0.4' } setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + resolution: + { + integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, + } + + sha.js@2.4.11: + resolution: + { + integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==, + } + hasBin: true shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: '>=8' } shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: '>=8' } shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==, + } + engines: { node: '>=4' } hasBin: true side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + resolution: + { + integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==, + } signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, + } + engines: { node: '>=14' } sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + resolution: + { + integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, + } slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, + } + engines: { node: '>=8' } slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==, + } + engines: { node: '>=12' } slice-ansi@7.1.0: - resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==, + } + engines: { node: '>=18' } source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + resolution: + { + integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==, + } source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + resolution: + { + integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, + } source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==, + } + engines: { node: '>=0.10.0' } source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: '>=0.10.0' } source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==, + } + engines: { node: '>= 8' } spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + resolution: + { + integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==, + } spdx-exceptions@2.4.0: - resolution: {integrity: sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==} + resolution: + { + integrity: sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==, + } spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + resolution: + { + integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==, + } spdx-license-ids@3.0.16: - resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + resolution: + { + integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==, + } split2@3.2.2: - resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + resolution: + { + integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==, + } split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} + resolution: + { + integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==, + } + engines: { node: '>= 10.x' } sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, + } + engines: { node: '>=10' } statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==, + } + engines: { node: '>= 0.8' } streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==, + } + engines: { node: '>=10.0.0' } string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} + resolution: + { + integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==, + } + engines: { node: '>=0.6.19' } string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, + } + engines: { node: '>=10' } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: '>=8' } string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, + } + engines: { node: '>=12' } string-width@7.1.0: - resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==, + } + engines: { node: '>=18' } string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + resolution: + { + integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==, + } string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + resolution: + { + integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, + } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: '>=8' } strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==, + } + engines: { node: '>=12' } strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, + } + engines: { node: '>=4' } strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, + } + engines: { node: '>=8' } strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, + } + engines: { node: '>=6' } strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, + } + engines: { node: '>=12' } strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==, + } + engines: { node: '>=8' } strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, + } + engines: { node: '>=8' } + + subscriptions-transport-ws@0.11.0: + resolution: + { + integrity: sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==, + } + deprecated: The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md + peerDependencies: + graphql: ^15.7.2 || ^16.0.0 superagent@8.1.2: - resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} - engines: {node: '>=6.4.0 <13 || >=14'} + resolution: + { + integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==, + } + engines: { node: '>=6.4.0 <13 || >=14' } supertest@6.3.4: - resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} - engines: {node: '>=6.4.0'} + resolution: + { + integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==, + } + engines: { node: '>=6.4.0' } supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, + } + engines: { node: '>=4' } supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: '>=8' } supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, + } + engines: { node: '>=10' } supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: '>= 0.4' } swagger-ui-dist@5.11.2: - resolution: {integrity: sha512-jQG0cRgJNMZ7aCoiFofnoojeSaa/+KgWaDlfgs8QN+BXoGMpxeMVY5OEnjq4OlNvF3yjftO8c9GRAgcHlO+u7A==} + resolution: + { + integrity: sha512-jQG0cRgJNMZ7aCoiFofnoojeSaa/+KgWaDlfgs8QN+BXoGMpxeMVY5OEnjq4OlNvF3yjftO8c9GRAgcHlO+u7A==, + } + + symbol-observable@1.2.0: + resolution: + { + integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==, + } + engines: { node: '>=0.10.0' } symbol-observable@4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} + resolution: + { + integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==, + } + engines: { node: '>=0.10' } synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} - engines: {node: ^14.18.0 || >=16.0.0} + resolution: + { + integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==, + } + engines: { node: ^14.18.0 || >=16.0.0 } tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==, + } + engines: { node: '>=6' } tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==, + } + engines: { node: '>=10' } terser-webpack-plugin@5.3.10: - resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} - engines: {node: '>= 10.13.0'} + resolution: + { + integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==, + } + engines: { node: '>= 10.13.0' } peerDependencies: '@swc/core': '*' esbuild: '*' @@ -3491,66 +6476,114 @@ packages: optional: true terser@5.27.0: - resolution: {integrity: sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==, + } + engines: { node: '>=10' } hasBin: true test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, + } + engines: { node: '>=8' } text-extensions@2.4.0: - resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==, + } + engines: { node: '>=8' } text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + resolution: + { + integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, + } through2@4.0.2: - resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + resolution: + { + integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==, + } through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + resolution: + { + integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==, + } tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} + resolution: + { + integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==, + } + engines: { node: '>=0.6.0' } tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + resolution: + { + integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, + } to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, + } + engines: { node: '>=4' } to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: '>=8.0' } toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, + } + engines: { node: '>=0.6' } tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + resolution: + { + integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, + } tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + resolution: + { + integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==, + } hasBin: true trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==, + } + engines: { node: '>=8' } ts-api-utils@1.0.3: - resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} - engines: {node: '>=16.13.0'} + resolution: + { + integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==, + } + engines: { node: '>=16.13.0' } peerDependencies: typescript: '>=4.2.0' ts-jest@29.1.2: - resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==} - engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} + resolution: + { + integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==, + } + engines: { node: ^16.10.0 || ^18.0.0 || >=20.0.0 } hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' @@ -3570,14 +6603,20 @@ packages: optional: true ts-loader@9.5.1: - resolution: {integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==, + } + engines: { node: '>=12.0.0' } peerDependencies: typescript: '*' webpack: ^5.0.0 ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + resolution: + { + integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==, + } hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -3591,12 +6630,18 @@ packages: optional: true ts-patch@3.1.2: - resolution: {integrity: sha512-n58F5AqjUMdp9RAKq+E1YBkmONltPVbt1nN+wrmZXoYZek6QcvaTuqvKMhYhr5BxtC53kD/exxIPA1cP1RQxsA==} + resolution: + { + integrity: sha512-n58F5AqjUMdp9RAKq+E1YBkmONltPVbt1nN+wrmZXoYZek6QcvaTuqvKMhYhr5BxtC53kD/exxIPA1cP1RQxsA==, + } hasBin: true tsconfck@2.1.2: - resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==} - engines: {node: ^14.13.1 || ^16 || >=18} + resolution: + { + integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==, + } + engines: { node: ^14.13.1 || ^16 || >=18 } hasBin: true peerDependencies: typescript: ^4.3.5 || ^5.0.0 @@ -3605,150 +6650,271 @@ packages: optional: true tsconfig-paths-webpack-plugin@4.1.0: - resolution: {integrity: sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==, + } + engines: { node: '>=10.13.0' } tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==, + } + engines: { node: '>=6' } tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + resolution: + { + integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==, + } tstl@3.0.0: - resolution: {integrity: sha512-pR83y6/tbJx6jeGRqGJXk2t/eCUynaHEE6zsOLB0Zga8ej61LXtPfoeiROdhezpoCT15+1QMbqKB1Um5kasSKg==} + resolution: + { + integrity: sha512-pR83y6/tbJx6jeGRqGJXk2t/eCUynaHEE6zsOLB0Zga8ej61LXtPfoeiROdhezpoCT15+1QMbqKB1Um5kasSKg==, + } twilio@5.0.3: - resolution: {integrity: sha512-92XIiR7tbtttS2cSD8/2mRUsUrrnaHIcqymGZSgFFpf5rjCxANETEPhWajs3bzJQo3Rb/ALBKh/BBprQS71oMQ==} - engines: {node: '>=14.0'} + resolution: + { + integrity: sha512-92XIiR7tbtttS2cSD8/2mRUsUrrnaHIcqymGZSgFFpf5rjCxANETEPhWajs3bzJQo3Rb/ALBKh/BBprQS71oMQ==, + } + engines: { node: '>=14.0' } type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, + } + engines: { node: '>= 0.8.0' } type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, + } + engines: { node: '>=4' } type-fest@0.18.1: - resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==, + } + engines: { node: '>=10' } type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==, + } + engines: { node: '>=10' } type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, + } + engines: { node: '>=10' } type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==, + } + engines: { node: '>=8' } type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==, + } + engines: { node: '>=8' } type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==, + } + engines: { node: '>= 0.6' } typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + resolution: + { + integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==, + } typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==, + } + engines: { node: '>=14.17' } hasBin: true typescript@5.4.4: - resolution: {integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==, + } + engines: { node: '>=14.17' } hasBin: true typia@5.5.10: - resolution: {integrity: sha512-IhSzSNW/CrFmrP9cgBMFj6oEJpDD9+mXSepaJu/E0/5mOUkH+riXsZSM6BjaMtBRtlhYeYyTRSyToL7XxZlueg==} + resolution: + { + integrity: sha512-IhSzSNW/CrFmrP9cgBMFj6oEJpDD9+mXSepaJu/E0/5mOUkH+riXsZSM6BjaMtBRtlhYeYyTRSyToL7XxZlueg==, + } hasBin: true peerDependencies: typescript: '>=4.8.0 <5.5.0' uid@2.0.2: - resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==, + } + engines: { node: '>=8' } undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + resolution: + { + integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, + } universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} + resolution: + { + integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, + } + engines: { node: '>= 10.0.0' } unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, + } + engines: { node: '>= 0.8' } update-browserslist-db@1.0.13: - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + resolution: + { + integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==, + } hasBin: true peerDependencies: browserslist: '>= 4.21.0' uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + resolution: + { + integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, + } url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + resolution: + { + integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==, + } util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + resolution: + { + integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, + } utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} + resolution: + { + integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==, + } + engines: { node: '>= 0.4.0' } uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + resolution: + { + integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==, + } hasBin: true v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + resolution: + { + integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, + } v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} - engines: {node: '>=10.12.0'} + resolution: + { + integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==, + } + engines: { node: '>=10.12.0' } validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + resolution: + { + integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==, + } + + value-or-promise@1.0.12: + resolution: + { + integrity: sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==, + } + engines: { node: '>=12' } vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, + } + engines: { node: '>= 0.8' } walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + resolution: + { + integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, + } watchpack@2.4.0: - resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==, + } + engines: { node: '>=10.13.0' } wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + resolution: + { + integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, + } webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + resolution: + { + integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, + } webpack-node-externals@3.0.0: - resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==, + } + engines: { node: '>=6' } webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==, + } + engines: { node: '>=10.13.0' } webpack@5.89.0: - resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==, + } + engines: { node: '>=10.13.0' } hasBin: true peerDependencies: webpack-cli: '*' @@ -3756,88 +6922,195 @@ packages: webpack-cli: optional: true + whatwg-mimetype@3.0.0: + resolution: + { + integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==, + } + engines: { node: '>=12' } + whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + resolution: + { + integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, + } which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + resolution: + { + integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==, + } hasBin: true which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: '>= 8' } hasBin: true wide-align@1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + resolution: + { + integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==, + } wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==, + } + engines: { node: '>=8' } wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: '>=10' } wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, + } + engines: { node: '>=12' } wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==, + } + engines: { node: '>=18' } wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } + + ws@7.5.9: + resolution: + { + integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==, + } + engines: { node: '>=8.3.0' } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.16.0: + resolution: + { + integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==, + } + engines: { node: '>=10.0.0' } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true xmlbuilder@13.0.2: - resolution: {integrity: sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==, + } + engines: { node: '>=6.0' } + + xss@1.0.15: + resolution: + { + integrity: sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==, + } + engines: { node: '>= 0.10.0' } + hasBin: true xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + resolution: + { + integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==, + } + engines: { node: '>=0.4' } y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: '>=10' } yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + resolution: + { + integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, + } yaml@2.3.4: - resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==, + } + engines: { node: '>= 14' } yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==, + } + engines: { node: '>=10' } yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: '>=12' } yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: '>=12' } yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, + } + engines: { node: '>=6' } yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: '>=10' } snapshots: - '@aashutoshrathi/word-wrap@1.2.6': {} '@ampproject/remapping@2.2.1': @@ -3877,6 +7150,127 @@ snapshots: transitivePeerDependencies: - chokidar + '@apollo/cache-control-types@1.0.3(graphql@16.8.1)': + dependencies: + graphql: 16.8.1 + + '@apollo/protobufjs@1.2.7': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + long: 4.0.0 + + '@apollo/server-gateway-interface@1.1.1(graphql@16.8.1)': + dependencies: + '@apollo/usage-reporting-protobuf': 4.1.1 + '@apollo/utils.fetcher': 2.0.1 + '@apollo/utils.keyvaluecache': 2.1.1 + '@apollo/utils.logger': 2.0.1 + graphql: 16.8.1 + + '@apollo/server-plugin-landing-page-graphql-playground@4.0.0(@apollo/server@4.10.4(graphql@16.8.1))': + dependencies: + '@apollo/server': 4.10.4(graphql@16.8.1) + '@apollographql/graphql-playground-html': 1.6.29 + + '@apollo/server@4.10.4(graphql@16.8.1)': + dependencies: + '@apollo/cache-control-types': 1.0.3(graphql@16.8.1) + '@apollo/server-gateway-interface': 1.1.1(graphql@16.8.1) + '@apollo/usage-reporting-protobuf': 4.1.1 + '@apollo/utils.createhash': 2.0.1 + '@apollo/utils.fetcher': 2.0.1 + '@apollo/utils.isnodelike': 2.0.1 + '@apollo/utils.keyvaluecache': 2.1.1 + '@apollo/utils.logger': 2.0.1 + '@apollo/utils.usagereporting': 2.1.0(graphql@16.8.1) + '@apollo/utils.withrequired': 2.0.1 + '@graphql-tools/schema': 9.0.19(graphql@16.8.1) + '@josephg/resolvable': 1.0.1 + '@types/express': 4.17.21 + '@types/express-serve-static-core': 4.17.43 + '@types/node-fetch': 2.6.11 + async-retry: 1.3.3 + cors: 2.8.5 + express: 4.18.2 + graphql: 16.8.1 + loglevel: 1.9.1 + lru-cache: 7.18.3 + negotiator: 0.6.3 + node-abort-controller: 3.1.1 + node-fetch: 2.7.0 + uuid: 9.0.1 + whatwg-mimetype: 3.0.0 + transitivePeerDependencies: + - encoding + - supports-color + + '@apollo/usage-reporting-protobuf@4.1.1': + dependencies: + '@apollo/protobufjs': 1.2.7 + + '@apollo/utils.createhash@2.0.1': + dependencies: + '@apollo/utils.isnodelike': 2.0.1 + sha.js: 2.4.11 + + '@apollo/utils.dropunuseddefinitions@2.0.1(graphql@16.8.1)': + dependencies: + graphql: 16.8.1 + + '@apollo/utils.fetcher@2.0.1': {} + + '@apollo/utils.isnodelike@2.0.1': {} + + '@apollo/utils.keyvaluecache@2.1.1': + dependencies: + '@apollo/utils.logger': 2.0.1 + lru-cache: 7.18.3 + + '@apollo/utils.logger@2.0.1': {} + + '@apollo/utils.printwithreducedwhitespace@2.0.1(graphql@16.8.1)': + dependencies: + graphql: 16.8.1 + + '@apollo/utils.removealiases@2.0.1(graphql@16.8.1)': + dependencies: + graphql: 16.8.1 + + '@apollo/utils.sortast@2.0.1(graphql@16.8.1)': + dependencies: + graphql: 16.8.1 + lodash.sortby: 4.7.0 + + '@apollo/utils.stripsensitiveliterals@2.0.1(graphql@16.8.1)': + dependencies: + graphql: 16.8.1 + + '@apollo/utils.usagereporting@2.1.0(graphql@16.8.1)': + dependencies: + '@apollo/usage-reporting-protobuf': 4.1.1 + '@apollo/utils.dropunuseddefinitions': 2.0.1(graphql@16.8.1) + '@apollo/utils.printwithreducedwhitespace': 2.0.1(graphql@16.8.1) + '@apollo/utils.removealiases': 2.0.1(graphql@16.8.1) + '@apollo/utils.sortast': 2.0.1(graphql@16.8.1) + '@apollo/utils.stripsensitiveliterals': 2.0.1(graphql@16.8.1) + graphql: 16.8.1 + + '@apollo/utils.withrequired@2.0.1': {} + + '@apollographql/graphql-playground-html@1.6.29': + dependencies: + xss: 1.0.15 + '@babel/code-frame@7.23.5': dependencies: '@babel/highlight': 7.23.4 @@ -4245,6 +7639,52 @@ snapshots: '@eslint/js@8.57.0': {} + '@graphql-tools/merge@8.4.2(graphql@16.8.1)': + dependencies: + '@graphql-tools/utils': 9.2.1(graphql@16.8.1) + graphql: 16.8.1 + tslib: 2.6.2 + + '@graphql-tools/merge@9.0.1(graphql@16.8.1)': + dependencies: + '@graphql-tools/utils': 10.0.13(graphql@16.8.1) + graphql: 16.8.1 + tslib: 2.6.2 + + '@graphql-tools/schema@10.0.2(graphql@16.8.1)': + dependencies: + '@graphql-tools/merge': 9.0.1(graphql@16.8.1) + '@graphql-tools/utils': 10.0.13(graphql@16.8.1) + graphql: 16.8.1 + tslib: 2.6.2 + value-or-promise: 1.0.12 + + '@graphql-tools/schema@9.0.19(graphql@16.8.1)': + dependencies: + '@graphql-tools/merge': 8.4.2(graphql@16.8.1) + '@graphql-tools/utils': 9.2.1(graphql@16.8.1) + graphql: 16.8.1 + tslib: 2.6.2 + value-or-promise: 1.0.12 + + '@graphql-tools/utils@10.0.13(graphql@16.8.1)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1) + cross-inspect: 1.0.0 + dset: 3.1.3 + graphql: 16.8.1 + tslib: 2.6.2 + + '@graphql-tools/utils@9.2.1(graphql@16.8.1)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.1) + graphql: 16.8.1 + tslib: 2.6.2 + + '@graphql-typed-document-node/core@3.2.0(graphql@16.8.1)': + dependencies: + graphql: 16.8.1 + '@hapi/hoek@9.3.0': {} '@hapi/topo@5.1.0': @@ -4444,6 +7884,8 @@ snapshots: '@types/yargs': 17.0.32 chalk: 4.1.2 + '@josephg/resolvable@1.0.1': {} + '@jridgewell/gen-mapping@0.3.3': dependencies: '@jridgewell/set-array': 1.1.2 @@ -4540,6 +7982,18 @@ snapshots: transitivePeerDependencies: - typescript + '@nestjs/apollo@12.1.0(@apollo/server@4.10.4(graphql@16.8.1))(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/graphql@12.1.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(graphql@16.8.1)(reflect-metadata@0.2.2))(graphql@16.8.1)': + dependencies: + '@apollo/server': 4.10.4(graphql@16.8.1) + '@apollo/server-plugin-landing-page-graphql-playground': 4.0.0(@apollo/server@4.10.4(graphql@16.8.1)) + '@nestjs/common': 10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/graphql': 12.1.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(graphql@16.8.1)(reflect-metadata@0.2.2) + graphql: 16.8.1 + iterall: 1.3.0 + lodash.omit: 4.5.0 + tslib: 2.6.2 + '@nestjs/axios@3.0.2(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.6.8)(rxjs@7.8.1)': dependencies: '@nestjs/common': 10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -4615,6 +8069,44 @@ snapshots: transitivePeerDependencies: - encoding + '@nestjs/cqrs@10.2.7(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)': + dependencies: + '@nestjs/common': 10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + reflect-metadata: 0.2.2 + rxjs: 7.8.1 + uuid: 9.0.1 + + '@nestjs/event-emitter@2.0.4(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))': + dependencies: + '@nestjs/common': 10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + eventemitter2: 6.4.9 + + '@nestjs/graphql@12.1.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(graphql@16.8.1)(reflect-metadata@0.2.2)': + dependencies: + '@graphql-tools/merge': 9.0.1(graphql@16.8.1) + '@graphql-tools/schema': 10.0.2(graphql@16.8.1) + '@graphql-tools/utils': 10.0.13(graphql@16.8.1) + '@nestjs/common': 10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.3.1(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/mapped-types': 2.0.5(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2) + chokidar: 3.6.0 + fast-glob: 3.3.2 + graphql: 16.8.1 + graphql-tag: 2.12.6(graphql@16.8.1) + graphql-ws: 5.14.3(graphql@16.8.1) + lodash: 4.17.21 + normalize-path: 3.0.0 + reflect-metadata: 0.2.2 + subscriptions-transport-ws: 0.11.0(graphql@16.8.1) + tslib: 2.6.2 + uuid: 9.0.1 + ws: 8.16.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@nestjs/jwt@10.2.0(@nestjs/common@10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1))': dependencies: '@nestjs/common': 10.3.1(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -4705,36 +8197,60 @@ snapshots: '@pkgr/core@0.1.1': {} - '@prisma/client@5.13.0(prisma@5.13.0)': + '@prisma/client@5.15.0(prisma@5.15.0)': optionalDependencies: - prisma: 5.13.0 + prisma: 5.15.0 '@prisma/debug@5.12.1': {} - '@prisma/debug@5.13.0': {} + '@prisma/debug@5.15.0': {} - '@prisma/engines-version@5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b': {} + '@prisma/engines-version@5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022': + {} - '@prisma/engines@5.13.0': + '@prisma/engines@5.15.0': dependencies: - '@prisma/debug': 5.13.0 - '@prisma/engines-version': 5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b - '@prisma/fetch-engine': 5.13.0 - '@prisma/get-platform': 5.13.0 + '@prisma/debug': 5.15.0 + '@prisma/engines-version': 5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022 + '@prisma/fetch-engine': 5.15.0 + '@prisma/get-platform': 5.15.0 - '@prisma/fetch-engine@5.13.0': + '@prisma/fetch-engine@5.15.0': dependencies: - '@prisma/debug': 5.13.0 - '@prisma/engines-version': 5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b - '@prisma/get-platform': 5.13.0 + '@prisma/debug': 5.15.0 + '@prisma/engines-version': 5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022 + '@prisma/get-platform': 5.15.0 '@prisma/generator-helper@5.12.1': dependencies: '@prisma/debug': 5.12.1 - '@prisma/get-platform@5.13.0': + '@prisma/get-platform@5.15.0': + dependencies: + '@prisma/debug': 5.15.0 + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': dependencies: - '@prisma/debug': 5.13.0 + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} '@redis/bloom@1.2.0(@redis/client@1.5.14)': dependencies: @@ -4893,6 +8409,8 @@ snapshots: dependencies: '@types/node': 20.11.16 + '@types/long@4.0.2': {} + '@types/methods@1.1.4': {} '@types/mime@1.3.5': {} @@ -4901,6 +8419,11 @@ snapshots: '@types/minimist@1.2.5': {} + '@types/node-fetch@2.6.11': + dependencies: + '@types/node': 20.11.16 + form-data: 4.0.0 + '@types/node@20.11.16': dependencies: undici-types: 5.26.5 @@ -5223,6 +8746,10 @@ snapshots: asap@2.0.6: {} + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + asynckit@0.4.0: {} axios@1.6.8: @@ -5285,6 +8812,8 @@ snapshots: babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.9) + backo2@1.0.2: {} + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -5442,6 +8971,18 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + chownr@2.0.0: {} chrome-trace-event@1.0.3: {} @@ -5635,12 +9176,18 @@ snapshots: create-require@1.1.1: {} + cross-inspect@1.0.0: + dependencies: + tslib: 2.6.2 + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + cssfilter@0.0.10: {} + dargs@7.0.0: {} dayjs@1.11.10: {} @@ -5717,6 +9264,8 @@ snapshots: drange@1.1.1: {} + dset@3.1.3: {} + eastasianwidth@0.2.0: {} ecdsa-sig-formatter@1.0.11: @@ -5855,6 +9404,10 @@ snapshots: etag@1.8.1: {} + eventemitter2@6.4.9: {} + + eventemitter3@3.1.2: {} + eventemitter3@5.0.1: {} events@3.3.0: {} @@ -6181,6 +9734,17 @@ snapshots: graphemer@1.4.0: {} + graphql-tag@2.12.6(graphql@16.8.1): + dependencies: + graphql: 16.8.1 + tslib: 2.6.2 + + graphql-ws@5.14.3(graphql@16.8.1): + dependencies: + graphql: 16.8.1 + + graphql@16.8.1: {} + hard-rejection@2.1.0: {} has-flag@3.0.0: {} @@ -6400,6 +9964,8 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + iterall@1.3.0: {} + iterare@1.2.1: {} jackspeak@2.3.6: @@ -6873,10 +10439,14 @@ snapshots: lodash.mergewith@4.6.2: {} + lodash.omit@4.5.0: {} + lodash.once@4.1.1: {} lodash.snakecase@4.1.1: {} + lodash.sortby@4.7.0: {} + lodash.startcase@4.4.0: {} lodash.uniq@4.5.0: {} @@ -6898,6 +10468,10 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 9.0.0 + loglevel@1.9.1: {} + + long@4.0.0: {} + lru-cache@10.2.0: {} lru-cache@5.1.1: @@ -6908,6 +10482,8 @@ snapshots: dependencies: yallist: 4.0.0 + lru-cache@7.18.3: {} + magic-string@0.30.5: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -7251,15 +10827,15 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.2.0 - prisma-markdown@1.0.9(@prisma/client@5.13.0(prisma@5.13.0))(prisma@5.13.0): + prisma-markdown@1.0.9(@prisma/client@5.15.0(prisma@5.15.0))(prisma@5.15.0): dependencies: - '@prisma/client': 5.13.0(prisma@5.13.0) + '@prisma/client': 5.15.0(prisma@5.15.0) '@prisma/generator-helper': 5.12.1 - prisma: 5.13.0 + prisma: 5.15.0 - prisma@5.13.0: + prisma@5.15.0: dependencies: - '@prisma/engines': 5.13.0 + '@prisma/engines': 5.15.0 process-nextick-args@2.0.1: {} @@ -7415,6 +10991,8 @@ snapshots: ret@0.2.2: {} + retry@0.13.1: {} + reusify@1.0.4: {} rfdc@1.3.1: {} @@ -7508,6 +11086,11 @@ snapshots: setprototypeof@1.2.0: {} + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -7645,6 +11228,18 @@ snapshots: strip-json-comments@3.1.1: {} + subscriptions-transport-ws@0.11.0(graphql@16.8.1): + dependencies: + backo2: 1.0.2 + eventemitter3: 3.1.2 + graphql: 16.8.1 + iterall: 1.3.0 + symbol-observable: 1.2.0 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + superagent@8.1.2: dependencies: component-emitter: 1.3.1 @@ -7683,6 +11278,8 @@ snapshots: swagger-ui-dist@5.11.2: {} + symbol-observable@1.2.0: {} + symbol-observable@4.0.0: {} synckit@0.8.8: @@ -7924,6 +11521,8 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + value-or-promise@1.0.12: {} + vary@1.1.2: {} walker@1.0.8: @@ -7976,6 +11575,8 @@ snapshots: - esbuild - uglify-js + whatwg-mimetype@3.0.0: {} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -8024,8 +11625,17 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + ws@7.5.9: {} + + ws@8.16.0: {} + xmlbuilder@13.0.2: {} + xss@1.0.15: + dependencies: + commander: 2.20.3 + cssfilter: 0.0.10 + xtend@4.0.2: {} y18n@5.0.8: {} diff --git a/prisma/migrations/20240509022543_init/migration.sql b/prisma/migrations/20240515064952_yes/migration.sql similarity index 92% rename from prisma/migrations/20240509022543_init/migration.sql rename to prisma/migrations/20240515064952_yes/migration.sql index 318b480..cfede91 100644 --- a/prisma/migrations/20240509022543_init/migration.sql +++ b/prisma/migrations/20240515064952_yes/migration.sql @@ -94,27 +94,24 @@ CREATE TABLE "terms_agreements" ( -- CreateTable CREATE TABLE "oauth" ( - "id" UUID NOT NULL, "user_id" UUID NOT NULL, "provider" "OAUT_PROVIDER" NOT NULL, "provider_id" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, - CONSTRAINT "oauth_pkey" PRIMARY KEY ("id") + CONSTRAINT "oauth_pkey" PRIMARY KEY ("user_id","provider") ); -- CreateTable -CREATE TABLE "certification" ( +CREATE TABLE "certification_record" ( "id" UUID NOT NULL, "certification_code_id" UUID NOT NULL, "user_id" UUID NOT NULL, - "targetType" "CERTIFICATION_TARGET_TYPE" NOT NULL, - "type" "CERTIFICATION_TYPE" NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, - CONSTRAINT "certification_pkey" PRIMARY KEY ("id") + CONSTRAINT "certification_record_pkey" PRIMARY KEY ("id") ); -- CreateTable @@ -127,7 +124,7 @@ CREATE TABLE "certification_code" ( "target" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, - "expired_at" TIMESTAMP(3) NOT NULL, + "expires_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "certification_code_pkey" PRIMARY KEY ("id") ); @@ -300,13 +297,7 @@ CREATE UNIQUE INDEX "terms_agreements_user_id_type_key" ON "terms_agreements"("u CREATE UNIQUE INDEX "oauth_provider_provider_id_key" ON "oauth"("provider", "provider_id"); -- CreateIndex -CREATE UNIQUE INDEX "oauth_user_id_provider_key" ON "oauth"("user_id", "provider"); - --- CreateIndex -CREATE UNIQUE INDEX "certification_certification_code_id_key" ON "certification"("certification_code_id"); - --- CreateIndex -CREATE UNIQUE INDEX "certification_user_id_type_key" ON "certification"("user_id", "type"); +CREATE UNIQUE INDEX "certification_record_certification_code_id_key" ON "certification_record"("certification_code_id"); -- CreateIndex CREATE INDEX "certification_code_target_idx" ON "certification_code"("target"); @@ -321,7 +312,7 @@ CREATE INDEX "certification_code_created_at_idx" ON "certification_code"("create CREATE INDEX "certification_code_target_created_at_idx" ON "certification_code"("target", "created_at"); -- CreateIndex -CREATE INDEX "certification_code_expired_at_idx" ON "certification_code"("expired_at"); +CREATE INDEX "certification_code_expires_at_idx" ON "certification_code"("expires_at"); -- CreateIndex CREATE INDEX "car_number_status_idx" ON "car"("number", "status"); @@ -360,10 +351,10 @@ ALTER TABLE "terms_agreements" ADD CONSTRAINT "terms_agreements_user_id_fkey" FO ALTER TABLE "oauth" ADD CONSTRAINT "oauth_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "certification" ADD CONSTRAINT "certification_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "certification_record" ADD CONSTRAINT "certification_record_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "certification" ADD CONSTRAINT "certification_certification_code_id_fkey" FOREIGN KEY ("certification_code_id") REFERENCES "certification_code"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "certification_record" ADD CONSTRAINT "certification_record_certification_code_id_fkey" FOREIGN KEY ("certification_code_id") REFERENCES "certification_code"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "car" ADD CONSTRAINT "car_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/_ddd/_template/application/command/_command/.command-handler.ts b/src/_ddd/_template/application/command/_command/.command-handler.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/_template/application/command/_command/.command.ts b/src/_ddd/_template/application/command/_command/.command.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/_template/application/query/.query-handler.ts b/src/_ddd/_template/application/query/.query-handler.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/_template/domain/entity/.entity.ts b/src/_ddd/_template/domain/entity/.entity.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/_template/domain/port/in/_.use-case.ts b/src/_ddd/_template/domain/port/in/_.use-case.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/_template/domain/port/out/_.port.ts b/src/_ddd/_template/domain/port/out/_.port.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/_template/infrastructure/repository/_.repository.ts b/src/_ddd/_template/infrastructure/repository/_.repository.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/auth/application/command/_command/.command-handler.ts b/src/_ddd/auth/application/command/_command/.command-handler.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/auth/application/command/_command/.command.ts b/src/_ddd/auth/application/command/_command/.command.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/auth/application/command/login-command/http/login.http-req.type.ts b/src/_ddd/auth/application/command/login-command/http/login.http-req.type.ts new file mode 100644 index 0000000..980270b --- /dev/null +++ b/src/_ddd/auth/application/command/login-command/http/login.http-req.type.ts @@ -0,0 +1,6 @@ +import { + LocalLoginCommandProps, + OauthLoginCommandProps, +} from '../login.command'; + +export type LoginHttpReq = LocalLoginCommandProps | OauthLoginCommandProps; diff --git a/src/_ddd/auth/application/command/login-command/http/login.http-res.type.ts b/src/_ddd/auth/application/command/login-command/http/login.http-res.type.ts new file mode 100644 index 0000000..6eb20be --- /dev/null +++ b/src/_ddd/auth/application/command/login-command/http/login.http-res.type.ts @@ -0,0 +1,10 @@ +import { LoginSuccess } from '@/_ddd/auth/domain/port/in/login.use-case'; + +export type LoginHttpRes = { + user: LoginSuccess['user']; + accessToken: string; + /** + * x-app = 'app' 일경우 + */ + refreshToken?: string; +}; diff --git a/src/_ddd/auth/application/command/login-command/http/login.http.controller.ts b/src/_ddd/auth/application/command/login-command/http/login.http.controller.ts new file mode 100644 index 0000000..99857cd --- /dev/null +++ b/src/_ddd/auth/application/command/login-command/http/login.http.controller.ts @@ -0,0 +1,43 @@ +import { AuthAccountInvalidExceptionType } from '@/_ddd/auth/domain/error'; +import { LoginSuccess } from '@/_ddd/auth/domain/port/in/login.use-case'; +import { handleException } from '@/_ddd_shared/exceptions'; +import { Result, match } from '@/_ddd_shared/types'; +import { Response } from '@/_ddd_shared/types/response.type'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { TypedBody, TypedHeaders, TypedRoute } from '@nestia/core'; +import { Controller, Res } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { Response as ExpressResponse } from 'express'; +import { LoginCommand } from '../login.command'; +import { LoginHttpReq } from './login.http-req.type'; +import { LoginHttpRes } from './login.http-res.type'; + +@Controller('/login') +export class LoginHttpController { + constructor(private readonly commandBus: CommandBus) {} + + @TypedRoute.Post('') + async login( + @TypedBody() dto: LoginHttpReq, + @TypedHeaders() headers: { 'x-app'?: 'app' | 'web' }, + @Res({ passthrough: true }) response: ExpressResponse, + ): Promise | AuthAccountInvalidExceptionType> { + const commadInput = dto.type === 'LOCAL' ? { local: dto } : { oauth: dto }; + const result: Result = + await this.commandBus.execute(new LoginCommand(commadInput)); + + const isApp = headers['x-app'] === 'app'; + + !isApp && response.cookie('_r', result.unwrap().refreshToken); + + return match(result, { + Ok: ({ user, accessToken, refreshToken }) => + res({ + user, + accessToken, + refreshToken: isApp ? refreshToken : undefined, + }), + Err: handleException, + }); + } +} diff --git a/src/_ddd/auth/application/command/login-command/login.command-handler.ts b/src/_ddd/auth/application/command/login-command/login.command-handler.ts new file mode 100644 index 0000000..f8322db --- /dev/null +++ b/src/_ddd/auth/application/command/login-command/login.command-handler.ts @@ -0,0 +1,90 @@ +import { AuthEntity } from '@/_ddd/auth/domain/entity/auth.root-entity'; +import { + AuthAccountInvalidException, + AuthAccountInvalidExceptionType, + AuthExction, + AuthJwtFailException, +} from '@/_ddd/auth/domain/error'; +import { + LoginSuccess, + LoginUseCase, +} from '@/_ddd/auth/domain/port/in/login.use-case'; +import { HashService } from '@/_ddd/auth/domain/service/HashService'; +import { UserAdaptor } from '@/_ddd/auth/infrastructure/adaptor/user.adaptor'; +import { handleException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { JwtService } from '@nestjs/jwt'; +import { + LocalLoginCommandProps, + LoginCommand, + OauthLoginCommandProps, +} from './login.command'; + +@CommandHandler(LoginCommand) +export class LoginCommandHandler implements ICommandHandler, LoginUseCase { + constructor( + private readonly userAdaptor: UserAdaptor, + private readonly hashService: HashService, + private readonly jwtService: JwtService, + ) {} + + async execute( + command: LoginCommand, + ): Promise> { + const { local, oauth } = command; + try { + if (local) { + return Ok(await this.localLogin(local)); + } + if (oauth) { + return Ok(await this.oauthLogin(oauth)); + } + throw new Error('Invalid login command'); + } catch (e) { + if (e instanceof AuthExction) { + return Err(e); + } + throw handleException(e as Error); + } + } + + private async localLogin( + local: LocalLoginCommandProps, + ): Promise { + const user = await this.userAdaptor.findByAccount(local.account); + console.log('localLogin', user); + if (!user) { + throw AuthAccountInvalidException( + '존재하지않는 계정정보입니다. 확인해주세요', + ); + } + + // 로그인시 해당 로그기록을 기록하기에 Entity - 현재는 기록 X + const auth = AuthEntity.create({ + id: user.id, + account: user.account, + password: user.password, + nickname: user.nickname, + }); + await auth.comparePassword(this.hashService, local.password); + const jwt = auth.setJwt(this.jwtService).getJwt()?.unpack(); + if (!jwt) { + throw AuthJwtFailException('JWT 토큰 생성 실패'); + } + + return { + accessToken: jwt.accessToken, + refreshToken: jwt.refreshToken, + user, + }; + } + + private async oauthLogin( + command: OauthLoginCommandProps, + ): Promise { + command; + throw new Error('Not implemented'); + } +} diff --git a/src/_ddd/auth/application/command/login-command/login.command.ts b/src/_ddd/auth/application/command/login-command/login.command.ts new file mode 100644 index 0000000..12b5f0b --- /dev/null +++ b/src/_ddd/auth/application/command/login-command/login.command.ts @@ -0,0 +1,23 @@ +import { OauthProvider } from '@/_ddd/auth/domain/value-object/oauth.value-object'; +import { Command, CommandProps } from '@/_ddd_shared/app/command/command.base'; + +export interface LocalLoginCommandProps { + readonly type: 'LOCAL'; + readonly account: string; + readonly password: string; +} + +export interface OauthLoginCommandProps { + readonly type: OauthProvider; + readonly accessToken: string; +} + +export class LoginCommand extends Command { + readonly local?: LocalLoginCommandProps; + readonly oauth?: OauthLoginCommandProps; + constructor(props: CommandProps) { + super(props); + this.local = props.local; + this.oauth = props.oauth; + } +} diff --git a/src/_ddd/auth/application/query/.query-handler.ts b/src/_ddd/auth/application/query/.query-handler.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/auth/application/query/isLogin/http/is-login.controller.ts b/src/_ddd/auth/application/query/isLogin/http/is-login.controller.ts new file mode 100644 index 0000000..3475149 --- /dev/null +++ b/src/_ddd/auth/application/query/isLogin/http/is-login.controller.ts @@ -0,0 +1,18 @@ +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { CurrentUser } from '@/_ddd_shared/decorator/CurrentUser'; +import { AuthGuard } from '@/_ddd_shared/guard/auth.guard'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { TypedRoute } from '@nestia/core'; +import { Controller, UseGuards } from '@nestjs/common'; + +@Controller('/auth') +export class IsLoginController { + @TypedRoute.Get('/is-login') + @UseGuards(AuthGuard) + async isLogin(@CurrentUser() user: TokenPayload) { + return res({ + user: { account: user.account, nickname: user.nickname }, + isLogin: true, + }); + } +} diff --git a/src/_ddd/auth/application/query/isLogin/is-login.query-handler.ts b/src/_ddd/auth/application/query/isLogin/is-login.query-handler.ts new file mode 100644 index 0000000..4dbfd50 --- /dev/null +++ b/src/_ddd/auth/application/query/isLogin/is-login.query-handler.ts @@ -0,0 +1,47 @@ +import { AuthEntity } from '@/_ddd/auth/domain/entity/auth.root-entity'; +import { + AuthJwtFailExceptionType, + AuthJwtInvalidExceptionType, +} from '@/_ddd/auth/domain/error'; +import { + RefreshSuccess, + RefreshUseCase, +} from '@/_ddd/auth/domain/port/in/refresh.use-case'; +import { DomainException, handleException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { IQueryHandler, QueryHandler } from '@nestjs/cqrs'; +import { JwtService } from '@nestjs/jwt'; +import { AuthJwtFailException } from '../../../domain/error/index'; +import { IsLoginQuery } from './is-login.query'; + +@QueryHandler(IsLoginQuery) +export class IsLoginQueryHandler implements IQueryHandler, RefreshUseCase { + constructor(private readonly jwtService: JwtService) {} + async execute( + query: IsLoginQuery, + ): Promise< + Result< + RefreshSuccess, + AuthJwtFailExceptionType | AuthJwtInvalidExceptionType + > + > { + try { + const user = query.user; + const auth = AuthEntity.create({ ...user, id: user.sub }); + const token = auth.setJwt(this.jwtService)?.getJwt()?.unpack(); + if (!token) throw AuthJwtFailException(''); + return Ok({ + user: { + nickname: user.nickname, + account: user.account, + }, + accessToken: token.accessToken, + refreshToken: token.refreshToken, + }); + } catch (e) { + if (e instanceof DomainException) return Err(e); + throw handleException(e as Error); + } + } +} diff --git a/src/_ddd/auth/application/query/isLogin/is-login.query.ts b/src/_ddd/auth/application/query/isLogin/is-login.query.ts new file mode 100644 index 0000000..ea38d9c --- /dev/null +++ b/src/_ddd/auth/application/query/isLogin/is-login.query.ts @@ -0,0 +1,10 @@ +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { Query } from '@/_ddd_shared/app/query/query-handler.interface'; + +export class IsLoginQuery extends Query { + readonly user: TokenPayload; + constructor(user: TokenPayload) { + super(); + this.user = user; + } +} diff --git a/src/_ddd/auth/application/query/refresh/http/refresh.http-controller.ts b/src/_ddd/auth/application/query/refresh/http/refresh.http-controller.ts new file mode 100644 index 0000000..0ee728c --- /dev/null +++ b/src/_ddd/auth/application/query/refresh/http/refresh.http-controller.ts @@ -0,0 +1,52 @@ +import { + AuthJwtFailExceptionType, + AuthJwtInvalidExceptionType, +} from '@/_ddd/auth/domain/error'; +import { RefreshSuccess } from '@/_ddd/auth/domain/port/in/refresh.use-case'; +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { RefreshGuard } from '@/_ddd/auth/guard/refresh.guard'; +import { CurrentUser } from '@/_ddd_shared/decorator/CurrentUser'; +import { handleException } from '@/_ddd_shared/exceptions'; +import { Response } from '@/_ddd_shared/types/response.type'; +import { Result } from '@/_ddd_shared/types/result.type'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { match } from '@/_ddd_shared/util/Result'; +import { TypedRoute } from '@nestia/core'; +import { Controller, Req, Res, UseGuards } from '@nestjs/common'; +import { QueryBus } from '@nestjs/cqrs'; +import { Response as ExpressResponse } from 'express'; +import { RefreshQuery } from '../refresh.query'; + +@Controller('auth') +export class RefreshHttpController { + constructor(private readonly queryBus: QueryBus) {} + @TypedRoute.Get('') + @UseGuards(RefreshGuard) + async refresh( + @CurrentUser() user: TokenPayload, + @Req() req: Request, + @Res({ passthrough: true }) response: ExpressResponse, + ): Promise< + | Response + | AuthJwtFailExceptionType + | AuthJwtInvalidExceptionType + > { + const query: RefreshQuery = new RefreshQuery(user); + const result: Result< + RefreshSuccess, + AuthJwtFailExceptionType | AuthJwtInvalidExceptionType + > = await this.queryBus.execute(query); + const headers = req.headers; + const isApp = headers['x-app'] === 'app'; + !isApp && response.cookie('_r', result.unwrap().refreshToken); + return match(result, { + Ok: ({ user, accessToken, refreshToken }) => + res({ + user, + accessToken, + refreshToken: isApp ? refreshToken : undefined, + }), + Err: handleException, + }); + } +} diff --git a/src/_ddd/auth/application/query/refresh/http/refresh.http-res.type.ts b/src/_ddd/auth/application/query/refresh/http/refresh.http-res.type.ts new file mode 100644 index 0000000..f34248d --- /dev/null +++ b/src/_ddd/auth/application/query/refresh/http/refresh.http-res.type.ts @@ -0,0 +1,10 @@ +import { LoginSuccess } from '@/_ddd/auth/domain/port/in/login.use-case'; + +export type RefreshHttpRes = { + user: LoginSuccess['user']; + accessToken: string; + /** + * x-app = 'app' 일경우 + */ + refreshToken?: string; +}; diff --git a/src/_ddd/auth/application/query/refresh/refresh.query-handler.ts b/src/_ddd/auth/application/query/refresh/refresh.query-handler.ts new file mode 100644 index 0000000..66b194c --- /dev/null +++ b/src/_ddd/auth/application/query/refresh/refresh.query-handler.ts @@ -0,0 +1,47 @@ +import { AuthEntity } from '@/_ddd/auth/domain/entity/auth.root-entity'; +import { + AuthJwtFailExceptionType, + AuthJwtInvalidExceptionType, +} from '@/_ddd/auth/domain/error'; +import { + RefreshSuccess, + RefreshUseCase, +} from '@/_ddd/auth/domain/port/in/refresh.use-case'; +import { DomainException, handleException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { IQueryHandler, QueryHandler } from '@nestjs/cqrs'; +import { JwtService } from '@nestjs/jwt'; +import { AuthJwtFailException } from './../../../domain/error/index'; +import { RefreshQuery } from './refresh.query'; + +@QueryHandler(RefreshQuery) +export class RefreshQueryHandler implements IQueryHandler, RefreshUseCase { + constructor(private readonly jwtService: JwtService) {} + async execute( + query: RefreshQuery, + ): Promise< + Result< + RefreshSuccess, + AuthJwtFailExceptionType | AuthJwtInvalidExceptionType + > + > { + try { + const user = query.user; + const auth = AuthEntity.create({ ...user, id: user.sub }); + const token = auth.setJwt(this.jwtService)?.getJwt()?.unpack(); + if (!token) throw AuthJwtFailException(''); + return Ok({ + user: { + nickname: user.nickname, + account: user.account, + }, + accessToken: token.accessToken, + refreshToken: token.refreshToken, + }); + } catch (e) { + if (e instanceof DomainException) return Err(e); + throw handleException(e as Error); + } + } +} diff --git a/src/_ddd/auth/application/query/refresh/refresh.query.ts b/src/_ddd/auth/application/query/refresh/refresh.query.ts new file mode 100644 index 0000000..cfeab17 --- /dev/null +++ b/src/_ddd/auth/application/query/refresh/refresh.query.ts @@ -0,0 +1,10 @@ +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { Query } from '@/_ddd_shared/app/query/query-handler.interface'; + +export class RefreshQuery extends Query { + readonly user: TokenPayload; + constructor(user: TokenPayload) { + super(); + this.user = user; + } +} diff --git a/src/_ddd/auth/auth.module.ts b/src/_ddd/auth/auth.module.ts new file mode 100644 index 0000000..c034f84 --- /dev/null +++ b/src/_ddd/auth/auth.module.ts @@ -0,0 +1,41 @@ +import { AuthGuard } from '@/_ddd_shared/guard/auth.guard'; +import { Global, Module, forwardRef } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; +import { JwtService } from '@nestjs/jwt'; +import { DDD_UserModule } from '../user/user.module'; +import { LoginHttpController } from './application/command/login-command/http/login.http.controller'; +import { LoginCommandHandler } from './application/command/login-command/login.command-handler'; +import { IsLoginController } from './application/query/isLogin/http/is-login.controller'; +import { RefreshHttpController } from './application/query/refresh/http/refresh.http-controller'; +import { RefreshQueryHandler } from './application/query/refresh/refresh.query-handler'; +import { HashService } from './domain/service/HashService'; +import { RefreshGuard } from './guard/refresh.guard'; +import { UserAdaptor } from './infrastructure/adaptor/user.adaptor'; + +const controllers = [ + LoginHttpController, + RefreshHttpController, + IsLoginController, +]; + +const commandHandler = [LoginCommandHandler]; +const queryHandler = [RefreshQueryHandler]; + +const guards = [AuthGuard, RefreshGuard]; +const services = [HashService, JwtService]; +const addaptors = [UserAdaptor]; + +@Module({ + imports: [CqrsModule, forwardRef(() => DDD_UserModule)], + controllers: [...controllers], + providers: [ + ...services, + ...addaptors, + ...commandHandler, + ...guards, + ...queryHandler, + ], + exports: [...services, ...guards], +}) +@Global() +export class DDD_AuthModule {} diff --git a/src/_ddd/auth/domain/entity/auth.root-entity.ts b/src/_ddd/auth/domain/entity/auth.root-entity.ts new file mode 100644 index 0000000..2f5bf0f --- /dev/null +++ b/src/_ddd/auth/domain/entity/auth.root-entity.ts @@ -0,0 +1,85 @@ +import { AggregateRoot } from '@/_ddd_shared/ddd/aggregate-root.base'; +import { AuthPasswordInvalidException } from '../error'; +import { HashPort } from '../port/out/hashPassword.port'; +import { AuthJwtPort } from '../port/out/token.port'; +import { JwtToken } from '../value-object/jwt.value-object'; +import { Oauth } from '../value-object/oauth.value-object'; + +interface AuthEntityProps { + account: string; + password?: string; + jwt?: JwtToken; + oauths: Oauth[]; + nickname: string; +} + +interface CreateAuthEntityProps { + id: string; + account: string; + password?: string; + nickname: string; + oauths?: Oauth[]; +} + +export class AuthEntity extends AggregateRoot { + constructor({ props, id }: { props: AuthEntityProps; id: string }) { + super({ id, props }); + } + + override getProps() { + return { + ...super.getProps(), + password: undefined, + }; + } + + static create(authEntityProps: CreateAuthEntityProps): AuthEntity { + const props = { + ...authEntityProps, + oauths: authEntityProps.oauths ?? [], + nickname: authEntityProps.nickname, + }; + const auth = new AuthEntity({ id: props.id, props }); + auth.validate(); + return auth; + } + + async hashPassword(hashService: HashPort): Promise { + if (!this.props.password) { + throw new Error('ONLY LOCAL AUTH'); + } + this.props.password = await hashService.hash(this.props.password); + } + + async comparePassword( + hashService: HashPort, + password: string, + ): Promise { + if (!this.props.password) { + throw new Error('ONLY LOCAL AUTH'); + } + const result = await hashService.compare(password, this.props.password); + if (!result) { + throw AuthPasswordInvalidException( + '잘못된 계정정보입니다. 다시 확인해주세요', + ); + } + return result; + } + + // 모든곳에서 JWT가 필요한것이 아니기에 set 메소드 이용 + setJwt(jwtService: AuthJwtPort) { + this.props.jwt = JwtToken.create(jwtService, { + sub: this.id, + account: this.props.account, + nickname: this.props.nickname, + }); + return this; + } + + getJwt() { + return this.props.jwt; + } + + public validate(): void {} +} diff --git a/src/_ddd/auth/domain/error/exception.codes.ts b/src/_ddd/auth/domain/error/exception.codes.ts new file mode 100644 index 0000000..f25247b --- /dev/null +++ b/src/_ddd/auth/domain/error/exception.codes.ts @@ -0,0 +1,5 @@ +export const AUTH_ACCOUNT_INVALID = 'AUTH_ACCOUNT_INVALID'; +export const AUTH_PASSWORD_INVALID = 'AUTH_PASSWORD_INVALID'; +export const AUTH_ACCOUNT_NOT_FOUND = 'AUTH_ACCOUNT_NOT_FOUND'; +export const AUTH_JWT_FAIL = 'AUTH_JWT_FAIL'; +export const AUTH_JWT_INVALID = 'AUTH_JWT_INVALID'; diff --git a/src/_ddd/auth/domain/error/index.ts b/src/_ddd/auth/domain/error/index.ts new file mode 100644 index 0000000..6a94ada --- /dev/null +++ b/src/_ddd/auth/domain/error/index.ts @@ -0,0 +1,53 @@ +import { DomainException } from '@/_ddd_shared/exceptions'; +import { ExceptionType } from '@/_ddd_shared/types/exception.type'; +import { DomainExceptionRes } from '@/_ddd_shared/types/response.type'; +import * as codes from './exception.codes'; + +export class AuthExction< + E extends string, + S extends number, +> extends DomainException {} + +// 잘못된 계정 - 존재하지 않는 계정 +export const AuthAccountInvalidException = AuthExction.create( + codes.AUTH_ACCOUNT_INVALID, + 400, +); +export type AuthAccountInvalidExceptionType = ExceptionType< + typeof AuthAccountInvalidException +>; +export type AuthAccountInvalidExceptionRes = + DomainExceptionRes; + +// 비밀번호 틀림 +export const AuthPasswordInvalidException = AuthExction.create( + codes.AUTH_PASSWORD_INVALID, + 400, +); +export type AuthPasswordInvalidExceptionType = ExceptionType< + typeof AuthPasswordInvalidException +>; +export type AuthPasswordInvalidExceptionRes = + DomainExceptionRes; + +// JWT fail +export const AuthJwtFailException = AuthExction.create( + codes.AUTH_JWT_FAIL, + 400, +); +export type AuthJwtFailExceptionType = ExceptionType< + typeof AuthJwtFailException +>; +export type AuthJwtFailExceptionRes = + DomainExceptionRes; + +// JWT INVALID +export const AuthJwtInvalidException = AuthExction.create( + codes.AUTH_JWT_INVALID, + 401, +); +export type AuthJwtInvalidExceptionType = ExceptionType< + typeof AuthJwtInvalidException +>; +export type AuthJwtInvalidExceptionRes = + DomainExceptionRes; diff --git a/src/_ddd/auth/domain/port/in/_.use-case.ts b/src/_ddd/auth/domain/port/in/_.use-case.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/auth/domain/port/in/login.use-case.ts b/src/_ddd/auth/domain/port/in/login.use-case.ts new file mode 100644 index 0000000..c467f49 --- /dev/null +++ b/src/_ddd/auth/domain/port/in/login.use-case.ts @@ -0,0 +1,23 @@ +import { LoginCommand } from '@/_ddd/auth/application/command/login-command/login.command'; +import { Result } from '@/_ddd_shared/types'; +import { AuthAccountInvalidExceptionType } from '../../error'; + +export interface LoginSuccess { + accessToken: string; + refreshToken: string; + user: { + account: string; + nickname: string; + }; +} + +export interface LoginUseCase { + execute( + command: LoginCommand, + ): Promise< + Result< + LoginSuccess, + AuthAccountInvalidExceptionType | AuthAccountInvalidExceptionType + > + >; +} diff --git a/src/_ddd/auth/domain/port/in/refresh.use-case.ts b/src/_ddd/auth/domain/port/in/refresh.use-case.ts new file mode 100644 index 0000000..6a27436 --- /dev/null +++ b/src/_ddd/auth/domain/port/in/refresh.use-case.ts @@ -0,0 +1,26 @@ +import { RefreshQuery } from '@/_ddd/auth/application/query/refresh/refresh.query'; +import { Result } from '@/_ddd_shared/types'; +import { + AuthJwtFailExceptionType, + AuthJwtInvalidExceptionType, +} from '../../error'; + +export interface RefreshSuccess { + accessToken: string; + refreshToken?: string; + user: { + account: string; + nickname: string; + }; +} + +export interface RefreshUseCase { + execute( + query: RefreshQuery, + ): Promise< + Result< + RefreshSuccess, + AuthJwtFailExceptionType | AuthJwtInvalidExceptionType + > + >; +} diff --git a/src/_ddd/auth/domain/port/out/certification-code.gateway.ts b/src/_ddd/auth/domain/port/out/certification-code.gateway.ts new file mode 100644 index 0000000..0aed9ee --- /dev/null +++ b/src/_ddd/auth/domain/port/out/certification-code.gateway.ts @@ -0,0 +1,12 @@ +export interface CertificationCodeGatewayPort { + findByPhone({ + countryCode, + phone, + }: { + countryCode: string; + phone: string; + }): Promise<{ + id: string; + status: 'PENDING' | 'EXPIRED' | 'VERIFIED'; + } | null>; +} diff --git a/src/_ddd/auth/domain/port/out/hashPassword.port.ts b/src/_ddd/auth/domain/port/out/hashPassword.port.ts new file mode 100644 index 0000000..7cecb29 --- /dev/null +++ b/src/_ddd/auth/domain/port/out/hashPassword.port.ts @@ -0,0 +1,4 @@ +export interface HashPort { + hash(password: string): Promise; + compare(password: string, hash: string): Promise; +} diff --git a/src/_ddd/auth/domain/port/out/oauth.provider.port.ts b/src/_ddd/auth/domain/port/out/oauth.provider.port.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/auth/domain/port/out/token.port.ts b/src/_ddd/auth/domain/port/out/token.port.ts new file mode 100644 index 0000000..172b5ba --- /dev/null +++ b/src/_ddd/auth/domain/port/out/token.port.ts @@ -0,0 +1,12 @@ +import { JwtSignOptions } from '@nestjs/jwt'; + +export interface TokenPayload { + sub: string; + account: string; + nickname: string; +} + +export interface AuthJwtPort { + sign(payload: TokenPayload, options?: JwtSignOptions): string; + verify(token: string): TokenPayload; +} diff --git a/src/_ddd/auth/domain/port/out/user.adaptor.port.ts b/src/_ddd/auth/domain/port/out/user.adaptor.port.ts new file mode 100644 index 0000000..7f5157d --- /dev/null +++ b/src/_ddd/auth/domain/port/out/user.adaptor.port.ts @@ -0,0 +1,25 @@ +export interface UserAdaptorPort { + findByAccount(account: string): Promise<{ + id: string; + account: string; + password: string; + phone: string; + countryCode: string; + nickname: string; + } | null>; + + findByPhone({ + countryCode, + phone, + }: { + countryCode: string; + phone: string; + }): Promise<{ + id: string; + account: string; + password: string; + phone: string; + countryCode: string; + nickname: string; + } | null>; +} diff --git a/src/_ddd/auth/domain/service/HashService.ts b/src/_ddd/auth/domain/service/HashService.ts new file mode 100644 index 0000000..1b61f20 --- /dev/null +++ b/src/_ddd/auth/domain/service/HashService.ts @@ -0,0 +1,15 @@ +import { Injectable } from '@nestjs/common'; +import * as bcrypt from 'bcrypt'; +import { HashPort } from '../port/out/hashPassword.port'; + +@Injectable() +export class HashService implements HashPort { + constructor() {} + + async hash(password: string): Promise { + return await bcrypt.hash(password, await bcrypt.genSalt()); + } + async compare(password: string, hash: string): Promise { + return await bcrypt.compare(password, hash); + } +} diff --git a/src/_ddd/auth/domain/value-object/jwt.value-object.ts b/src/_ddd/auth/domain/value-object/jwt.value-object.ts new file mode 100644 index 0000000..9e97cf7 --- /dev/null +++ b/src/_ddd/auth/domain/value-object/jwt.value-object.ts @@ -0,0 +1,27 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { AuthJwtPort, TokenPayload } from '../port/out/token.port'; + +interface JwtValueObjectProps { + accessToken: string; + refreshToken: string; +} +export class JwtToken extends ValueObject { + constructor(props: JwtValueObjectProps) { + super(props); + } + + static create(jwtService: AuthJwtPort, payload: TokenPayload): JwtToken { + const accessToken = jwtService.sign(payload, { + secret: process.env.JWT_ACCESS_SECRET, + expiresIn: process.env.JWT_ACCESS_EXPIRES_IN, + }); + const refreshToken = jwtService.sign(payload, { + secret: process.env.JWT_REFRESH_SECRET, + expiresIn: process.env.JWT_REFRESH_EXPIRES_IN, + }); + + return new JwtToken({ accessToken, refreshToken }); + } + + protected validate(): void {} +} diff --git a/src/_ddd/auth/domain/value-object/oauth.value-object.ts b/src/_ddd/auth/domain/value-object/oauth.value-object.ts new file mode 100644 index 0000000..3743f48 --- /dev/null +++ b/src/_ddd/auth/domain/value-object/oauth.value-object.ts @@ -0,0 +1,21 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; + +export type OauthProvider = 'GOOGLE' | 'KAKAO'; + +export interface OauthProps { + provider: OauthProvider; + providerId: string; +} + +export interface CreateOauthProps { + provider: OauthProvider; + providerId: string; +} + +/** + * @deprecated + */ +// TODO: 구현예정 +export class Oauth extends ValueObject { + protected validate(): void {} +} diff --git a/src/_ddd/auth/guard/refresh.guard.ts b/src/_ddd/auth/guard/refresh.guard.ts new file mode 100644 index 0000000..d7b862e --- /dev/null +++ b/src/_ddd/auth/guard/refresh.guard.ts @@ -0,0 +1,37 @@ +import { AuthJwtInvalidException } from '@/_ddd/auth/domain/error'; +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +import { JwtService } from '@nestjs/jwt'; +import { Observable } from 'rxjs'; +import typia from 'typia'; + +@Injectable() +export class RefreshGuard implements CanActivate { + constructor(private readonly jwtService: JwtService) {} + canActivate( + context: ExecutionContext, + ): boolean | Promise | Observable { + const request = context.switchToHttp().getRequest(); + + return this.validateRequest(request); + } + + private validateRequest(request: any) { + try { + const isApp = request.headers['x-app'] === 'app'; + const token = isApp + ? request.headers?.authorization?.split(' ')[1] + : request.cookies?._r; + if (!token) throw AuthJwtInvalidException('Invalid refresh token'); + const user = this.jwtService.verify(token, { + secret: process.env.JWT_REFRESH_SECRET, + }); + if (!user || !typia.is(user)) + throw AuthJwtInvalidException('Invalid refresh token'); + request.user = user; + return true; + } catch (e) { + throw e; + } + } +} diff --git a/src/_ddd/auth/infrastructure/adaptor/user.adaptor.ts b/src/_ddd/auth/infrastructure/adaptor/user.adaptor.ts new file mode 100644 index 0000000..b1aa5aa --- /dev/null +++ b/src/_ddd/auth/infrastructure/adaptor/user.adaptor.ts @@ -0,0 +1,19 @@ +import { UserService } from '@/_ddd/user/domain/service/user.service'; +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; +import { UserAdaptorPort } from '../../domain/port/out/user.adaptor.port'; + +// TODO: 이벤트기반으로 변경 +@Injectable() +export class UserAdaptor implements UserAdaptorPort { + constructor(private readonly userService: UserService) {} + async findByAccount(account: string, tx?: PrismaTxType) { + return this.userService.findByAccount(account, tx); + } + async findByPhone( + input: { phone: string; countryCode: string }, + tx?: PrismaTxType, + ) { + return this.userService.findByPhone(input, tx); + } +} diff --git a/src/_ddd/auth/infrastructure/repository/_.repository.ts b/src/_ddd/auth/infrastructure/repository/_.repository.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/car/application/command/create-car/create-car.command-hander.ts b/src/_ddd/car/application/command/create-car/create-car.command-hander.ts new file mode 100644 index 0000000..ef78fc5 --- /dev/null +++ b/src/_ddd/car/application/command/create-car/create-car.command-hander.ts @@ -0,0 +1,40 @@ +import { CarEntity } from '@/_ddd/car/domain/entity/car.root-entity'; +import { + CarAlreadyExists, + CarAlreadyExistsType, +} from '@/_ddd/car/domain/error'; +import { CarRepository } from '@/_ddd/car/infrastructure/car.repository'; +import { DomainException, handleException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { CreateCarCommand } from './create-car.command'; + +@CommandHandler(CreateCarCommand) +export class CreateCarCommandHandler implements ICommandHandler { + constructor(private readonly carRepository: CarRepository) {} + + async execute( + command: CreateCarCommand, + ): Promise> { + try { + const { props } = command; + const existCheck = await this.carRepository.findByNumberAndStatus( + props.number, + 'ACTIVE', + ); + if (existCheck) { + throw CarAlreadyExists('이미 존재하는 차량입니다.'); + } + const car = CarEntity.create(props); + console.log(car); + await this.carRepository.save(car); + return Ok('success'); + } catch (error) { + if (error instanceof DomainException) { + return Err(error); + } + throw handleException(error as Error); + } + } +} diff --git a/src/_ddd/car/application/command/create-car/create-car.command.ts b/src/_ddd/car/application/command/create-car/create-car.command.ts new file mode 100644 index 0000000..9ecbd2b --- /dev/null +++ b/src/_ddd/car/application/command/create-car/create-car.command.ts @@ -0,0 +1,17 @@ +import { Command, CommandProps } from '@/_ddd_shared/app/command/command.base'; + +export interface CreateCarCommandProps { + ownerId: string; + type: string; + number: string; + images: string[]; +} + +export class CreateCarCommand extends Command { + readonly props: CreateCarCommandProps; + + constructor(props: CommandProps) { + super(props); + this.props = props; + } +} diff --git a/src/_ddd/car/application/command/create-car/http/create-car.req-type.ts b/src/_ddd/car/application/command/create-car/http/create-car.req-type.ts new file mode 100644 index 0000000..55866b0 --- /dev/null +++ b/src/_ddd/car/application/command/create-car/http/create-car.req-type.ts @@ -0,0 +1,5 @@ +export interface CreateCarHttpReq { + type: string; + number: string; + images: string[]; +} diff --git a/src/_ddd/car/application/command/create-car/http/create-carr.controller.ts b/src/_ddd/car/application/command/create-car/http/create-carr.controller.ts new file mode 100644 index 0000000..525a28c --- /dev/null +++ b/src/_ddd/car/application/command/create-car/http/create-carr.controller.ts @@ -0,0 +1,35 @@ +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { CarAlreadyExistsType } from '@/_ddd/car/domain/error'; +import { CurrentUser } from '@/_ddd_shared/decorator/CurrentUser'; +import { handleException } from '@/_ddd_shared/exceptions'; +import { AuthGuard } from '@/_ddd_shared/guard/auth.guard'; +import { Result, match } from '@/_ddd_shared/types'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { TypedBody, TypedRoute } from '@nestia/core'; +import { Controller, UseGuards } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { CreateCarCommand } from '../create-car.command'; +import { CreateCarHttpReq } from './create-car.req-type'; + +@Controller('car') +export class CreateCarController { + constructor(private readonly commandBus: CommandBus) {} + + @TypedRoute.Post() + @UseGuards(AuthGuard) + async createCar( + @TypedBody() body: CreateCarHttpReq, + @CurrentUser() user: TokenPayload, + ) { + const command = new CreateCarCommand({ + ...body, + ownerId: user.sub, + }); + const result: Result<'success', CarAlreadyExistsType> = + await this.commandBus.execute(command); + return match(result, { + Ok: (s) => res(s), + Err: handleException, + }); + } +} diff --git a/src/_ddd/car/application/command/request-rental/http/request-rental.controller.ts b/src/_ddd/car/application/command/request-rental/http/request-rental.controller.ts new file mode 100644 index 0000000..0efc200 --- /dev/null +++ b/src/_ddd/car/application/command/request-rental/http/request-rental.controller.ts @@ -0,0 +1,38 @@ +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { CurrentUser } from '@/_ddd_shared/decorator/CurrentUser'; +import { handleException } from '@/_ddd_shared/exceptions'; +import { AuthGuard } from '@/_ddd_shared/guard/auth.guard'; +import { match } from '@/_ddd_shared/types'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { TypedBody, TypedParam, TypedRoute } from '@nestia/core'; +import { Controller, UseGuards } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { RequestRentalCommand } from '../request-rental.command'; +import { RequestRentalHttpReq } from './request-rental.req-type'; + +@Controller('/car') +export class RequestRentalController { + constructor(private readonly commandBus: CommandBus) {} + + @TypedRoute.Post('/:id/rental') + @UseGuards(AuthGuard) + async requestRental( + @TypedParam('id') id: string, + @TypedBody() body: RequestRentalHttpReq, + @CurrentUser() user: TokenPayload, + ) { + const command = new RequestRentalCommand({ + carId: id, + userId: user.sub, + startDate: new Date(body.startDate), + endDate: new Date(body.endDate), + }); + const result = await this.commandBus.execute(command); + return match(result, { + Ok: () => { + return res('success'); + }, + Err: handleException, + }); + } +} diff --git a/src/_ddd/car/application/command/request-rental/http/request-rental.req-type.ts b/src/_ddd/car/application/command/request-rental/http/request-rental.req-type.ts new file mode 100644 index 0000000..e57f5ed --- /dev/null +++ b/src/_ddd/car/application/command/request-rental/http/request-rental.req-type.ts @@ -0,0 +1,4 @@ +export interface RequestRentalHttpReq { + startDate: string; + endDate: string; +} diff --git a/src/_ddd/car/application/command/request-rental/request-rental.command-handler.ts b/src/_ddd/car/application/command/request-rental/request-rental.command-handler.ts new file mode 100644 index 0000000..f3aeea6 --- /dev/null +++ b/src/_ddd/car/application/command/request-rental/request-rental.command-handler.ts @@ -0,0 +1,46 @@ +import { + CarNotFound, + CarNotFoundType, + CarOwnerCannotRent, + CarOwnerCannotRentType, +} from '@/_ddd/car/domain/error'; +import { CarRepository } from '@/_ddd/car/infrastructure/car.repository'; +import { DomainException, handleException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { RequestRentalCommand } from './request-rental.command'; + +@CommandHandler(RequestRentalCommand) +export class RequestRentalCommandHandler + implements ICommandHandler +{ + constructor(private readonly carRepository: CarRepository) {} + + async execute( + command: RequestRentalCommand, + ): Promise> { + try { + const { carId, startDate, endDate, userId } = command.props; + + const car = await this.carRepository.findById(carId); + + if (car?.isOwner(userId)) { + throw CarOwnerCannotRent('You are the owner of the car'); + } + + if (!car) { + throw CarNotFound('Car not found'); + } + + car.addRental({ userId, startDate, endDate }); + await this.carRepository.save(car); + return Ok('success'); + } catch (error) { + if (error instanceof DomainException) { + return Err(error); + } + throw handleException(error as Error); + } + } +} diff --git a/src/_ddd/car/application/command/request-rental/request-rental.command.ts b/src/_ddd/car/application/command/request-rental/request-rental.command.ts new file mode 100644 index 0000000..dc0e00a --- /dev/null +++ b/src/_ddd/car/application/command/request-rental/request-rental.command.ts @@ -0,0 +1,16 @@ +import { Command } from '@/_ddd_shared/app/command/command.base'; + +export interface RequestRentalCommandProps { + carId: string; + userId: string; + startDate: Date; + endDate: Date; +} + +export class RequestRentalCommand extends Command { + readonly props: RequestRentalCommandProps; + constructor(props: RequestRentalCommandProps) { + super(props); + this.props = props; + } +} diff --git a/src/_ddd/car/car.mapper.ts b/src/_ddd/car/car.mapper.ts new file mode 100644 index 0000000..07e17de --- /dev/null +++ b/src/_ddd/car/car.mapper.ts @@ -0,0 +1,155 @@ +import { Mapper } from '@/_ddd_shared/ddd/mapper.interface'; +import { Injectable } from '@nestjs/common'; +import { + Car, + CarSnapshot, + Prisma, + Rental, + RentalSnapshot, +} from '@prisma/client'; +import { CarEntity } from './domain/entity/car.root-entity'; +import { RentalEntity } from './domain/entity/rental.entity'; +import { CarSnapshot as CarSnapshotVO } from './domain/value-object/car-snapshot.value-object'; +import { RentalSnapshot as RentalSnapshotVO } from './domain/value-object/rental-snapshot.value-object'; + +@Injectable() +export class CarMapper implements Mapper { + toPersistence(entity: CarEntity): { + create: Prisma.CarCreateInput; + update: Prisma.CarUpdateInput; + } { + const car = entity.getProps(); + // CarSnapshot 데이터 준비 + const carSnapshot = car.snapshots.map((s) => { + const { id, ownerId, type, number, status } = s.unpack(); + return { id, ownerId, type, number, status }; + }); + // Rental 데이터 준비 + const rentals = car.rentals.map((r) => { + const { id, userId, startDate, endDate, status, snapshots } = + r.getProps(); + return { + id, + userId, + startDate, + endDate, + status, + snapshots: snapshots.map((s) => { + const { id, startDate, endDate, status } = s.unpack(); + return { id, startDate, endDate, status }; + }), + }; + }); + + // Create Input 준비 + // 이미 존재할경우 렌탈정보는 없으므로 생략 + const create: Prisma.CarCreateInput = { + id: car.id, + type: car.type, + number: car.number, + owner: { + connect: { + id: car.ownerId, + }, + }, + snapshots: { + createMany: { + data: carSnapshot.map(({ id, ownerId, type, number, status }) => { + return { id, ownerId, type, number, status }; + }), + }, + }, + status: car.status, + }; + console.log(create); + + // Update Input 준비 + const update: Prisma.CarUpdateInput = { + ...car, + snapshots: { + upsert: carSnapshot.map(({ id, ...s }) => ({ + where: { + id: id, + }, + update: { ...s }, + create: { id, ...s }, + })), + }, + rentals: { + upsert: rentals.map(({ snapshots, ...r }) => ({ + where: { + id: r.id, + }, + update: { + ...r, + snapshots: { + upsert: snapshots.map(({ id, ...s }) => ({ + where: { + id: id, + }, + update: {}, + create: { id, ...s }, + })), + }, + }, + create: { + ...r, + snapshots: { + createMany: { + data: snapshots, + }, + }, + }, + })), + }, + images: { + upsert: car.images.map((image) => ({ + where: { + id: image, + }, + create: { id: image, image: { connect: { id: image } } }, + update: {}, + })), + }, + }; + + return { create, update }; + } + + toDomain(record: FindByID): CarEntity { + const { snapshots, rentals, ...car } = record; + const carSnapshotVOs = snapshots.map((s) => new CarSnapshotVO(s)); + const rentalEntities = rentals.map((r) => { + const { snapshots, ...rental } = r; + const rentalSnapshotVOs = snapshots.map((s) => new RentalSnapshotVO(s)); + return new RentalEntity({ + id: rental.id, + props: { ...rental, snapshots: rentalSnapshotVOs }, + }); + }); + + const carEntity = new CarEntity({ + id: car.id, + props: { + ...car, + snapshots: carSnapshotVOs, + rentals: rentalEntities, + images: [], + }, + }); + + return carEntity; + } + + toResponse(entity: CarEntity) { + entity; + throw new Error('Method not implemented.'); + } +} + +type FindByID = Car & { + snapshots: CarSnapshot[]; + rentals: (Rental & { + snapshots: RentalSnapshot[]; + })[]; +}; diff --git a/src/_ddd/car/car.module.ts b/src/_ddd/car/car.module.ts new file mode 100644 index 0000000..ddcf4da --- /dev/null +++ b/src/_ddd/car/car.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; +import { DDD_AuthModule } from '../auth/auth.module'; +import { CreateCarCommandHandler } from './application/command/create-car/create-car.command-hander'; +import { CreateCarController } from './application/command/create-car/http/create-carr.controller'; +import { RequestRentalController } from './application/command/request-rental/http/request-rental.controller'; +import { RequestRentalCommandHandler } from './application/command/request-rental/request-rental.command-handler'; +import { CarMapper } from './car.mapper'; +import { CarRepository } from './infrastructure/car.repository'; + +const httpControllers = [CreateCarController, RequestRentalController]; +const commandHandlers = [CreateCarCommandHandler, RequestRentalCommandHandler]; +const repositories = [CarRepository]; + +const mappers = [CarMapper]; + +@Module({ + imports: [CqrsModule, DDD_AuthModule], + controllers: [...httpControllers], + providers: [...commandHandlers, ...repositories, ...mappers], +}) +export class DDD_CarModule {} diff --git a/src/_ddd/car/domain/entity/car.root-entity.ts b/src/_ddd/car/domain/entity/car.root-entity.ts new file mode 100644 index 0000000..fa309b7 --- /dev/null +++ b/src/_ddd/car/domain/entity/car.root-entity.ts @@ -0,0 +1,96 @@ +import { AggregateRoot } from '@/_ddd_shared/ddd/aggregate-root.base'; +import { v4 } from 'uuid'; +import { CarSnapshot } from '../value-object/car-snapshot.value-object'; +import { CreateRentalProps, RentalEntity, RentalStatus } from './rental.entity'; + +interface CarProps { + id: string; + type: string; // SEDAN, SUV, ... + ownerId: string; + number: string; // 123가 1234 + images: string[]; + snapshots: CarSnapshot[]; + rentals: RentalEntity[]; + status: CarStatus; +} +interface CarCreateProps { + type: string; + ownerId: string; + number: string; + images: string[]; +} +type CarStatus = 'ACTIVE' | 'SCRAPPED'; +export class CarEntity extends AggregateRoot { + /** + * 해당 생성은 도메인상의 생성을 의미한다. + * 실제 검증은 외부 서비스를 통해 진행후 이루어져야한다. + * 예를 들어, 차량정보 API를 통해 유저가 실제 소유자가 맞는지 등의 검증을 외부서비스를 통해 진행해야한다. + */ + static create(createProps: CarCreateProps) { + const id = v4(); + const props = { + id, + ...createProps, + rentals: [], + status: 'ACTIVE' as CarStatus, + snapshots: [], + }; + return new CarEntity({ id, props }).addSnapshot(); + } + + isOwner(userId: string): boolean { + return this.props.ownerId === userId; + } + + // ------------------------------------------------ + // Rental + // ------------------------------------------------ + /** + * 렌트정보는 추가시 제거할수 없다. + * 렌트정보는 반드시 양방향의 동의가 필요하다. + * 즉, 렌탈정보 생성은 요청과 동시에 이루어져야한다. + */ + addRental(rental: CreateRentalProps): CarEntity { + if (!this.canRent()) { + throw new Error('Car is not available'); + } + const newRental = RentalEntity.create(rental); + this.props.rentals.push(newRental); + return this; + } + + updateRentalStatus(rentalId: string, status: RentalStatus): CarEntity { + const rental = this.props.rentals.find((r) => r.id === rentalId); + if (!rental) { + throw new Error('Rental not found'); + } + rental.updateStatus(status).addSnapshot(); + return this; + } + + canRent(): boolean { + // 차량이 대여중인지 확인 + const rental = this.props.rentals.find( + (r) => r.getProps().status === 'APPROVED', + ); + if (rental) { + return false; + } + return this.props.status === 'ACTIVE'; + } + + // ------------------------------------------------ + // Snapshot + // ------------------------------------------------ + addSnapshot(): CarEntity { + const { id: _, images: __, snapshots: ___, ...rest } = this.getProps(); + const snapshot = CarSnapshot.create({ + id: v4(), + ...rest, + }); + this.props.snapshots.push(snapshot); + return this; + } + + public validate(): void {} +} diff --git a/src/_ddd/car/domain/entity/rental.entity.ts b/src/_ddd/car/domain/entity/rental.entity.ts new file mode 100644 index 0000000..ca26366 --- /dev/null +++ b/src/_ddd/car/domain/entity/rental.entity.ts @@ -0,0 +1,57 @@ +import { Entity } from '@/_ddd_shared/ddd/entity.base'; +import { v4 } from 'uuid'; +import { RentalSnapshot } from '../value-object/rental-snapshot.value-object'; + +export interface RentalProps { + id: string; + userId: string; + startDate: Date; + endDate: Date; + status: RentalStatus; + snapshots: RentalSnapshot[]; +} + +export interface CreateRentalProps { + userId: string; + startDate: Date; + endDate: Date; +} +/** + * 렌트 상태 + * - REQUESTED: 렌트 요청 + * - APPROVED: 렌트 수락 + * - REJECTED: 렌트 거절 + * - COMPLETED: 렌트 완료 (계약 완료, 렌트 종료) + */ +export type RentalStatus = 'REQUESTED' | 'APPROVED' | 'REJECTED' | 'COMPLETED'; + +export class RentalEntity extends Entity { + static create(createProps: CreateRentalProps): RentalEntity { + const id = v4(); + const props = { + id, + ...createProps, + status: 'REQUESTED' as RentalStatus, + snapshots: [], + }; + return new RentalEntity({ id, props }).addSnapshot(); + } + + updateStatus(status: RentalStatus): RentalEntity { + this.props.status = status; + return this; + } + + addSnapshot(): RentalEntity { + const snapshot = new RentalSnapshot({ + id: v4(), + status: this.props.status, + startDate: this.props.startDate, + endDate: this.props.endDate, + }); + this.props.snapshots.push(snapshot); + return this; + } + + public validate(): void {} +} diff --git a/src/_ddd/car/domain/error/car-error.codes.ts b/src/_ddd/car/domain/error/car-error.codes.ts new file mode 100644 index 0000000..4e4a607 --- /dev/null +++ b/src/_ddd/car/domain/error/car-error.codes.ts @@ -0,0 +1,3 @@ +export const CAR_ALREADY_EXISTS = 'CAR_ALREADY_EXISTS'; +export const CAR_NOT_FOUND = 'CAR_NOT_FOUND'; +export const CAR_OWNER_CANNOT_RENT = 'CAR_OWNER_CANNOT_RENT'; diff --git a/src/_ddd/car/domain/error/index.ts b/src/_ddd/car/domain/error/index.ts new file mode 100644 index 0000000..5c0a92b --- /dev/null +++ b/src/_ddd/car/domain/error/index.ts @@ -0,0 +1,29 @@ +import { DomainException } from '@/_ddd_shared/exceptions'; +import { ExceptionType } from '@/_ddd_shared/types/exception.type'; +import { DomainExceptionRes } from '@/_ddd_shared/types/response.type'; +import * as codes from './car-error.codes'; + +export class CarException< + C extends string, + S extends number, +> extends DomainException {} + +// 이미 존재하는 차량 정보입니다. +export const CarAlreadyExists = CarException.create( + codes.CAR_ALREADY_EXISTS, + 400, +); +export type CarAlreadyExistsType = ExceptionType; +export type CarAlreadyExistsErr = DomainExceptionRes; + +// 차량 정보를 찾을 수 없습니다. +export const CarNotFound = CarException.create(codes.CAR_NOT_FOUND, 404); +export type CarNotFoundType = ExceptionType; +export type CarNotFoundErr = DomainExceptionRes; + +export const CarOwnerCannotRent = CarException.create( + codes.CAR_OWNER_CANNOT_RENT, + 400, +); +export type CarOwnerCannotRentType = ExceptionType; +export type CarOwnerCannotRentErr = DomainExceptionRes; diff --git a/src/_ddd/car/domain/value-object/car-snapshot.value-object.ts b/src/_ddd/car/domain/value-object/car-snapshot.value-object.ts new file mode 100644 index 0000000..3ac7e4e --- /dev/null +++ b/src/_ddd/car/domain/value-object/car-snapshot.value-object.ts @@ -0,0 +1,19 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { CAR_STATUS } from '@prisma/client'; + +export interface CarSnapshotProps { + id: string; + ownerId: string; + type: string; + number: string; + status: CAR_STATUS; +} + +export class CarSnapshot extends ValueObject { + static create(props: CarSnapshotProps): CarSnapshot { + const snapshot = new CarSnapshot(props); + snapshot.validate(); + return snapshot; + } + protected validate(): void {} +} diff --git a/src/_ddd/car/domain/value-object/rental-snapshot.value-object.ts b/src/_ddd/car/domain/value-object/rental-snapshot.value-object.ts new file mode 100644 index 0000000..925d3ea --- /dev/null +++ b/src/_ddd/car/domain/value-object/rental-snapshot.value-object.ts @@ -0,0 +1,17 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { RentalStatus } from '../entity/rental.entity'; + +export interface RentalSnapshotProps { + id: string; + status: RentalStatus; + startDate: Date; + endDate: Date; +} + +export class RentalSnapshot extends ValueObject { + constructor(props: RentalSnapshotProps) { + super(props); + } + + validate(): void {} +} diff --git a/src/_ddd/car/infrastructure/car.repository.ts b/src/_ddd/car/infrastructure/car.repository.ts new file mode 100644 index 0000000..6192443 --- /dev/null +++ b/src/_ddd/car/infrastructure/car.repository.ts @@ -0,0 +1,66 @@ +import { PrismaRepositoryBase } from '@/_ddd_shared/db/prisma.repository.base'; +import { PrismaService } from '@common/prisma/prisma.service'; +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; +import { CAR_STATUS } from '@prisma/client'; +import { CarMapper } from '../car.mapper'; +import { CarEntity } from '../domain/entity/car.root-entity'; + +@Injectable() +export class CarRepository extends PrismaRepositoryBase { + constructor( + protected readonly prisma: PrismaService, + private readonly carMapper: CarMapper, + ) { + super(prisma); + } + + async save(car: CarEntity, tx?: PrismaTxType): Promise { + const { create, update } = this.carMapper.toPersistence(car); + await this.excute(async (prisma) => { + await prisma.car.upsert({ + where: { id: car.id }, + update, + create, + }); + }, tx); + return car; + } + + async findById(id: string, tx?: PrismaTxType): Promise { + return await this.excute(async (prisma) => { + const car = await prisma.car.findUnique({ + where: { id }, + include: { + snapshots: true, + rentals: { + include: { + snapshots: true, + }, + }, + }, + }); + return car ? this.carMapper.toDomain(car) : null; + }, tx); + } + async findByNumberAndStatus( + number: string, + status: CAR_STATUS, + tx?: PrismaTxType, + ): Promise { + return await this.excute(async (prisma) => { + const car = await prisma.car.findFirst({ + where: { number, status }, + include: { + snapshots: true, + rentals: { + include: { + snapshots: true, + }, + }, + }, + }); + return car ? this.carMapper.toDomain(car) : null; + }, tx); + } +} diff --git a/src/_ddd/certification/application/command/certificate-code/certificate-code.command-handler.ts b/src/_ddd/certification/application/command/certificate-code/certificate-code.command-handler.ts new file mode 100644 index 0000000..60a3c0a --- /dev/null +++ b/src/_ddd/certification/application/command/certificate-code/certificate-code.command-handler.ts @@ -0,0 +1,48 @@ +import { + CertificationCodeExpiredType, + CertificationCodeNotFound, + CertificationCodeNotFoundType, +} from '@/_ddd/certification/domain/error'; +import { CertificateCodeUseCase } from '@/_ddd/certification/domain/port/in/certificate-code.use-case'; +import { CertificationRepository } from '@/_ddd/certification/infrastructure/repository/certification-code.repository'; +import { AggregateID } from '@/_ddd_shared/ddd/entity.base'; +import { DomainException, handleException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { CertificateCodeCommand } from './certificate-code.command'; + +@CommandHandler(CertificateCodeCommand) +export class CertificateCodeCommandHandler + implements ICommandHandler, CertificateCodeUseCase +{ + constructor( + private readonly ceritficationRepository: CertificationRepository, + ) {} + + async execute( + command: CertificateCodeCommand, + ): Promise< + Result< + AggregateID, + CertificationCodeNotFoundType | CertificationCodeExpiredType + > + > { + try { + const code = await this.ceritficationRepository.findOneByTargetAndCode({ + ...command, + }); + if (!code) { + throw CertificationCodeNotFound('NOT_FOUND'); + } + code.verify(); + await this.ceritficationRepository.save(code); + return Ok(code.id); + } catch (error) { + if (error instanceof DomainException) { + return Err(error); + } + throw handleException(error as Error); + } + } +} diff --git a/src/_ddd/certification/application/command/certificate-code/certificate-code.command.ts b/src/_ddd/certification/application/command/certificate-code/certificate-code.command.ts new file mode 100644 index 0000000..0fb9325 --- /dev/null +++ b/src/_ddd/certification/application/command/certificate-code/certificate-code.command.ts @@ -0,0 +1,28 @@ +import { + CertificationTargetType, + CertificationType, +} from '@/_ddd/certification/domain/type/certification.code.type'; +import { Command, CommandProps } from '@/_ddd_shared/app/command/command.base'; + +export class CertificateCodeCommand extends Command { + readonly type: CertificationType; + readonly targetType: CertificationTargetType; + readonly target: string; + readonly code: string; + constructor( + props: CommandProps<{ + target: { + type: CertificationType; + targetType: CertificationTargetType; + target: string; + }; + code: string; + }>, + ) { + super(props); + this.type = props.target.type; + this.targetType = props.target.targetType; + this.target = props.target.target; + this.code = props.code; + } +} diff --git a/src/_ddd/certification/application/command/certificate-code/http/certificate-code.req.type.ts b/src/_ddd/certification/application/command/certificate-code/http/certificate-code.req.type.ts new file mode 100644 index 0000000..a59252d --- /dev/null +++ b/src/_ddd/certification/application/command/certificate-code/http/certificate-code.req.type.ts @@ -0,0 +1,26 @@ +import { + CertificationTargetType, + CertificationType, +} from '@/_ddd/certification/domain/type/certification.code.type'; + +export interface CertificateCodeHttpReq { + /** + * 인증번호 + */ + code: string; + + /** + * 인증대상 : 이메일주소, 핸드폰번호 + */ + target: string; + + /** + * 인증대상 종류: PHONE, EMAIL + */ + targetType: CertificationTargetType; + + /** + * 인증 종류: SIGN_UP, FIND_PASSWORD + */ + type: CertificationType; +} diff --git a/src/_ddd/certification/application/command/certificate-code/http/certificate-code.res-type.ts b/src/_ddd/certification/application/command/certificate-code/http/certificate-code.res-type.ts new file mode 100644 index 0000000..2c45b38 --- /dev/null +++ b/src/_ddd/certification/application/command/certificate-code/http/certificate-code.res-type.ts @@ -0,0 +1,10 @@ +export interface CertificateCodeHttpRes { + /** + * 인증번호 ID + * + * 인증이 완료된 코드의 ID로써, + * + * 인증번호가 필요한 API의 경우 해당 ID를 포함하여 요청해야한다. + */ + id: string; +} diff --git a/src/_ddd/certification/application/command/certificate-code/http/certification-code.http.controller.ts b/src/_ddd/certification/application/command/certificate-code/http/certification-code.http.controller.ts new file mode 100644 index 0000000..ff86c98 --- /dev/null +++ b/src/_ddd/certification/application/command/certificate-code/http/certification-code.http.controller.ts @@ -0,0 +1,42 @@ +import { + CertificationCodeExpiredType, + CertificationCodeNotFoundType, +} from '@/_ddd/certification/domain/error'; +import { handleException } from '@/_ddd_shared/exceptions'; +import { Result, match } from '@/_ddd_shared/types'; +import { Response } from '@/_ddd_shared/types/response.type'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { TypedBody, TypedRoute } from '@nestia/core'; +import { Controller } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { CertificateCodeCommand } from '../certificate-code.command'; +import { CertificateCodeHttpReq } from './certificate-code.req.type'; +import { CertificateCodeHttpRes } from './certificate-code.res-type'; + +@Controller('certification') +export class CertificateCodeHttpController { + constructor(private readonly commandBus: CommandBus) {} + + @TypedRoute.Patch('') + async createCertificationCode( + @TypedBody() body: CertificateCodeHttpReq, + ): Promise< + | Response + | CertificationCodeNotFoundType + | CertificationCodeExpiredType + > { + const { targetType, target, type, code } = body; + const command = new CertificateCodeCommand({ + target: { target, targetType, type }, + code, + }); + const result: Result< + string, + CertificationCodeNotFoundType | CertificationCodeExpiredType + > = await this.commandBus.execute(command); + return match(result, { + Ok: (code) => res({ id: code }), + Err: handleException, + }); + } +} diff --git a/src/_ddd/certification/application/command/request-code/graphql/dto/id.gql-res.dto.ts b/src/_ddd/certification/application/command/request-code/graphql/dto/id.gql-res.dto.ts new file mode 100644 index 0000000..52c3799 --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/graphql/dto/id.gql-res.dto.ts @@ -0,0 +1,11 @@ +import { Field, ObjectType } from '@nestjs/graphql'; + +@ObjectType() +export class IdGqlResponse { + constructor(id: string) { + this.id = id; + } + + @Field() + readonly id: string; +} diff --git a/src/_ddd/certification/application/command/request-code/graphql/dto/request-code-gql-res.dto.ts b/src/_ddd/certification/application/command/request-code/graphql/dto/request-code-gql-res.dto.ts new file mode 100644 index 0000000..069f32d --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/graphql/dto/request-code-gql-res.dto.ts @@ -0,0 +1,8 @@ +import { GqlResponse } from '@/_ddd_shared/ui/response-base'; +import { RequestCodeHttpRes } from '../../http/request-code.res-type'; + +class RequestCodeResDto implements RequestCodeHttpRes { + id!: string; +} + +export class RequestCodeGqlResDto extends GqlResponse(RequestCodeResDto) {} diff --git a/src/_ddd/certification/application/command/request-code/graphql/dto/request-code.gql-req.dto.ts b/src/_ddd/certification/application/command/request-code/graphql/dto/request-code.gql-req.dto.ts new file mode 100644 index 0000000..1a1393e --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/graphql/dto/request-code.gql-req.dto.ts @@ -0,0 +1,32 @@ +import { ArgsType, Field, InputType, registerEnumType } from '@nestjs/graphql'; +import { RequestCodeHttpReq } from '../../http/request-code.req-type'; + +export enum CertificationTargetTypeEnum { + PHONE = 'PHONE', +} + +export enum CertificationTypeEnum { + SIGN_UP = 'SIGN_UP', + FIND_PASSWORD = 'FIND_PASSWORD', +} + +registerEnumType(CertificationTargetTypeEnum, { + name: 'CertificationTargetType', +}); + +registerEnumType(CertificationTypeEnum, { + name: 'CertificationType', +}); + +@ArgsType() +@InputType() +export class RequestCodeGqlRequestDto implements RequestCodeHttpReq { + @Field() + readonly targetType!: CertificationTargetTypeEnum; + + @Field() + readonly target!: string; + + @Field() + readonly type!: CertificationTypeEnum; +} diff --git a/src/_ddd/certification/application/command/request-code/graphql/request-code.resolver.ts b/src/_ddd/certification/application/command/request-code/graphql/request-code.resolver.ts new file mode 100644 index 0000000..d02563b --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/graphql/request-code.resolver.ts @@ -0,0 +1,23 @@ +import { AggregateID } from '@/_ddd_shared/ddd/entity.base'; +import { ArgumentInvalidException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { CommandBus } from '@nestjs/cqrs'; +import { Args, Mutation, Resolver } from '@nestjs/graphql'; +import { RequestCodeCommand } from '../request-code.command'; +import { IdGqlResponse } from './dto/id.gql-res.dto'; +import { RequestCodeGqlRequestDto } from './dto/request-code.gql-req.dto'; + +@Resolver() +export class RequestCodeGraphqlResolver { + constructor(private readonly commandBus: CommandBus) {} + + @Mutation(() => IdGqlResponse) + async create( + @Args('input') input: RequestCodeGqlRequestDto, + ): Promise { + const command = new RequestCodeCommand(input); + const id: Result = + await this.commandBus.execute(command); + return new IdGqlResponse(id.unwrap()); + } +} diff --git a/src/_ddd/certification/application/command/request-code/http/request-code.http.controller.ts b/src/_ddd/certification/application/command/request-code/http/request-code.http.controller.ts new file mode 100644 index 0000000..266e882 --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/http/request-code.http.controller.ts @@ -0,0 +1,43 @@ +import { CertificationLimitExceededRes } from '@/_ddd/certification/domain/error'; +import { AggregateID } from '@/_ddd_shared/ddd/entity.base'; +import { + ArgumentInvalidException, + handleException, +} from '@/_ddd_shared/exceptions'; +import { Result, match } from '@/_ddd_shared/types'; +import { Response } from '@/_ddd_shared/types/response.type'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { TypedBody, TypedException, TypedRoute } from '@nestia/core'; +import { Controller } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { RequestCodeCommand } from '../request-code.command'; +import { RequestCodeHttpReq } from './request-code.req-type'; +import { RequestCodeHttpRes } from './request-code.res-type'; + +@Controller('certification') +export class RequestCodeHttpController { + constructor(private readonly commandBus: CommandBus) {} + /** + * 인증 요청 API + * + * @Tag Certification + */ + @TypedRoute.Post('') + @TypedException( + 400, + 'AggregateRoot Validation Error', + ) + @TypedException(400, 'LIMIT_EXCEEDED') + async requestCode( + @TypedBody() body: RequestCodeHttpReq, + ): Promise | ArgumentInvalidException> { + const command = new RequestCodeCommand(body); + const result: Result = + await this.commandBus.execute(command); + + return match(result, { + Ok: (id) => res({ id }), + Err: handleException, + }); + } +} diff --git a/src/_ddd/certification/application/command/request-code/http/request-code.req-type.ts b/src/_ddd/certification/application/command/request-code/http/request-code.req-type.ts new file mode 100644 index 0000000..28408bf --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/http/request-code.req-type.ts @@ -0,0 +1,18 @@ +import { + CertificationTargetType, + CertificationType, +} from '@/_ddd/certification/domain/type/certification.code.type'; +export interface RequestCodeHttpReq { + /** + * 인증번호 사용 목적 + */ + type: CertificationType; + /** + * 인증 대상 종류 + */ + targetType: CertificationTargetType; + /** + * 인증 대상 + */ + target: string; +} diff --git a/src/_ddd/certification/application/command/request-code/http/request-code.res-type.ts b/src/_ddd/certification/application/command/request-code/http/request-code.res-type.ts new file mode 100644 index 0000000..dd49f41 --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/http/request-code.res-type.ts @@ -0,0 +1,3 @@ +export type RequestCodeHttpRes = { + id: string; +}; diff --git a/src/_ddd/certification/application/command/request-code/request-code.command-handler.ts b/src/_ddd/certification/application/command/request-code/request-code.command-handler.ts new file mode 100644 index 0000000..d5923ce --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/request-code.command-handler.ts @@ -0,0 +1,84 @@ +import { CertificationCodeEntity } from '@/_ddd/certification/domain/entity/certification-code.root-entity'; +import { + CertificationException, + CertificationLimitExceeded, + CertificationLimitExceededType, +} from '@/_ddd/certification/domain/error'; +import { RequestCodeUseCase } from '@/_ddd/certification/domain/port/in/request-code.use-case'; +import { CertificationRepository } from '@/_ddd/certification/infrastructure/repository/certification-code.repository'; +import { AggregateID } from '@/_ddd_shared/ddd/entity.base'; +import { + ArgumentInvalidException, + handleException, +} from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { PrismaService } from '@common/prisma/prisma.service'; +import { Logger } from '@nestjs/common'; +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { EventEmitter2 } from '@nestjs/event-emitter'; +import { RequestCodeCommand } from './request-code.command'; + +@CommandHandler(RequestCodeCommand) +export class RequestCodeCommandHandler + implements ICommandHandler, RequestCodeUseCase +{ + private logger = new Logger(RequestCodeCommandHandler.name); + constructor( + private readonly prisma: PrismaService, + private readonly certificationRepository: CertificationRepository, + private readonly eventEmitter: EventEmitter2, + ) {} + + async execute( + command: RequestCodeCommand, + ): Promise< + Result< + AggregateID, + ArgumentInvalidException | CertificationLimitExceededType + > + > { + try { + return await this.prisma.$transaction(async (tx) => { + //TODO: type이 signup인경우 해당 정보를 사용하고있는 유저가 있는지 확인 필요 - User 도메인과 소통 + + // 새로운 인증코드 생성 + const code = CertificationCodeEntity.create({ + type: command.type, + target: command.target, + targetType: command.targetType, + }); + const target = code.getProps().target; + const exist = await this.certificationRepository.findManyByTarget( + target, + tx, + ); + if (exist.length > 5) { + throw CertificationLimitExceeded( + 'LIMIT_EXCEEDED', + '인증 횟수 초과', + exist, + ); + } + // 기존 인증코드 만료처리 + await Promise.all([ + ...exist.map(async (code) => { + code.expire(); + await this.certificationRepository.save(code, tx); + }), + ]); + await this.certificationRepository.save(code, tx); + code.publishEvents(this.logger, this.eventEmitter); + return Ok(code.id); + }); + } catch (error) { + if (error instanceof ArgumentInvalidException) { + return Err(error); + } + if (error instanceof CertificationException) { + return Err(error); + } + throw handleException(error as Error); + } + } +} diff --git a/src/_ddd/certification/application/command/request-code/request-code.command.ts b/src/_ddd/certification/application/command/request-code/request-code.command.ts new file mode 100644 index 0000000..64ac044 --- /dev/null +++ b/src/_ddd/certification/application/command/request-code/request-code.command.ts @@ -0,0 +1,17 @@ +import { + CertificationTargetType, + CertificationType, +} from '@/_ddd/certification/domain/type/certification.code.type'; +import { Command, CommandProps } from '@/_ddd_shared/app/command/command.base'; + +export class RequestCodeCommand extends Command { + readonly type: CertificationType; + readonly targetType: CertificationTargetType; + readonly target: string; + constructor(props: CommandProps) { + super(props); + this.type = props.type; + this.targetType = props.targetType; + this.target = props.target; + } +} diff --git a/src/_ddd/certification/application/query/find-certification-by-phone.graphql-resolver.ts b/src/_ddd/certification/application/query/find-certification-by-phone.graphql-resolver.ts new file mode 100644 index 0000000..a70fc8c --- /dev/null +++ b/src/_ddd/certification/application/query/find-certification-by-phone.graphql-resolver.ts @@ -0,0 +1,12 @@ +import { QueryBus } from '@nestjs/cqrs'; +import { Args, Query, Resolver } from '@nestjs/graphql'; + +@Resolver() +export class FindCertificationByPhoneQueryResolver { + constructor(private readonly queryBus: QueryBus) {} + + @Query(() => String) + async findCertificationByPhone(@Args('phone') phone: string) { + return phone; + } +} diff --git a/src/_ddd/certification/application/query/find-certification-by-phone.query-handler.ts b/src/_ddd/certification/application/query/find-certification-by-phone.query-handler.ts new file mode 100644 index 0000000..3fa2edb --- /dev/null +++ b/src/_ddd/certification/application/query/find-certification-by-phone.query-handler.ts @@ -0,0 +1,14 @@ +import { IQueryHandler, QueryHandler } from '@nestjs/cqrs'; +import { CertificationRepository } from '../../infrastructure/repository/certification-code.repository'; +import { FindCertificationByPhoneQuery } from './find-certification-by-phone.query'; + +@QueryHandler(FindCertificationByPhoneQuery) +export class FindCertificationByPhoneQueryHandler implements IQueryHandler { + constructor( + private readonly certificationRepository: CertificationRepository, + ) {} + + async execute(): Promise { + return ''; + } +} diff --git a/src/_ddd/certification/application/query/find-certification-by-phone.query.ts b/src/_ddd/certification/application/query/find-certification-by-phone.query.ts new file mode 100644 index 0000000..14529b8 --- /dev/null +++ b/src/_ddd/certification/application/query/find-certification-by-phone.query.ts @@ -0,0 +1,6 @@ +export class FindCertificationByPhoneQuery { + readonly phone: string; + constructor(phone: string) { + this.phone = phone; + } +} diff --git a/src/_ddd/certification/certification.module.ts b/src/_ddd/certification/certification.module.ts new file mode 100644 index 0000000..fe90456 --- /dev/null +++ b/src/_ddd/certification/certification.module.ts @@ -0,0 +1,60 @@ +import { Module, Provider } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; +import { CertificateCodeCommandHandler } from './application/command/certificate-code/certificate-code.command-handler'; +import { CertificateCodeHttpController } from './application/command/certificate-code/http/certification-code.http.controller'; +import { RequestCodeGraphqlResolver } from './application/command/request-code/graphql/request-code.resolver'; +import { RequestCodeHttpController } from './application/command/request-code/http/request-code.http.controller'; +import { RequestCodeCommandHandler } from './application/command/request-code/request-code.command-handler'; +import { FindCertificationByPhoneQueryResolver } from './application/query/find-certification-by-phone.graphql-resolver'; +import { CertificationMapper } from './domain/cerfication.mapper'; +import { SaveCertificationPort } from './domain/port/out/save-certification.port'; +import { CertificationService } from './domain/service/certification.service'; +import { CertificationRepository } from './infrastructure/repository/certification-code.repository'; + +/** + * 컨트롤러 + */ +const messageController = []; +const httpController = [ + RequestCodeHttpController, + CertificateCodeHttpController, +]; + +/** + * 프로바이더 + */ +// 도메인 서비스 +const graphQlResolvers = [ + RequestCodeGraphqlResolver, + FindCertificationByPhoneQueryResolver, +]; +const commands: Provider[] = [ + RequestCodeCommandHandler, + CertificateCodeCommandHandler, +]; +const queries: Provider[] = []; +const mapper: Provider[] = [CertificationMapper]; +const service: Provider[] = [CertificationService]; +// 인프라 서비스 +const repositories: Provider[] = [ + { + provide: SaveCertificationPort, + useClass: CertificationRepository, + }, + CertificationRepository, +]; + +@Module({ + imports: [CqrsModule], + controllers: [...messageController, ...httpController], + providers: [ + ...graphQlResolvers, + ...repositories, + ...commands, + ...queries, + ...mapper, + ...service, + ], + exports: [...service], +}) +export class CertificationModule {} diff --git a/src/_ddd/certification/domain/cerfication.mapper.ts b/src/_ddd/certification/domain/cerfication.mapper.ts new file mode 100644 index 0000000..350bb7f --- /dev/null +++ b/src/_ddd/certification/domain/cerfication.mapper.ts @@ -0,0 +1,105 @@ +// infrastructure/mapper/certification-code.mapper.ts + +import { Mapper } from '@/_ddd_shared/ddd/mapper.interface'; +import { Injectable } from '@nestjs/common'; +import { + CertificationCode as PrismaCertificationCode, + CertificationRecord as PrismaCertificationRecord, +} from '@prisma/client'; +import { CertificationCodeEntity } from './entity/certification-code.root-entity'; +import { CertificationRecordEntity } from './entity/certification-record.entity'; +import { CertificationCodeStatus } from './value-object/certification-code-status.value-object'; +import { CertificationTarget } from './value-object/certification-target.value-object'; + +@Injectable() +export class CertificationMapper implements Mapper { + toPersistence(certificationCode: CertificationCodeEntity) { + const props = certificationCode.getProps(); + const { target, targetType, type } = props.target.unpack(); + const expiresAt = props.expiresAt; + const status = props.status.unpack(); + const recordProps = props?.certificationRecord?.getProps(); + const record = recordProps + ? { + id: recordProps.id, + userId: recordProps.userId, + } + : null; + + const _code = { + code: props.code, + targetType, + type, + status, + expiresAt, + target, + }; + + const create = { + id: props.id, + ..._code, + }; + + const update = { + ..._code, + certification: record + ? { + upsert: { + update: { + userId: record.userId, + }, + create: { + id: record.id, + userId: record.userId, + }, + }, + } + : undefined, // 조건에 따라 필드를 추가하지 않도록 undefined 반환 + }; + + return { create, update }; + } + + toDomain( + prismaReturn: PrismaCertificationCode & { + certification?: PrismaCertificationRecord | null; + }, + ) { + const { certification, ...code } = prismaReturn; + + // Certification Record Entity + const _certification = certification + ? new CertificationRecordEntity({ + id: certification.id, + props: { + id: certification.id, + userId: certification.userId, + }, + }) + : undefined; + + // target + const { target, targetType, type } = code; + const _target = new CertificationTarget({ target, targetType, type }); + + // status + const { status } = code; + const _status = new CertificationCodeStatus(status); + + return new CertificationCodeEntity({ + id: code.id, + props: { + id: code.id, + code: code.code, + target: _target, + status: _status, + expiresAt: code.expiresAt, + certificationRecord: _certification, + }, + }); + } + + toResponse(entity: CertificationCodeEntity) { + return entity; + } +} diff --git a/src/_ddd/certification/domain/entity/certification-code.root-entity.ts b/src/_ddd/certification/domain/entity/certification-code.root-entity.ts new file mode 100644 index 0000000..446a47a --- /dev/null +++ b/src/_ddd/certification/domain/entity/certification-code.root-entity.ts @@ -0,0 +1,103 @@ +import { AggregateRoot } from '@/_ddd_shared/ddd/aggregate-root.base'; +import { ArgumentInvalidException } from '@/_ddd_shared/exceptions'; +import typia from 'typia'; +import { v4 } from 'uuid'; +import { + CertificationCodeAlreadyVerified, + CertificationCodeExpired, + CertificationCodeNotVerified, +} from '../error'; +import { RequestCertificationCodeEvent } from '../event/request-code.event'; +import { + CertificationCodeProps, + CreateCertificationCodeProps, +} from '../type/certification.code.type'; +import { CertificationCodeStatus } from '../value-object/certification-code-status.value-object'; +import { CertificationTarget } from '../value-object/certification-target.value-object'; +import { CertificationRecordEntity } from './certification-record.entity'; + +export class CertificationCodeEntity extends AggregateRoot { + protected _id!: string; + + static create(createCertificationCodeProps: CreateCertificationCodeProps) { + const id = v4(); + const code = this.generateCode(); + const expiresAt = this.generateExpiresAt(); + const target = new CertificationTarget(createCertificationCodeProps); + const status = CertificationCodeStatus.PENDING; + const props = { + id, + code, + expiresAt, + target, + status, + }; + const certificationCode = new CertificationCodeEntity({ id, props }); + certificationCode.validate(); + + // TODO: 생성 이벤트 발급 (Notification 도메인이 구독하여 이벤트 처리) + /** + * 여기에 작성 + */ + certificationCode.addEvent( + new RequestCertificationCodeEvent({ + aggregateId: id, + ...target.unpack(), + code, + }), + ); + return certificationCode; + } + + private static generateCode() { + return Math.floor(Math.random() * 1000000) + .toString() + .padStart(6, '0'); + } + + private static generateExpiresAt() { + const expiresAt = new Date(); + expiresAt.setMinutes(expiresAt.getMinutes() + 10); + return expiresAt; + } + + record(userId: string) { + const certificationRecord = CertificationRecordEntity.create({ + userId, + }); + this.props.certificationRecord = certificationRecord; + } + + ////////////////////////// + // Status + expire() { + this.props.status = CertificationCodeStatus.EXPIRED; + } + + verify() { + if (this.props.expiresAt < new Date()) { + throw CertificationCodeExpired('Certification code is expired'); + } + if (!CertificationCodeStatus.PENDING.equals(this.props.status)) { + throw CertificationCodeAlreadyVerified( + 'Certification code is already verified', + ); + } + this.props.status = CertificationCodeStatus.VERIFIED; + } + + success() { + console.log(this.props.status.unpack()); + if (!CertificationCodeStatus.VERIFIED.equals(this.props.status)) { + throw CertificationCodeNotVerified('Certification code is not verified'); + } + this.props.status = CertificationCodeStatus.SUCCESS; + } + + ////////////////////////// + public validate(): void { + if (!typia.is(this.props)) { + throw new ArgumentInvalidException('Invalid certification code props'); + } + } +} diff --git a/src/_ddd/certification/domain/entity/certification-record.entity.ts b/src/_ddd/certification/domain/entity/certification-record.entity.ts new file mode 100644 index 0000000..17678fd --- /dev/null +++ b/src/_ddd/certification/domain/entity/certification-record.entity.ts @@ -0,0 +1,19 @@ +import { Entity } from '@/_ddd_shared/ddd/entity.base'; +import { v4 } from 'uuid'; +import { CertificationRecordProps } from '../type/certification-record.type'; + +export class CertificationRecordEntity extends Entity { + protected _id!: string; + + static create({ userId }: { userId: string }) { + const id = v4(); + const props = { + id, + userId, + }; + + return new CertificationRecordEntity({ id, props }); + } + + public validate(): void {} +} diff --git a/src/_ddd/certification/domain/error/exception.codes.ts b/src/_ddd/certification/domain/error/exception.codes.ts new file mode 100644 index 0000000..5dce3cf --- /dev/null +++ b/src/_ddd/certification/domain/error/exception.codes.ts @@ -0,0 +1,7 @@ +export const CERTIFICATION_LIMIT_EXCEEDED = 'CERTIFICATION.LIMIT_EXCEEDEDED'; +export const CERTIFICATION_EXIST_CODE = 'CERTIFICATION.INVALID_CODE'; +export const CERTIFICATION_CODE_NOT_FOUND = 'CERTIFICATION.NOT_FOUND'; +export const CERTIFICATION_CODE_EXPIRED = 'CERTIFICATION.EXPIRED'; +export const CERTIFICATION_CODE_NOT_VERIFIED = 'CERTIFICATION.NOT_VERIFIED'; +export const CERTIFICATION_CODE_ALREADY_VERIFIED = + 'CERTIFICATION.ALREADY_VERIFIED'; diff --git a/src/_ddd/certification/domain/error/index.ts b/src/_ddd/certification/domain/error/index.ts new file mode 100644 index 0000000..119b358 --- /dev/null +++ b/src/_ddd/certification/domain/error/index.ts @@ -0,0 +1,64 @@ +import { DomainException } from '@/_ddd_shared/exceptions'; +import { ExceptionType } from '@/_ddd_shared/types/exception.type'; +import { DomainExceptionRes } from '@/_ddd_shared/types/response.type'; +import * as code from './exception.codes'; + +export class CertificationException< + T extends string, + S extends number, +> extends DomainException {} + +// 하루인증 제한횟수 초과 +export const CertificationLimitExceeded = CertificationException.create( + code.CERTIFICATION_LIMIT_EXCEEDED, + 400, +); +export type CertificationLimitExceededType = ExceptionType< + typeof CertificationLimitExceeded +>; +export type CertificationLimitExceededRes = + DomainExceptionRes; + +// 코드 존재 안함 +export const CertificationCodeNotFound = CertificationException.create( + code.CERTIFICATION_CODE_NOT_FOUND, + 404, +); +export type CertificationCodeNotFoundType = ExceptionType< + typeof CertificationCodeNotFound +>; +export type CertificationCodeNotFoundRes = + DomainExceptionRes; + +// 코드 만료 +export const CertificationCodeExpired = CertificationException.create( + code.CERTIFICATION_CODE_EXPIRED, + 400, +); +export type CertificationCodeExpiredType = ExceptionType< + typeof CertificationCodeExpired +>; +export type CertificationCodeExpiredRes = + DomainExceptionRes; + +// 이미 인증 완료 +export const CertificationCodeAlreadyVerified = CertificationException.create( + code.CERTIFICATION_CODE_ALREADY_VERIFIED, + 400, +); +export type CertificationCodeAlreadyVerifiedType = ExceptionType< + typeof CertificationCodeAlreadyVerified +>; +export type CertificationCodeAlreadyVerifiedRes = + DomainExceptionRes; + +// 인증 안됨 +export const CertificationCodeNotVerified = CertificationException.create( + code.CERTIFICATION_CODE_NOT_VERIFIED, + 400, +); +export type CertificationCodeNotVerifiedType = ExceptionType< + typeof CertificationCodeNotVerified +>; +export type CertificationCodeNotVerifiedRes = + DomainExceptionRes; diff --git a/src/_ddd/certification/domain/event/request-code.event.ts b/src/_ddd/certification/domain/event/request-code.event.ts new file mode 100644 index 0000000..a679e36 --- /dev/null +++ b/src/_ddd/certification/domain/event/request-code.event.ts @@ -0,0 +1,23 @@ +import { + DomainEvent, + DomainEventProps, +} from '@/_ddd_shared/ddd/domain-event/domain-event.base'; +import { + CertificationTargetType, + CertificationType, +} from '../type/certification.code.type'; + +export class RequestCertificationCodeEvent extends DomainEvent { + readonly targetType: CertificationTargetType; + readonly type: CertificationType; + readonly target: string; + readonly code: string; + + constructor(props: DomainEventProps) { + super(props); + this.targetType = props.targetType; + this.type = props.type; + this.target = props.target; + this.code = props.code; + } +} diff --git a/src/_ddd/certification/domain/port/in/certificate-code.use-case.ts b/src/_ddd/certification/domain/port/in/certificate-code.use-case.ts new file mode 100644 index 0000000..fd16156 --- /dev/null +++ b/src/_ddd/certification/domain/port/in/certificate-code.use-case.ts @@ -0,0 +1,21 @@ +import { CertificateCodeCommand } from '@/_ddd/certification/application/command/certificate-code/certificate-code.command'; +import { AggregateID } from '@/_ddd_shared/ddd/entity.base'; +import { ArgumentInvalidException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { + CertificationCodeExpiredType, + CertificationCodeNotFoundType, +} from '../../error'; + +export interface CertificateCodeUseCase { + execute( + command: CertificateCodeCommand, + ): Promise< + Result< + AggregateID, + | ArgumentInvalidException + | CertificationCodeExpiredType + | CertificationCodeNotFoundType + > + >; +} diff --git a/src/_ddd/certification/domain/port/in/request-code.use-case.ts b/src/_ddd/certification/domain/port/in/request-code.use-case.ts new file mode 100644 index 0000000..d35f3cc --- /dev/null +++ b/src/_ddd/certification/domain/port/in/request-code.use-case.ts @@ -0,0 +1,16 @@ +import { RequestCodeCommand } from '@/_ddd/certification/application/command/request-code/request-code.command'; +import { AggregateID } from '@/_ddd_shared/ddd/entity.base'; +import { ArgumentInvalidException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { CertificationLimitExceededType } from '../../error'; + +export interface RequestCodeUseCase { + execute( + input: RequestCodeCommand, + ): Promise< + Result< + AggregateID, + ArgumentInvalidException | CertificationLimitExceededType + > + >; +} diff --git a/src/_ddd/certification/domain/port/out/save-certification.port.ts b/src/_ddd/certification/domain/port/out/save-certification.port.ts new file mode 100644 index 0000000..8e47a97 --- /dev/null +++ b/src/_ddd/certification/domain/port/out/save-certification.port.ts @@ -0,0 +1,7 @@ +import { CertificationCodeEntity } from '../../entity/certification-code.root-entity'; + +export abstract class SaveCertificationPort { + abstract save( + certificationCode: CertificationCodeEntity, + ): Promise; +} diff --git a/src/_ddd/certification/domain/service/certification.service.ts b/src/_ddd/certification/domain/service/certification.service.ts new file mode 100644 index 0000000..1295113 --- /dev/null +++ b/src/_ddd/certification/domain/service/certification.service.ts @@ -0,0 +1,43 @@ +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; +import { CertificationRepository } from '../../infrastructure/repository/certification-code.repository'; +import { CertificationCodeNotFound } from '../error'; + +@Injectable() +export class CertificationService { + constructor(private readonly repo: CertificationRepository) {} + + async findById(id: string) { + const certification = await this.repo.findById(id); + if (!certification) { + throw CertificationCodeNotFound('존재하지 않는 코드입니다.'); + } + const props = certification.getProps(); + const targetInfo = props.target.unpack(); + const status = props.status.unpack(); + return { id, ...targetInfo, status }; + } + + async changeStatusSuccess(id: string, tx?: PrismaTxType) { + const certification = await this.repo.findById(id); + if (!certification) { + throw CertificationCodeNotFound('존재하지 않는 코드입니다.'); + } + certification.success(); + await this.repo.save(certification, tx); + } + + async recordCertificationCode( + certificationId: string, + userId: string, + tx?: PrismaTxType, + ) { + const certification = await this.repo.findById(certificationId, tx); + if (!certification) { + throw CertificationCodeNotFound('존재하지 않는 코드입니다.'); + } + certification.record(userId); + await this.repo.save(certification, tx); + return true; + } +} diff --git a/src/_ddd/certification/domain/type/certification-record.type.ts b/src/_ddd/certification/domain/type/certification-record.type.ts new file mode 100644 index 0000000..5225050 --- /dev/null +++ b/src/_ddd/certification/domain/type/certification-record.type.ts @@ -0,0 +1,4 @@ +export interface CertificationRecordProps { + id: string; + userId: string; +} diff --git a/src/_ddd/certification/domain/type/certification.code.type.ts b/src/_ddd/certification/domain/type/certification.code.type.ts new file mode 100644 index 0000000..997e3e4 --- /dev/null +++ b/src/_ddd/certification/domain/type/certification.code.type.ts @@ -0,0 +1,33 @@ +import { CertificationRecordEntity } from '../entity/certification-record.entity'; +import { CertificationCodeStatus } from '../value-object/certification-code-status.value-object'; +import { CertificationTarget } from '../value-object/certification-target.value-object'; + +export interface CertificationCodeProps { + id: string; + status: CertificationCodeStatus; + code: string; + target: CertificationTarget; + expiresAt: Date; + certificationRecord?: CertificationRecordEntity; +} + +export type CertificationTargetType = 'PHONE'; +export type CertificationType = + | 'SIGN_UP' + | 'FIND_PASSWORD' + | 'CHANGE_PHONE_INFO'; + +export interface CertificationTargetProps { + type: CertificationType; + targetType: CertificationTargetType; + target: string; +} + +export type CertificationCodeStatusEnum = + | 'PENDING' + | 'EXPIRED' + | 'VERIFIED' + | 'SUCCESS'; + +export interface CreateCertificationCodeProps + extends CertificationTargetProps {} diff --git a/src/_ddd/certification/domain/value-object/certification-code-status.value-object.ts b/src/_ddd/certification/domain/value-object/certification-code-status.value-object.ts new file mode 100644 index 0000000..84f28a2 --- /dev/null +++ b/src/_ddd/certification/domain/value-object/certification-code-status.value-object.ts @@ -0,0 +1,22 @@ +import { + DomainPrimitive, + ValueObject, +} from '@/_ddd_shared/ddd/value-object/value-object.base'; +import typia from 'typia'; +import { CertificationCodeStatusEnum } from '../type/certification.code.type'; + +export class CertificationCodeStatus extends ValueObject { + constructor(value: CertificationCodeStatusEnum) { + super({ value }); + } + static PENDING = new CertificationCodeStatus('PENDING'); + static EXPIRED = new CertificationCodeStatus('EXPIRED'); + static VERIFIED = new CertificationCodeStatus('VERIFIED'); + static SUCCESS = new CertificationCodeStatus('SUCCESS'); + + validate({ value }: DomainPrimitive): void { + if (!typia.is(value)) { + throw new Error('Invalid certification code status'); + } + } +} diff --git a/src/_ddd/certification/domain/value-object/certification-target.value-object.ts b/src/_ddd/certification/domain/value-object/certification-target.value-object.ts new file mode 100644 index 0000000..6cef5aa --- /dev/null +++ b/src/_ddd/certification/domain/value-object/certification-target.value-object.ts @@ -0,0 +1,16 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { ArgumentInvalidException } from '@/_ddd_shared/exceptions'; +import typia from 'typia'; +import { CertificationTargetProps } from '../type/certification.code.type'; + +export class CertificationTarget extends ValueObject { + constructor(props: CertificationTargetProps) { + super(props); + } + + protected validate(props: CertificationTargetProps): void { + if (!typia.is(props)) { + throw new ArgumentInvalidException('Invalid certification target props'); + } + } +} diff --git a/src/_ddd/certification/infrastructure/repository/certification-code.repository.ts b/src/_ddd/certification/infrastructure/repository/certification-code.repository.ts new file mode 100644 index 0000000..bfc61d5 --- /dev/null +++ b/src/_ddd/certification/infrastructure/repository/certification-code.repository.ts @@ -0,0 +1,119 @@ +import { CertificationMapper } from '@/_ddd/certification/domain/cerfication.mapper'; +import { CertificationCodeEntity } from '@/_ddd/certification/domain/entity/certification-code.root-entity'; +import { SaveCertificationPort } from '@/_ddd/certification/domain/port/out/save-certification.port'; +import { + CertificationTargetType, + CertificationType, +} from '@/_ddd/certification/domain/type/certification.code.type'; +import { CertificationCodeStatus } from '@/_ddd/certification/domain/value-object/certification-code-status.value-object'; +import { CertificationTarget } from '@/_ddd/certification/domain/value-object/certification-target.value-object'; +import { PrismaRepositoryBase } from '@/_ddd_shared/db/prisma.repository.base'; +import { PrismaService } from '@common/prisma/prisma.service'; +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; +import { CERTIFICATION_STATUS } from '@prisma/client'; + +@Injectable() +export class CertificationRepository + extends PrismaRepositoryBase + implements SaveCertificationPort +{ + private readonly include = { + certification: true, + }; + private readonly range = { + gt: new Date(Date.now() - 1000 * 60 * 60 * 24).toISOString(), + lt: new Date(Date.now()).toISOString(), + }; + + constructor( + protected readonly prisma: PrismaService, + private readonly mapper: CertificationMapper, + ) { + super(prisma); + } + + async save( + certificationCode: CertificationCodeEntity, + tx?: PrismaTxType, + ): Promise { + const { create, update } = this.mapper.toPersistence(certificationCode); + const result = await this.excute(async (prisma) => { + return await prisma.certificationCode.upsert({ + where: { + id: certificationCode.id, + }, + update, + create, + include: this.include, + }); + }, tx); + return this.mapper.toDomain(result); + } + /** + * 인증코드 조회는 하루 기준으로 한다. + */ + async findManyByTarget( + targetVO: CertificationTarget, + tx?: PrismaTxType, + ): Promise { + const { target, targetType } = targetVO.unpack(); + const result = await this.excute(async (prisma) => { + return await prisma.certificationCode.findMany({ + where: { + target, + targetType, + status: { + notIn: [CertificationCodeStatus.VERIFIED.unpack()], + }, + createdAt: this.range, + }, + include: this.include, + }); + }, tx); + return result.map((item) => this.mapper.toDomain(item)); + } + + async findOneByTargetAndCode( + input: { + target: string; + targetType: CertificationTargetType; + type: CertificationType; + code: string; + status?: CERTIFICATION_STATUS; + }, + tx?: PrismaTxType, + ): Promise { + const { status = 'PENDING' } = input; + const result = await this.excute(async (prisma) => { + return await prisma.certificationCode.findFirst({ + where: { + targetType: input.targetType, + type: input.type, + target: input.target, + code: input.code, + expiresAt: { gt: new Date(Date.now()).toISOString() }, + status, + }, + include: this.include, + }); + }, tx); + return result ? this.mapper.toDomain(result) : null; + } + + async findById( + id: string, + tx?: PrismaTxType, + ): Promise { + const result = await this.excute(async (prisma) => { + return await prisma.certificationCode.findUnique({ + where: { + id, + expiresAt: { gt: new Date(Date.now()).toISOString() }, + }, + include: this.include, + }); + }, tx); + return result ? this.mapper.toDomain(result) : null; + } +} diff --git a/src/_ddd/driving/application/command/start-driving/http/start-driving.controller.ts b/src/_ddd/driving/application/command/start-driving/http/start-driving.controller.ts new file mode 100644 index 0000000..324f668 --- /dev/null +++ b/src/_ddd/driving/application/command/start-driving/http/start-driving.controller.ts @@ -0,0 +1,30 @@ +import { TokenPayload } from '@/_ddd/auth/domain/port/out/token.port'; +import { CurrentUser } from '@/_ddd_shared/decorator/CurrentUser'; +import { AuthGuard } from '@/_ddd_shared/guard/auth.guard'; +import { TypedBody, TypedParam, TypedRoute } from '@nestia/core'; +import { Controller, UseGuards } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { StartDrivingCommand } from '../start-driving.command'; +import { StartDrivingHttpReq } from './start-driving.req-type'; + +@Controller('car/:carId/driving') +export class StartDrivingController { + constructor(private readonly commandBus: CommandBus) {} + + @TypedRoute.Post('') + @UseGuards(AuthGuard) + async startDriving( + @TypedParam('carId') carId: string, + @TypedBody() body: StartDrivingHttpReq, + @CurrentUser() user: TokenPayload, + ): Promise { + const { sub: userId } = user; + await this.commandBus.execute( + new StartDrivingCommand({ + carId, + userId, + rentalId: body.rentalId, + }), + ); + } +} diff --git a/src/_ddd/driving/application/command/start-driving/http/start-driving.req-type.ts b/src/_ddd/driving/application/command/start-driving/http/start-driving.req-type.ts new file mode 100644 index 0000000..9d578c0 --- /dev/null +++ b/src/_ddd/driving/application/command/start-driving/http/start-driving.req-type.ts @@ -0,0 +1,3 @@ +export interface StartDrivingHttpReq { + rentalId?: string; +} diff --git a/src/_ddd/driving/application/command/start-driving/start-driving.command-handler.ts b/src/_ddd/driving/application/command/start-driving/start-driving.command-handler.ts new file mode 100644 index 0000000..90f7f0d --- /dev/null +++ b/src/_ddd/driving/application/command/start-driving/start-driving.command-handler.ts @@ -0,0 +1,42 @@ +import { CarNotFound } from '@/_ddd/car/domain/error'; +import { DrivingEntity } from '@/_ddd/driving/domain/entity/driving.root-entity'; +import { CarAdaptor } from '@/_ddd/driving/infrastructure/adaptor/car.adaptor'; +import { DrivingRepository } from '@/_ddd/driving/infrastructure/repo/driving.repository'; +import { PrismaService } from '@common/prisma/prisma.service'; +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { StartDrivingCommand } from './start-driving.command'; + +@CommandHandler(StartDrivingCommand) +export class StartDrivingCommandHandler implements ICommandHandler { + constructor( + private readonly carAdaptor: CarAdaptor, + private readonly prisma: PrismaService, + private readonly drivingRepository: DrivingRepository, + ) {} + + async execute(command: StartDrivingCommand): Promise { + const { carId, userId, rentalId } = command.props; + const car = await this.carAdaptor.getCar(carId, userId); + if (!car) { + throw CarNotFound('차량을 찾을 수 없습니다.'); + } + const existDriving = await this.prisma.driving.findMany({ + where: { + carId, + status: { + in: ['DRIVING'], + }, + }, + }); + + if (existDriving.length) { + throw new Error('이미 운행중인 차량입니다.'); + } + const driving = DrivingEntity.create({ + carId, + rentalId, + userId, + }); + await this.drivingRepository.save(driving); + } +} diff --git a/src/_ddd/driving/application/command/start-driving/start-driving.command.ts b/src/_ddd/driving/application/command/start-driving/start-driving.command.ts new file mode 100644 index 0000000..4981a33 --- /dev/null +++ b/src/_ddd/driving/application/command/start-driving/start-driving.command.ts @@ -0,0 +1,16 @@ +import { Command } from '@/_ddd_shared/app/command/command.base'; + +export interface StartDrivingCommandProps { + carId: string; + userId: string; + rentalId?: string; +} + +export class StartDrivingCommand extends Command { + readonly props: StartDrivingCommandProps; + + constructor(props: StartDrivingCommandProps) { + super(props); + this.props = props; + } +} diff --git a/src/_ddd/driving/domain/driving.mapper.ts b/src/_ddd/driving/domain/driving.mapper.ts new file mode 100644 index 0000000..9cabbe9 --- /dev/null +++ b/src/_ddd/driving/domain/driving.mapper.ts @@ -0,0 +1,191 @@ +import { Injectable } from '@nestjs/common'; +import { + Driving, + DrivingSnapshot, + Parking, + ParkingSnapshot, + Prisma, +} from '@prisma/client'; +import { Mapper } from './../../../_ddd_shared/ddd/mapper.interface'; +import { DrivingEntity } from './entity/driving.root-entity'; +import { ParkingEntity } from './entity/parking.entity'; +import { DrivingSnapshot as DrivingSnapshotVO } from './value-object/driving-snapshot.value-object'; +import { ParkingSnapshot as ParkingSnapshotVO } from './value-object/parking-snapshot.value-object'; + +export type FindDrivingRecord = Driving & { + snapshots: DrivingSnapshot[]; + parkings: (Parking & { + snapshots: ParkingSnapshot[]; + })[]; +}; + +@Injectable() +export class DrivingMapper implements Mapper { + toPersistence(aggregate: DrivingEntity): { + create: Prisma.DrivingCreateInput; + update: Prisma.DrivingUpdateInput; + } { + const { snapshots, parkings, userId, carId, ...driving } = + aggregate.getProps(); + const DrivingSnapshot = snapshots.map((snapshot) => { + return { + ...snapshot.unpack(), + }; + }); + const parking = parkings.map((parking) => { + const props = parking.getProps(); + const snapshots = props.snapshots.map((snapshot) => { + return { + ...snapshot.unpack(), + }; + }); + return { + ...props, + snapshots, + }; + }); + const create: Prisma.DrivingCreateInput = { + ...driving, + user: { + connect: { + id: userId, + }, + }, + car: { + connect: { + id: carId, + }, + }, + snapshots: { + createMany: { + data: DrivingSnapshot.map((snapshot) => { + return { + ...snapshot, + }; + }), + }, + }, + parkings: { + connectOrCreate: parking.map(({ snapshots, ...parking }) => { + return { + where: { + id: parking.id, + }, + create: { + ...parking, + carId, + snapshots: { + createMany: { + data: snapshots.map((snapshot) => { + return { + ...snapshot, + }; + }), + }, + }, + }, + }; + }), + }, + }; + + const update: Prisma.DrivingUpdateInput = { + ...driving, + snapshots: { + upsert: DrivingSnapshot.map(({ id, ...snapshot }) => { + return { + where: { + id, + }, + update: { + ...snapshot, + }, + create: { + id, + ...snapshot, + }, + }; + }), + }, + parkings: { + upsert: parking.map(({ id, snapshots, ...parking }) => { + return { + where: { + id, + }, + update: { + ...parking, + snapshots: { + upsert: snapshots.map(({ id, ...snapshot }) => { + return { + where: { + id, + }, + update: { + ...snapshot, + }, + create: { + id, + ...snapshot, + }, + }; + }), + }, + }, + create: { + id, + ...parking, + carId, + snapshots: { + createMany: { + data: snapshots.map((snapshot) => { + return { + ...snapshot, + }; + }), + }, + }, + }, + }; + }), + }, + }; + + return { + create, + update, + }; + } + toDomain(record: FindDrivingRecord): DrivingEntity { + const { snapshots, parkings, rentalId, ...driving } = record; + const drivingSnapshots = snapshots.map((snapshot) => { + return new DrivingSnapshotVO(snapshot); + }); + const parking = parkings.map((p) => { + const { snapshots, ...parking } = p; + const parkingSnapshots = snapshots.map((snapshot) => { + return new ParkingSnapshotVO(snapshot); + }); + return new ParkingEntity({ + id: parking.id, + props: { ...parking, snapshots: parkingSnapshots }, + }); + }); + + const aggregate = new DrivingEntity({ + id: driving.id, + props: { + ...driving, + rentalId: rentalId ?? undefined, + snapshots: drivingSnapshots, + parkings: parking, + }, + }); + return aggregate; + } + + toResponse(aggregate: DrivingEntity) { + aggregate; + throw new Error('Method not implemented.'); + } +} diff --git a/src/_ddd/driving/domain/entity/driving.root-entity.ts b/src/_ddd/driving/domain/entity/driving.root-entity.ts new file mode 100644 index 0000000..40faa7f --- /dev/null +++ b/src/_ddd/driving/domain/entity/driving.root-entity.ts @@ -0,0 +1,77 @@ +import { AggregateRoot } from '@/_ddd_shared/ddd/aggregate-root.base'; +import { v4 } from 'uuid'; +import { + DrivingSnapshot, + DrivingSnapshotProps, +} from '../value-object/driving-snapshot.value-object'; +import { CreateParkingEntityProps, ParkingEntity } from './parking.entity'; + +interface DrivingEntityProps { + id: string; + carId: string; + userId: string; + rentalId?: string; + snapshots: DrivingSnapshot[]; + parkings: ParkingEntity[]; + status: DrivingStatus; +} + +interface CreateDrivingEntityProps { + carId: string; + userId: string; + rentalId?: string; +} + +export type DrivingStatus = 'DRIVING' | 'END'; + +export class DrivingEntity extends AggregateRoot { + static create(createProps: CreateDrivingEntityProps): DrivingEntity { + const id = v4(); + const carId = createProps.carId; + const userId = createProps.userId; + const rentalId = createProps.rentalId; + const snapshots: DrivingSnapshot[] = []; + const parkings: ParkingEntity[] = []; + const props: DrivingEntityProps = { + id, + carId, + userId, + rentalId, + snapshots, + parkings, + status: 'DRIVING', + }; + return new DrivingEntity({ id, props }); + } + + //---------------- + // parkings + //---------------- + parking(parkingProps: Omit) { + const parking = ParkingEntity.create({ ...parkingProps, status: 'PARKED' }); + this.props.parkings.push(parking); + } + + parkingEnd(parkingId: string) { + const parking = this.props.parkings.find( + (parking) => parking.id === parkingId, + ); + if (!parking) { + throw new Error('Parking not found'); + } + parking.end(); + } + + //---------------- + // snapshots + //---------------- + addSnapshot(snapshotProps: DrivingSnapshotProps): void { + const snapshot = new DrivingSnapshot({ + ...snapshotProps, + id: v4(), + }); + this.props.snapshots.push(snapshot); + } + + validate(): void {} +} diff --git a/src/_ddd/driving/domain/entity/parking.entity.ts b/src/_ddd/driving/domain/entity/parking.entity.ts new file mode 100644 index 0000000..89b665f --- /dev/null +++ b/src/_ddd/driving/domain/entity/parking.entity.ts @@ -0,0 +1,75 @@ +import { Entity } from '@/_ddd_shared/ddd/entity.base'; +import { v4 } from 'uuid'; +import { ParkingSnapshot } from '../value-object/parking-snapshot.value-object'; + +export interface ParkingEntityProps { + id: string; + location: string; + latitude: number; + longitude: number; + status: ParkingStatus; + startDate: Date; + endDate: Date; + snapshots: ParkingSnapshot[]; +} +export interface CreateParkingEntityProps { + location: string; + latitude: number; + longitude: number; + status: ParkingStatus; + startDate: Date; + endDate: Date; +} + +export type ParkingStatus = 'PARKED' | 'COMPLETED'; + +export class ParkingEntity extends Entity { + public static create(createProps: CreateParkingEntityProps): ParkingEntity { + const id = v4(); + const location = createProps.location; + const latitude = createProps.latitude; + const longitude = createProps.longitude; + const status = createProps.status; + const startDate = createProps.startDate; + const endDate = createProps.endDate; + const props = { + id, + location, + latitude, + longitude, + status, + startDate, + endDate, + snapshots: [], + }; + return new ParkingEntity({ id, props }).addSnapshot(); + } + + end() { + this.props.status = 'COMPLETED'; + return this.addSnapshot(); + } + + // -------------------- + // snapshot + // -------------------- + addSnapshot() { + const props = this.props; + const snapshot = new ParkingSnapshot({ + id: v4(), + location: props.location, + latitude: props.latitude, + longitude: props.longitude, + status: props.status, + startDate: props.startDate, + endDate: props.endDate, + }); + this.props.snapshots.push(snapshot); + return this; + } + + // -------------------- + // validate + // -------------------- + public validate(): void {} +} diff --git a/src/_ddd/driving/domain/value-object/driving-snapshot.value-object.ts b/src/_ddd/driving/domain/value-object/driving-snapshot.value-object.ts new file mode 100644 index 0000000..c99ffed --- /dev/null +++ b/src/_ddd/driving/domain/value-object/driving-snapshot.value-object.ts @@ -0,0 +1,18 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { DrivingStatus } from '../entity/driving.root-entity'; + +export interface DrivingSnapshotProps { + id: string; + location: string; + latitude: number; + longitude: number; + status: DrivingStatus; +} + +export class DrivingSnapshot extends ValueObject { + constructor(props: DrivingSnapshotProps) { + super(props); + } + + validate(): void {} +} diff --git a/src/_ddd/driving/domain/value-object/parking-snapshot.value-object.ts b/src/_ddd/driving/domain/value-object/parking-snapshot.value-object.ts new file mode 100644 index 0000000..375e852 --- /dev/null +++ b/src/_ddd/driving/domain/value-object/parking-snapshot.value-object.ts @@ -0,0 +1,20 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { ParkingStatus } from '../entity/parking.entity'; + +export interface ParkingSnapshotProps { + id: string; + location: string; + latitude: number; + longitude: number; + status: ParkingStatus; + startDate: Date; + endDate: Date; +} + +export class ParkingSnapshot extends ValueObject { + constructor(props: ParkingSnapshotProps) { + super(props); + } + + validate(): void {} +} diff --git a/src/_ddd/driving/driving.module.ts b/src/_ddd/driving/driving.module.ts new file mode 100644 index 0000000..a708bba --- /dev/null +++ b/src/_ddd/driving/driving.module.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; +import { StartDrivingController } from './application/command/start-driving/http/start-driving.controller'; +import { StartDrivingCommandHandler } from './application/command/start-driving/start-driving.command-handler'; +import { DrivingMapper } from './domain/driving.mapper'; +import { CarAdaptor } from './infrastructure/adaptor/car.adaptor'; +import { DrivingRepository } from './infrastructure/repo/driving.repository'; + +const controllers = [StartDrivingController]; +const commandHandlers = [StartDrivingCommandHandler]; + +const mapper = [DrivingMapper]; +const repositories = [DrivingRepository]; + +const adaptors = [CarAdaptor]; +@Module({ + imports: [CqrsModule], + controllers, + providers: [...commandHandlers, ...mapper, ...repositories, ...adaptors], +}) +export class DDD_DrivingModule {} diff --git a/src/_ddd/driving/infrastructure/adaptor/car.adaptor.ts b/src/_ddd/driving/infrastructure/adaptor/car.adaptor.ts new file mode 100644 index 0000000..99e6979 --- /dev/null +++ b/src/_ddd/driving/infrastructure/adaptor/car.adaptor.ts @@ -0,0 +1,32 @@ +import { PrismaService } from '@common/prisma/prisma.service'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class CarAdaptor { + constructor(private readonly prisma: PrismaService) {} + + async getCar(carId: string, userId: string) { + const car = await this.prisma.car.findUnique({ + where: { + id: carId, + OR: [ + { + ownerId: userId, + }, + { + rentals: { + some: { + userId: userId, + status: { + in: ['APPROVED'], + }, + }, + }, + }, + ], + }, + }); + + return car; + } +} diff --git a/src/_ddd/driving/infrastructure/repo/driving.repository.ts b/src/_ddd/driving/infrastructure/repo/driving.repository.ts new file mode 100644 index 0000000..24a2287 --- /dev/null +++ b/src/_ddd/driving/infrastructure/repo/driving.repository.ts @@ -0,0 +1,51 @@ +import { PrismaRepositoryBase } from '@/_ddd_shared/db/prisma.repository.base'; +import { PrismaService } from '@common/prisma/prisma.service'; +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; +import { Prisma } from '@prisma/client'; +import { DrivingMapper } from '../../domain/driving.mapper'; +import { DrivingEntity } from '../../domain/entity/driving.root-entity'; + +@Injectable() +export class DrivingRepository extends PrismaRepositoryBase { + constructor( + protected readonly prisma: PrismaService, + private readonly drivingMapper: DrivingMapper, + ) { + super(prisma); + } + + private includes = { + snapshots: true, + parkings: { + include: { + snapshots: true, + }, + }, + } satisfies Prisma.DrivingInclude; + + async save( + aggregate: DrivingEntity, + tx?: PrismaTxType, + ): Promise { + const { create, update } = this.drivingMapper.toPersistence(aggregate); + await this.excute((prisma) => { + return prisma.driving.upsert({ + where: { + id: aggregate.id, + }, + update, + create, + }); + }, tx); + return aggregate; + } + + async findById(id: string): Promise { + const record = await this.prisma.driving.findUnique({ + where: { id }, + include: this.includes, + }); + return record ? this.drivingMapper.toDomain(record) : null; + } +} diff --git a/src/_ddd/notification/application/event-handler/request-certification-code.event-handler.ts b/src/_ddd/notification/application/event-handler/request-certification-code.event-handler.ts new file mode 100644 index 0000000..895c5a3 --- /dev/null +++ b/src/_ddd/notification/application/event-handler/request-certification-code.event-handler.ts @@ -0,0 +1,29 @@ +import { RequestCertificationCodeEvent } from '@/_ddd/certification/domain/event/request-code.event'; +import { CertificationType } from '@/_ddd/certification/domain/type/certification.code.type'; +import { Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; +import { TwilioAdaptor } from './../../infrastructure/adaptor/twilio.adapor'; + +@Injectable() +export class RequestCertificationCodeEventHandler { + constructor(private readonly twilioAdaptor: TwilioAdaptor) {} + + @OnEvent(RequestCertificationCodeEvent.name, { async: true, promisify: true }) + async handle(event: RequestCertificationCodeEvent) { + const { target, targetType, type, code } = event; + if (targetType === 'PHONE') { + await this.twilioAdaptor.send(target, this.codeTemplate(code, type)); + } + } + + private codeTemplate(code: string, type: CertificationType) { + switch (type) { + case 'SIGN_UP': + return `[uncar] 회원가입 인증 코드: ${code}`; + case 'FIND_PASSWORD': + return `[uncar] 비밀번호 찾기 인증 코드: ${code}`; + default: + throw new Error('Invalid certification type'); + } + } +} diff --git a/src/_ddd/notification/domain/port/out/twilio.adaptor.out-port.ts b/src/_ddd/notification/domain/port/out/twilio.adaptor.out-port.ts new file mode 100644 index 0000000..39f4dcb --- /dev/null +++ b/src/_ddd/notification/domain/port/out/twilio.adaptor.out-port.ts @@ -0,0 +1,3 @@ +export interface TwilioAdaptorOutPort { + send(target: string, message: string): Promise; +} diff --git a/src/_ddd/notification/infrastructure/adaptor/twilio.adapor.ts b/src/_ddd/notification/infrastructure/adaptor/twilio.adapor.ts new file mode 100644 index 0000000..b80d7da --- /dev/null +++ b/src/_ddd/notification/infrastructure/adaptor/twilio.adapor.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { TwilioService } from 'nestjs-twilio'; +import { TwilioAdaptorOutPort } from '../../domain/port/out/twilio.adaptor.out-port'; + +@Injectable() +export class TwilioAdaptor implements TwilioAdaptorOutPort { + constructor(private readonly twilioService: TwilioService) {} + + async send(target: string, message: string) { + // Send SMS + this.twilioService.client.messages.create({ + body: message, + from: process.env.TWILIO_PHONE_NUMBER, + to: target, + }); + } +} diff --git a/src/_ddd/notification/notification.module.ts b/src/_ddd/notification/notification.module.ts new file mode 100644 index 0000000..6e4d638 --- /dev/null +++ b/src/_ddd/notification/notification.module.ts @@ -0,0 +1,11 @@ +import { Module, Provider } from '@nestjs/common'; +import { RequestCertificationCodeEventHandler } from './application/event-handler/request-certification-code.event-handler'; +import { TwilioAdaptor } from './infrastructure/adaptor/twilio.adapor'; + +export const eventHandlers: Provider[] = [RequestCertificationCodeEventHandler]; +export const adapters: Provider[] = [TwilioAdaptor]; + +@Module({ + providers: [...eventHandlers, ...adapters], +}) +export class DDD_NotificationModule {} diff --git a/src/_ddd/terms-agreement/application/command/_command/.command-handler.ts b/src/_ddd/terms-agreement/application/command/_command/.command-handler.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/terms-agreement/application/command/_command/.command.ts b/src/_ddd/terms-agreement/application/command/_command/.command.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/terms-agreement/application/query/.query-handler.ts b/src/_ddd/terms-agreement/application/query/.query-handler.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/terms-agreement/domain/entity/.entity.ts b/src/_ddd/terms-agreement/domain/entity/.entity.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/terms-agreement/domain/port/in/_.use-case.ts b/src/_ddd/terms-agreement/domain/port/in/_.use-case.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/terms-agreement/domain/port/out/_.port.ts b/src/_ddd/terms-agreement/domain/port/out/_.port.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/terms-agreement/infrastructure/repository/_.repository.ts b/src/_ddd/terms-agreement/infrastructure/repository/_.repository.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/user/application/command/signup/http/signup.http.controller.ts b/src/_ddd/user/application/command/signup/http/signup.http.controller.ts new file mode 100644 index 0000000..90e787d --- /dev/null +++ b/src/_ddd/user/application/command/signup/http/signup.http.controller.ts @@ -0,0 +1,31 @@ +import { + UserCertificationCodeInvalidType, + UserNicknameExistType, +} from '@/_ddd/user/domain/error'; +import { handleException } from '@/_ddd_shared/exceptions'; +import { Result, match } from '@/_ddd_shared/types'; +import { res } from '@/_ddd_shared/ui/response-base'; +import { TypedBody, TypedRoute } from '@nestia/core'; +import { Controller } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { SignupCommand } from '../signup.command'; +import { SignupHttpReq } from './signup.req-type'; + +@Controller('signup') +export class SignupHttpController { + constructor(private readonly commandBus: CommandBus) {} + + @TypedRoute.Post() + async signup(@TypedBody() dto: SignupHttpReq) { + const input = dto.type === 'LOCAL' ? { local: dto } : { oauth: dto }; + const command = new SignupCommand(input); + const result: Result< + 'success', + UserNicknameExistType | UserCertificationCodeInvalidType + > = await this.commandBus.execute(command); + return match(result, { + Ok: (s) => res(s), + Err: handleException, + }); + } +} diff --git a/src/_ddd/user/application/command/signup/http/signup.req-type.ts b/src/_ddd/user/application/command/signup/http/signup.req-type.ts new file mode 100644 index 0000000..7cb0328 --- /dev/null +++ b/src/_ddd/user/application/command/signup/http/signup.req-type.ts @@ -0,0 +1,6 @@ +import { + LocalSignupCommandProps, + OauthSignupCommandProps, +} from '../signup.command'; + +export type SignupHttpReq = LocalSignupCommandProps | OauthSignupCommandProps; diff --git a/src/_ddd/user/application/command/signup/signup.command-handler.ts b/src/_ddd/user/application/command/signup/signup.command-handler.ts new file mode 100644 index 0000000..56f37d7 --- /dev/null +++ b/src/_ddd/user/application/command/signup/signup.command-handler.ts @@ -0,0 +1,88 @@ +import { UserEntity } from '@/_ddd/user/domain/entity/user.root-entity'; +import { + UserCertificationCodeInvalidType, + UserNicknameExistType, +} from '@/_ddd/user/domain/error'; +import { UserValidator } from '@/_ddd/user/domain/service/user.validator'; +import { AuthAdaptor } from '@/_ddd/user/infrastructure/adaptor/auth.adaptor'; +import { CertificationAdaptor } from '@/_ddd/user/infrastructure/adaptor/cerification.adaptor'; +import { UserRepository } from '@/_ddd/user/infrastructure/repository/user.repository'; +import { DomainException, handleException } from '@/_ddd_shared/exceptions'; +import { Result } from '@/_ddd_shared/types'; +import { Err, Ok } from '@/_ddd_shared/util/Result'; +import { PrismaService } from '@common/prisma/prisma.service'; +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { + LocalSignupCommandProps, + OauthSignupCommandProps, + SignupCommand, +} from './signup.command'; + +@CommandHandler(SignupCommand) +export class SignupCommandHandler implements ICommandHandler { + constructor( + private readonly prisma: PrismaService, + private readonly userRepo: UserRepository, + private readonly authAdaptor: AuthAdaptor, + private readonly userService: UserValidator, + private readonly certificationAdaptor: CertificationAdaptor, + ) {} + + async execute( + command: SignupCommand, + ): Promise< + Result<'success', UserNicknameExistType | UserCertificationCodeInvalidType> + > { + try { + const { local, oauth } = command; + if (local) { + return Ok(await this.signupLocal(local)); + } + if (oauth) { + return Ok(await this.signupOauth(oauth)); + } + throw new Error('SignupCommand'); + } catch (e) { + if (e instanceof DomainException) { + return Err(e); + } + throw handleException(e as Error); + } + } + + async signupLocal(local: LocalSignupCommandProps): Promise<'success'> { + if (!local) { + throw new Error('SignupCommand'); + } + await this.userService.canSignup(local); + + const hashedPassword = await this.authAdaptor.hash(local.password); + const user = UserEntity.create({ + nickname: local.nickname, + account: { + account: local.account, + password: hashedPassword, + }, + phone: { + countryCode: local.countryCode, + phone: local.phone, + }, + }); + await this.prisma.$transaction(async (tx) => { + await this.userRepo.save(user, tx); + await this.certificationAdaptor.changeStatusSuccessAndRecord( + local.certificationId, + user.id, + tx, + ); + }); + return 'success'; + } + + async signupOauth(oauth: OauthSignupCommandProps): Promise<'success'> { + if (!oauth) { + throw new Error('SignupCommand'); + } + throw new Error('NOT IMPLEMENTED'); + } +} diff --git a/src/_ddd/user/application/command/signup/signup.command.ts b/src/_ddd/user/application/command/signup/signup.command.ts new file mode 100644 index 0000000..1c6ab9a --- /dev/null +++ b/src/_ddd/user/application/command/signup/signup.command.ts @@ -0,0 +1,31 @@ +import { OauthProvider } from '@/_ddd/auth/domain/value-object/oauth.value-object'; +import { Command, CommandProps } from '@/_ddd_shared/app/command/command.base'; + +export interface LocalSignupCommandProps { + readonly account: string; + readonly password: string; + readonly type: 'LOCAL'; + + readonly nickname: string; + readonly phone: string; + readonly countryCode: string; + + // Certification + readonly certificationId: string; +} + +export interface OauthSignupCommandProps { + readonly type: OauthProvider; + readonly accessToken: string; +} + +export class SignupCommand extends Command { + readonly local?: LocalSignupCommandProps; + readonly oauth?: OauthSignupCommandProps; + + constructor(props: CommandProps) { + super(props); + this.local = props.local; + this.oauth = props.oauth; + } +} diff --git a/src/_ddd/user/application/query/find-user-by-account.query.ts b/src/_ddd/user/application/query/find-user-by-account.query.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/user/application/query/find-user-by-phone.query.ts b/src/_ddd/user/application/query/find-user-by-phone.query.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/user/domain/entity/user.root-entity.ts b/src/_ddd/user/domain/entity/user.root-entity.ts new file mode 100644 index 0000000..8b2c8eb --- /dev/null +++ b/src/_ddd/user/domain/entity/user.root-entity.ts @@ -0,0 +1,85 @@ +import { AggregateRoot } from '@/_ddd_shared/ddd/aggregate-root.base'; +import { v4 } from 'uuid'; +import { AuthAdaptor } from '../../infrastructure/adaptor/auth.adaptor'; +import { UserValidator } from '../service/user.validator'; +import { PhoneProps } from '../type/phone.props'; +import { CreateUserProps, UserProps } from '../type/user.props'; +import { Account } from '../value-object/account.value-object'; +import { Phone } from '../value-object/phone.value-object'; +import { Snapshot } from '../value-object/snapshot.value-object'; + +export class UserEntity extends AggregateRoot { + protected readonly _id!: string; + private changed: boolean = false; + + static create(createProps: CreateUserProps): UserEntity { + const id = v4(); + const account = new Account(createProps.account); + const phone = new Phone(createProps.phone); + const nickname = createProps.nickname; + const props: UserProps = { + id, + account, + phone, + nickname, + snapshots: [], + }; + return new UserEntity({ id, props }).addSnapshot(); + } + + isChanged(): boolean { + return this.changed; + } + + async changePhone( + validator: UserValidator, + newPhoneProps: PhoneProps, + certificationId: string, + ): Promise { + await validator.canChangePhone(newPhoneProps, certificationId); + const phone = new Phone(newPhoneProps); + this.props.phone = phone; + this.changed = true; + return this; + } + + async changeNickname( + validator: UserValidator, + nickname: string, + ): Promise { + await validator.canChangeUserNickname(nickname); + this.props.nickname = nickname; + this.changed = true; + return this; + } + + async changePassword( + validator: UserValidator, + authAdaptor: AuthAdaptor, + nowPassword: string, + newPassword: string, + ): Promise { + await validator.checkPassword(this, nowPassword); + const hashedPassword = await authAdaptor.hash(newPassword); + this.props.account = new Account({ + ...this.props.account.unpack(), + password: hashedPassword, + }); + this.changed = true; + return this; + } + + addSnapshot() { + const { snapshots: _, account, phone, nickname } = this.getProps(); + console.log(phone.unpack); + const snapshot = Snapshot.create({ + account: account.unpack(), + phone: phone.unpack(), + nickname, + id: v4(), + }); + this.props.snapshots.push(snapshot); + return this; + } + public validate(): void {} +} diff --git a/src/_ddd/user/domain/error/index.ts b/src/_ddd/user/domain/error/index.ts new file mode 100644 index 0000000..90ddb15 --- /dev/null +++ b/src/_ddd/user/domain/error/index.ts @@ -0,0 +1,57 @@ +import { DomainException } from '@/_ddd_shared/exceptions'; +import { ExceptionType } from '@/_ddd_shared/types/exception.type'; +import { DomainExceptionRes } from '@/_ddd_shared/types/response.type'; +import * as codes from './user-error.codes'; + +export class UserException< + C extends string, + S extends number, +> extends DomainException {} + +// 유저가 존재하지 않습니다. +export const UserNotFound = UserException.create(codes.USER_NOT_FOUND, 404); +export type UserNotFoundType = ExceptionType; +export type UserNotFoundRes = DomainExceptionRes; + +// 유저 폰 번호 중복 +export const UserPhoneExist = UserException.create(codes.USER_PHONE_EXIST, 400); +export type UserPhoneExistType = ExceptionType; +export type UserPhoneExistRes = DomainExceptionRes; + +// 계정 중복 +export const UserAccountExist = UserException.create( + codes.USER_ACCOUNT_EXIST, + 400, +); +export type UserAccountExistType = ExceptionType; +export type UserAccountExistRes = DomainExceptionRes; + +// 닉네임 중복 +export const UserNicknameExist = UserException.create( + codes.USER_NICKNAME_EXIST, + 400, +); +export type UserNicknameExistType = ExceptionType; +export type UserNicknameExistRes = DomainExceptionRes; + +// 비밀번호 불일치 +export const UserPasswordInvailid = UserException.create( + codes.USER_PASSWORD_INVALID, + 400, +); +export type UserPasswordInvailidType = ExceptionType< + typeof UserPasswordInvailid +>; +export type UserPasswordInvailidRes = + DomainExceptionRes; + +// 인증번호 invailid +export const UserCertificationCodeInvalid = UserException.create( + codes.USER_CERTIFICATION_CODE_INVALID, + 400, +); +export type UserCertificationCodeInvalidType = ExceptionType< + typeof UserCertificationCodeInvalid +>; +export type UserCertificationCodeInvalidRes = + DomainExceptionRes; diff --git a/src/_ddd/user/domain/error/user-error.codes.ts b/src/_ddd/user/domain/error/user-error.codes.ts new file mode 100644 index 0000000..03a0d15 --- /dev/null +++ b/src/_ddd/user/domain/error/user-error.codes.ts @@ -0,0 +1,8 @@ +export const USER_NOT_FOUND = 'USER.NOT_FOUND'; +export const USER_PHONE_EXIST = 'USER.PHONE_EXIST'; +export const USER_ACCOUNT_EXIST = 'USER.ACCOUNT_EXIST'; +export const USER_NICKNAME_EXIST = 'USER.NICKNAME_EXIST'; + +export const USER_PASSWORD_INVALID = 'USER.PASSWORD_INVALID'; +export const USER_CERTIFICATION_CODE_INVALID = + 'USER.CERTIFICATION_CODE_INVALID'; diff --git a/src/_ddd/user/domain/port/in/find-user-by-id.use-case.ts b/src/_ddd/user/domain/port/in/find-user-by-id.use-case.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/user/domain/port/out/auth-adaptor.out-port.ts b/src/_ddd/user/domain/port/out/auth-adaptor.out-port.ts new file mode 100644 index 0000000..9825fa0 --- /dev/null +++ b/src/_ddd/user/domain/port/out/auth-adaptor.out-port.ts @@ -0,0 +1,7 @@ +export interface AuthAdaptorPort { + // 회원가입시 비밀번호 암호화 + hash(password: string): Promise; + + // 비밀번호 변경과 같은 기능에 사용 + compare(hash: string, password: string): Promise; +} diff --git a/src/_ddd/user/domain/port/out/certification-adaptor.out-port.ts b/src/_ddd/user/domain/port/out/certification-adaptor.out-port.ts new file mode 100644 index 0000000..7fc09ea --- /dev/null +++ b/src/_ddd/user/domain/port/out/certification-adaptor.out-port.ts @@ -0,0 +1,21 @@ +import { PrismaTxType } from '@common/prisma/prisma.type'; + +export interface FindVerifiedCertificationCode { + target: string; + targetType: 'PHONE' | 'EMAIL'; + type: 'SIGN_UP' | 'CHANGE_PHONE' | 'FIND_PASSWORD'; + certificationId: string; +} + +export interface CertificationAdaptorPort { + findVerifiedCertificationCode( + command: FindVerifiedCertificationCode, + tx?: PrismaTxType, + ): Promise; + + changeStatusSuccessAndRecord( + id: string, + userId: string, + tx?: PrismaTxType, + ): Promise; +} diff --git a/src/_ddd/user/domain/service/user.service.ts b/src/_ddd/user/domain/service/user.service.ts new file mode 100644 index 0000000..53bd719 --- /dev/null +++ b/src/_ddd/user/domain/service/user.service.ts @@ -0,0 +1,52 @@ +import { UserEntity } from '@/_ddd/user/domain/entity/user.root-entity'; +import { UserRepository } from '@/_ddd/user/infrastructure/repository/user.repository'; +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class UserService { + constructor(private readonly userRepository: UserRepository) {} + async findByAccount(account: string, tx?: PrismaTxType) { + const user = await this.userRepository.findByAccount(account, tx); + if (!user) return null; + const phone = user.getProps().phone.unpack(); + const accout = user.getProps().account.unpack(); + const { nickname } = user.getProps(); + return { + id: user.id, + ...phone, + ...accout, + nickname, + }; + } + + async findByPhone( + input: { phone: string; countryCode: string }, + tx?: PrismaTxType, + ) { + const user = await this.userRepository.findByPhone(input, tx); + if (!user) return null; + const phone = user.getProps().phone.unpack(); + const accout = user.getProps().account.unpack(); + const { nickname } = user.getProps(); + return { + id: user.id, + ...phone, + ...accout, + nickname, + }; + } + + private mapUser(user: UserEntity) { + const userProps = user.getProps(); + const phone = userProps.phone.unpack(); + const accout = userProps.account.unpack(); + const { nickname } = userProps; + return { + id: user.id, + ...phone, + ...accout, + nickname, + }; + } +} diff --git a/src/_ddd/user/domain/service/user.validator.ts b/src/_ddd/user/domain/service/user.validator.ts new file mode 100644 index 0000000..6f7b5ce --- /dev/null +++ b/src/_ddd/user/domain/service/user.validator.ts @@ -0,0 +1,108 @@ +import { Injectable } from '@nestjs/common'; +import { AuthAdaptor } from '../../infrastructure/adaptor/auth.adaptor'; +import { CertificationAdaptor } from '../../infrastructure/adaptor/cerification.adaptor'; +import { UserRepository } from '../../infrastructure/repository/user.repository'; +import { UserEntity } from '../entity/user.root-entity'; +import { + UserAccountExist, + UserCertificationCodeInvalid, + UserNicknameExist, + UserPasswordInvailid, + UserPhoneExist, +} from '../error'; +import { PhoneProps } from '../type/phone.props'; + +@Injectable() +export class UserValidator { + constructor( + private readonly userRepo: UserRepository, + private readonly authAdaptor: AuthAdaptor, + private readonly certificationAdaptor: CertificationAdaptor, + ) {} + + async canSignup({ + account, + phone, + countryCode, + nickname, + certificationId, + }: { + account: string; + phone: string; + countryCode: string; + nickname: string; + certificationId: string; + }) { + const existAccount = await this.userRepo.findByAccount(account); + if (existAccount) { + throw UserAccountExist('이미 존재하는 계정'); + } + + const existPhone = await this.userRepo.findByPhone({ + countryCode, + phone, + }); + if (existPhone) { + throw UserPhoneExist('이미 존재하는 핸드폰'); + } + + const existNickname = await this.userRepo.findByNickname(nickname); + if (existNickname) { + throw UserNicknameExist('이미 존재하는 닉네임'); + } + + const certification = + await this.certificationAdaptor.findVerifiedCertificationCode({ + certificationId: certificationId, + type: 'SIGN_UP', + target: countryCode + phone, + targetType: 'PHONE', + }); + if (!certification) { + throw UserCertificationCodeInvalid('인증정보가 올바르지 않습니다.'); + } + return true; + } + + async canChangeUserNickname(nickname: string) { + const existNickname = await this.userRepo.findByNickname(nickname); + if (existNickname) { + throw UserNicknameExist('이미 존재하는 닉네임'); + } + return true; + } + + async checkPassword(user: UserEntity, nowPassword: string) { + const props = user.getProps(); + const compare = await this.authAdaptor.compare( + nowPassword, + props.account.unpack().password, + ); + if (!compare) { + throw UserPasswordInvailid('비밀번호가 틀렸습니다.'); + } + return true; + } + + async canChangePhone(newPhone: PhoneProps, certificationId: string) { + const existPhone = await this.userRepo.findByPhone({ + countryCode: newPhone.countryCode, + phone: newPhone.phone, + }); + if (existPhone) { + throw UserPhoneExist('이미 존재하는 핸드폰'); + } + const check = await this.certificationAdaptor.findVerifiedCertificationCode( + { + certificationId, + target: newPhone.countryCode + newPhone.phone, + type: 'CHANGE_PHONE', + targetType: 'PHONE', + }, + ); + if (!check) { + throw UserCertificationCodeInvalid('인증번호가 유효하지 않습니다.'); + } + return true; + } +} diff --git a/src/_ddd/user/domain/type/account.props.ts b/src/_ddd/user/domain/type/account.props.ts new file mode 100644 index 0000000..80be867 --- /dev/null +++ b/src/_ddd/user/domain/type/account.props.ts @@ -0,0 +1,4 @@ +export interface AccountProps { + account: string; + password: string; +} diff --git a/src/_ddd/user/domain/type/address.props.ts b/src/_ddd/user/domain/type/address.props.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/_ddd/user/domain/type/phone.props.ts b/src/_ddd/user/domain/type/phone.props.ts new file mode 100644 index 0000000..0808050 --- /dev/null +++ b/src/_ddd/user/domain/type/phone.props.ts @@ -0,0 +1,4 @@ +export interface PhoneProps { + countryCode: string; + phone: string; +} diff --git a/src/_ddd/user/domain/type/user.props.ts b/src/_ddd/user/domain/type/user.props.ts new file mode 100644 index 0000000..be6515f --- /dev/null +++ b/src/_ddd/user/domain/type/user.props.ts @@ -0,0 +1,19 @@ +import { Account } from '../value-object/account.value-object'; +import { Phone } from '../value-object/phone.value-object'; +import { Snapshot } from '../value-object/snapshot.value-object'; +import { AccountProps } from './account.props'; +import { PhoneProps } from './phone.props'; + +export interface UserProps { + id: string; + account: Account; + phone: Phone; + nickname: string; + snapshots: Snapshot[]; +} + +export interface CreateUserProps { + nickname: string; + account: AccountProps; + phone: PhoneProps; +} diff --git a/src/_ddd/user/domain/user.mapper.ts b/src/_ddd/user/domain/user.mapper.ts new file mode 100644 index 0000000..7699167 --- /dev/null +++ b/src/_ddd/user/domain/user.mapper.ts @@ -0,0 +1,81 @@ +import { Mapper } from '@/_ddd_shared/ddd/mapper.interface'; +import { Injectable } from '@nestjs/common'; +import { Prisma, User } from '@prisma/client'; +import { UserEntity } from './entity/user.root-entity'; +import { UserProps } from './type/user.props'; +import { Account } from './value-object/account.value-object'; +import { Phone } from './value-object/phone.value-object'; + +@Injectable() +export class UserMapper implements Mapper { + toPersistence(entity: UserEntity): { + create: Prisma.UserCreateInput; + update: Prisma.UserUpdateInput; + } { + const user = entity.getProps(); + const accountInput = user.account.unpack(); + const phoneInput = user.phone.unpack(); + const snapshots = user.snapshots.map((snapshot) => { + const sn = snapshot.unpack(); + const { id, nickname } = sn; + const phone = sn.phone; + const account = sn.account; + return { + id, + nickname, + ...phone, + ...account, + }; + }); + const create: Prisma.UserCreateInput = { + id: user.id, + nickname: user.nickname, + ...accountInput, + ...phoneInput, + snapshots: { + createMany: { + data: snapshots, + }, + }, + }; + + const update: Prisma.UserUpdateInput = { + nickname: user.nickname, + ...phoneInput, + snapshots: { + createMany: { + data: snapshots, + }, + }, + }; + + return { create, update }; + } + + toDomain(record: User): UserEntity { + const account = new Account({ + account: record.account, + password: record.password, + }); + const phone = new Phone({ + phone: record.phone, + countryCode: record.countryCode, + }); + const props: UserProps = { + id: record.id, + nickname: record.nickname, + account, + phone, + snapshots: [], + }; + const user = new UserEntity({ + id: record.id, + props, + }); + + return user; + } + toResponse(entity: any): any { + return entity; + } +} diff --git a/src/_ddd/user/domain/value-object/account.value-object.ts b/src/_ddd/user/domain/value-object/account.value-object.ts new file mode 100644 index 0000000..4215d68 --- /dev/null +++ b/src/_ddd/user/domain/value-object/account.value-object.ts @@ -0,0 +1,14 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { AccountProps } from '../type/account.props'; + +export class Account extends ValueObject { + constructor(props: AccountProps) { + super(props); + } + + protected validate(props: AccountProps): void { + if (!props.account || !props.password) { + throw new Error('Email and password are required'); + } + } +} diff --git a/src/_ddd/user/domain/value-object/phone.value-object.ts b/src/_ddd/user/domain/value-object/phone.value-object.ts new file mode 100644 index 0000000..53b4569 --- /dev/null +++ b/src/_ddd/user/domain/value-object/phone.value-object.ts @@ -0,0 +1,14 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { PhoneProps } from '../type/phone.props'; + +export class Phone extends ValueObject { + constructor(props: PhoneProps) { + super(props); + } + + protected validate(props: PhoneProps): void { + if (props.countryCode.length !== 3) { + throw new Error('Invalid country code'); + } + } +} diff --git a/src/_ddd/user/domain/value-object/snapshot.value-object.ts b/src/_ddd/user/domain/value-object/snapshot.value-object.ts new file mode 100644 index 0000000..5f696f6 --- /dev/null +++ b/src/_ddd/user/domain/value-object/snapshot.value-object.ts @@ -0,0 +1,17 @@ +import { ValueObject } from '@/_ddd_shared/ddd/value-object/value-object.base'; +import { AccountProps } from '../type/account.props'; +import { PhoneProps } from '../type/phone.props'; + +export interface SnapshotProps { + id: string; + account: AccountProps; + phone: PhoneProps; + nickname: string; +} + +export class Snapshot extends ValueObject { + static create(props: SnapshotProps) { + return new Snapshot(props); + } + protected validate(): void {} +} diff --git a/src/_ddd/user/infrastructure/adaptor/auth.adaptor.ts b/src/_ddd/user/infrastructure/adaptor/auth.adaptor.ts new file mode 100644 index 0000000..35246c0 --- /dev/null +++ b/src/_ddd/user/infrastructure/adaptor/auth.adaptor.ts @@ -0,0 +1,19 @@ +import { HashService } from '@/_ddd/auth/domain/service/HashService'; +import { Injectable } from '@nestjs/common'; +import { AuthAdaptorPort } from '../../domain/port/out/auth-adaptor.out-port'; + +/** + * 만약 서버 분리가 될경우 API통신이나 rpc등의 기능을 사용해야합니다. + */ +@Injectable() +export class AuthAdaptor implements AuthAdaptorPort { + constructor(private readonly authService: HashService) {} + + async hash(password: string): Promise { + return await this.authService.hash(password); + } + + async compare(hash: string, password: string): Promise { + return await this.authService.compare(hash, password); + } +} diff --git a/src/_ddd/user/infrastructure/adaptor/cerification.adaptor.ts b/src/_ddd/user/infrastructure/adaptor/cerification.adaptor.ts new file mode 100644 index 0000000..fa420cd --- /dev/null +++ b/src/_ddd/user/infrastructure/adaptor/cerification.adaptor.ts @@ -0,0 +1,35 @@ +import { CertificationService } from '@/_ddd/certification/domain/service/certification.service'; +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; +import { + CertificationAdaptorPort, + FindVerifiedCertificationCode, +} from '../../domain/port/out/certification-adaptor.out-port'; + +@Injectable() +export class CertificationAdaptor implements CertificationAdaptorPort { + constructor(private readonly service: CertificationService) {} + async findVerifiedCertificationCode( + command: FindVerifiedCertificationCode, + ): Promise { + const { target, certificationId, targetType, type } = command; + const certification = await this.service.findById(certificationId); + const isCertificationVaild = + targetType === certification.targetType && + target === certification.target && + type === certification.type && + certification.status === 'VERIFIED'; + return isCertificationVaild; + } + + // TODO: certification code - user record 로 변경 + async changeStatusSuccessAndRecord( + id: string, + userId: string, + tx?: PrismaTxType, + ): Promise { + await this.service.changeStatusSuccess(id, tx); + await this.service.recordCertificationCode(id, userId, tx); + return true; + } +} diff --git a/src/_ddd/user/infrastructure/repository/user.repository.ts b/src/_ddd/user/infrastructure/repository/user.repository.ts new file mode 100644 index 0000000..3540263 --- /dev/null +++ b/src/_ddd/user/infrastructure/repository/user.repository.ts @@ -0,0 +1,66 @@ +import { PrismaRepositoryBase } from '@/_ddd_shared/db/prisma.repository.base'; +import { PrismaService } from '@common/prisma/prisma.service'; +import { PrismaTxType } from '@common/prisma/prisma.type'; +import { Injectable } from '@nestjs/common'; +import { UserEntity } from '../../domain/entity/user.root-entity'; +import { UserMapper } from '../../domain/user.mapper'; + +@Injectable() +export class UserRepository extends PrismaRepositoryBase { + constructor( + protected readonly prisma: PrismaService, + private readonly userMapper: UserMapper, + ) { + super(prisma); + } + async save(userEntity: UserEntity, tx?: PrismaTxType): Promise { + const check = userEntity.isChanged(); + if (check) { + userEntity.addSnapshot(); + } + const { create, update } = this.userMapper.toPersistence(userEntity); + await this.excute(async (prisma) => { + return await prisma.user.upsert({ + where: { id: userEntity.id }, + update: update, + create: create, + }); + }, tx); + return userEntity; + } + + async findByAccount( + account: string, + tx?: PrismaTxType, + ): Promise { + return await this.excute(async (prisma) => { + const record = await prisma.user.findUnique({ where: { account } }); + return record ? this.userMapper.toDomain(record) : null; + }, tx); + } + + async findByPhone( + phone: { countryCode: string; phone: string }, + tx?: PrismaTxType, + ): Promise { + return await this.excute(async (prisma) => { + const record = await prisma.user.findUnique({ + where: { + countryCode: phone.countryCode, + phone: phone.phone, + }, + }); + return record ? this.userMapper.toDomain(record) : null; + }, tx); + } + + async findByNickname( + nickname: string, + tx?: PrismaTxType, + ): Promise { + return await this.excute(async (prisma) => { + const record = await prisma.user.findUnique({ where: { nickname } }); + return record ? this.userMapper.toDomain(record) : null; + }, tx); + } +} diff --git a/src/_ddd/user/user.module.ts b/src/_ddd/user/user.module.ts new file mode 100644 index 0000000..2b20847 --- /dev/null +++ b/src/_ddd/user/user.module.ts @@ -0,0 +1,37 @@ +import { Module, Provider, forwardRef } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; +import { DDD_AuthModule } from '../auth/auth.module'; +import { CertificationModule } from '../certification/certification.module'; +import { SignupHttpController } from './application/command/signup/http/signup.http.controller'; +import { SignupCommandHandler } from './application/command/signup/signup.command-handler'; +import { UserService } from './domain/service/user.service'; +import { UserValidator } from './domain/service/user.validator'; +import { UserMapper } from './domain/user.mapper'; +import { AuthAdaptor } from './infrastructure/adaptor/auth.adaptor'; +import { CertificationAdaptor } from './infrastructure/adaptor/cerification.adaptor'; +import { UserRepository } from './infrastructure/repository/user.repository'; + +const httpController = [SignupHttpController]; + +const handler: Provider[] = [SignupCommandHandler]; +const validator: Provider[] = [UserValidator]; +const service: Provider[] = [UserService]; + +const mapper: Provider[] = [UserMapper]; +const repository: Provider[] = [UserRepository]; +const adaptor: Provider[] = [AuthAdaptor, CertificationAdaptor]; + +@Module({ + imports: [CqrsModule, CertificationModule, forwardRef(() => DDD_AuthModule)], + controllers: [...httpController], + providers: [ + ...validator, + ...mapper, + ...repository, + ...adaptor, + ...handler, + ...service, + ], + exports: [...service], +}) +export class DDD_UserModule {} diff --git a/src/app.module.ts b/src/app.module.ts index 0414eb5..adbae78 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,21 +1,43 @@ import { defaultModules } from '@config/module/default.module'; +import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; import { Module } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; +import { EventEmitterModule } from '@nestjs/event-emitter'; +import { GraphQLModule } from '@nestjs/graphql'; +import { DDD_AuthModule } from './_ddd/auth/auth.module'; +import { DDD_CarModule } from './_ddd/car/car.module'; +import { CertificationModule } from './_ddd/certification/certification.module'; +import { DDD_DrivingModule } from './_ddd/driving/driving.module'; +import { DDD_NotificationModule } from './_ddd/notification/notification.module'; +import { DDD_UserModule } from './_ddd/user/user.module'; import { AppController } from './app.controller'; import { AppService } from './app.service'; -import { AuthModule } from './auth/auth.module'; -import { CarModule } from './module/car.module'; -import { DrivingModule } from './module/driving.module'; + import { ParkingModule } from './module/parking.module'; import { SmsModule } from './module/sms.module'; @Module({ imports: [ + EventEmitterModule.forRoot(), + GraphQLModule.forRoot({ + driver: ApolloDriver, + autoSchemaFile: true, + }), + CqrsModule, + CertificationModule, ...defaultModules, - AuthModule, + // AuthModule, SmsModule, - CarModule, - DrivingModule, + // CarModule, + // DrivingModule, ParkingModule, + //DDD + CertificationModule, + DDD_AuthModule, + DDD_UserModule, + DDD_NotificationModule, + DDD_CarModule, + DDD_DrivingModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 97b1f9d..540d01d 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -1,95 +1,95 @@ -import { CurrentUser } from '@common/decorator/CurrentUser'; -import { LoginOnly } from '@common/decorator/LoginOnly'; -import { eitherToResponse, generateResponse } from '@common/util/Res'; -import { TypedBody, TypedRoute } from '@nestia/core'; -import { Controller, Res, UseGuards } from '@nestjs/common'; -import { Auth } from '@type/auth'; -import { Base } from '@type/index'; -import { Response } from 'express'; -import { REFRESH_COOKIE_NAME } from './auth.constant'; -import { RefreshGuard } from './guard/refresh.guard'; -import { JwtPayload } from './interface/auth.service.interface'; -import { AuthService } from './provider/auth.service'; -@Controller('/auth') -export class AuthController { - constructor(private readonly authService: AuthService) {} - @TypedRoute.Get('/') - @LoginOnly() - checkLogin(@CurrentUser() user: JwtPayload) { - if (user) { - return generateResponse({ isLogin: true, user: user }); - } - return generateResponse({ isLogin: false }); - } +// import { CurrentUser } from '@common/decorator/CurrentUser'; +// import { LoginOnly } from '@common/decorator/LoginOnly'; +// import { eitherToResponse, generateResponse } from '@common/util/Res'; +// import { TypedBody, TypedRoute } from '@nestia/core'; +// import { Controller, Res, UseGuards } from '@nestjs/common'; +// import { Auth } from '@type/auth'; +// import { Base } from '@type/index'; +// import { Response } from 'express'; +// import { REFRESH_COOKIE_NAME } from './auth.constant'; +// import { RefreshGuard } from './guard/refresh.guard'; +// import { JwtPayload } from './interface/auth.service.interface'; +// import { AuthService } from './provider/auth.service'; +// @Controller('/auth') +// export class AuthController { +// constructor(private readonly authService: AuthService) {} +// @TypedRoute.Get('/') +// @LoginOnly() +// checkLogin(@CurrentUser() user: JwtPayload) { +// if (user) { +// return generateResponse({ isLogin: true, user: user }); +// } +// return generateResponse({ isLogin: false }); +// } - @TypedRoute.Post('/login') - async login( - @TypedBody() dto: Auth.Login.Request.Dto, - @Res({ passthrough: true }) res: Response, - ) { - const result = await this.authService.login(dto); - if (result.isLeft()) { - result; - return eitherToResponse(result); - } - const { refreshToken, ...rest } = result.value; - res.cookie(REFRESH_COOKIE_NAME, refreshToken, { - httpOnly: true, - secure: process.env.NODE_ENV === 'production', - sameSite: 'strict', - }); - return generateResponse({ ...rest }); - } +// @TypedRoute.Post('/login') +// async login( +// @TypedBody() dto: Auth.Login.Request.Dto, +// @Res({ passthrough: true }) res: Response, +// ) { +// const result = await this.authService.login(dto); +// if (result.isLeft()) { +// result; +// return eitherToResponse(result); +// } +// const { refreshToken, ...rest } = result.value; +// res.cookie(REFRESH_COOKIE_NAME, refreshToken, { +// httpOnly: true, +// secure: process.env.NODE_ENV === 'production', +// sameSite: 'strict', +// }); +// return generateResponse({ ...rest }); +// } - @TypedRoute.Post('/signup') - async signup(@TypedBody() dto: Auth.Signup.Request.Dto) { - const result = await this.authService.signup(dto); - return eitherToResponse(result); - } +// @TypedRoute.Post('/signup') +// async signup(@TypedBody() dto: Auth.Signup.Request.Dto) { +// const result = await this.authService.signup(dto); +// return eitherToResponse(result); +// } - @TypedRoute.Get('/token') - @UseGuards(RefreshGuard) - async refreshToken( - @CurrentUser() user: JwtPayload, - @Res({ passthrough: true }) res: Response, - ): Promise< - Base.SUCCESS<{ - accessToken: string; - }> - > { - const { refreshToken, accessToken } = - await this.authService.refreshToken(user); - res.cookie(REFRESH_COOKIE_NAME, refreshToken, { - httpOnly: true, - secure: process.env.NODE_ENV === 'production', - sameSite: 'strict', - }); - return generateResponse({ accessToken }); - } +// @TypedRoute.Get('/token') +// @UseGuards(RefreshGuard) +// async refreshToken( +// @CurrentUser() user: JwtPayload, +// @Res({ passthrough: true }) res: Response, +// ): Promise< +// Base.SUCCESS<{ +// accessToken: string; +// }> +// > { +// const { refreshToken, accessToken } = +// await this.authService.refreshToken(user); +// res.cookie(REFRESH_COOKIE_NAME, refreshToken, { +// httpOnly: true, +// secure: process.env.NODE_ENV === 'production', +// sameSite: 'strict', +// }); +// return generateResponse({ accessToken }); +// } - @TypedRoute.Post('/logout') - @LoginOnly() - logout(@Res() res: Response, @CurrentUser() user: JwtPayload) { - this.authService.logout(user); - res.clearCookie(REFRESH_COOKIE_NAME); - return generateResponse({ - isLogin: false, - }); - } +// @TypedRoute.Post('/logout') +// @LoginOnly() +// logout(@Res() res: Response, @CurrentUser() user: JwtPayload) { +// this.authService.logout(user); +// res.clearCookie(REFRESH_COOKIE_NAME); +// return generateResponse({ +// isLogin: false, +// }); +// } - @TypedRoute.Post('/certification') - async requsetCertificationCode( - @TypedBody() dto: Auth.RequsetCertificationCode.Request.Dto, - ) { - const result = await this.authService.requsetCertificationCode(dto); - return eitherToResponse(result); - } +// @TypedRoute.Post('/certification') +// async requsetCertificationCode( +// @TypedBody() dto: Auth.RequsetCertificationCode.Request.Dto, +// ) { +// const result = await this.authService.requsetCertificationCode(dto); +// return eitherToResponse(result); +// } - @TypedRoute.Post('/certification/validate') - async validateCertificationCode( - @TypedBody() dto: Auth.ValidateCertificationCode.Request.Dto, - ) { - const result = await this.authService.validateCertificationCode(dto); - return eitherToResponse(result); - } -} +// @TypedRoute.Post('/certification/validate') +// async validateCertificationCode( +// @TypedBody() dto: Auth.ValidateCertificationCode.Request.Dto, +// ) { +// const result = await this.authService.validateCertificationCode(dto); +// return eitherToResponse(result); +// } +// } diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index 15fbf46..84d8a46 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -1,52 +1,52 @@ -import { SmsModule } from '@/module/sms.module'; -import { UserModule } from '@/module/user.module'; -import { CertificationCodeRepository } from '@/repository/certification/certificationCode.repository'; -import { Global, Module } from '@nestjs/common'; -import { JwtService } from '@nestjs/jwt'; -import { - AUTH_CACHE_SERVICE, - JWT_OPTIONS, - PASSWORD_OPTIONS, -} from './auth.constant'; -import { AuthController } from './auth.controller'; -import { jwtOptions, passwordOptions } from './auth.option'; -import { RefreshGuard } from './guard/refresh.guard'; -import { AuthLocalService } from './implement/auth.local.service'; -import { AuthCacheService } from './provider/auth.cache.service'; -import { AuthJWTService } from './provider/auth.jwt.service'; -import { AuthPasswordService } from './provider/auth.password.service'; -import { AuthService } from './provider/auth.service'; -import { PhoneCertificationService } from './provider/phone.certification.service'; +// import { SmsModule } from '@/module/sms.module'; +// import { UserModule } from '@/module/user.module'; +// import { CertificationCodeRepository } from '@/repository/certification/certificationCode.repository'; +// import { Global, Module } from '@nestjs/common'; +// import { JwtService } from '@nestjs/jwt'; +// import { +// AUTH_CACHE_SERVICE, +// JWT_OPTIONS, +// PASSWORD_OPTIONS, +// } from './auth.constant'; +// import { AuthController } from './auth.controller'; +// import { jwtOptions, passwordOptions } from './auth.option'; +// import { RefreshGuard } from './guard/refresh.guard'; +// import { AuthLocalService } from './implement/auth.local.service'; +// import { AuthCacheService } from './provider/auth.cache.service'; +// import { AuthJWTService } from './provider/auth.jwt.service'; +// import { AuthPasswordService } from './provider/auth.password.service'; +// import { AuthService } from './provider/auth.service'; +// import { PhoneCertificationService } from './provider/phone.certification.service'; -const providers = [ - AuthService, - AuthLocalService, - AuthPasswordService, - AuthJWTService, - AuthCacheService, - JwtService, - PhoneCertificationService, - CertificationCodeRepository, - { - provide: AUTH_CACHE_SERVICE, - useClass: AuthCacheService, - }, -]; +// const providers = [ +// AuthService, +// AuthLocalService, +// AuthPasswordService, +// AuthJWTService, +// AuthCacheService, +// JwtService, +// PhoneCertificationService, +// CertificationCodeRepository, +// { +// provide: AUTH_CACHE_SERVICE, +// useClass: AuthCacheService, +// }, +// ]; -const gaurds = [RefreshGuard]; -const options = [ - { provide: JWT_OPTIONS, useValue: jwtOptions }, - { - provide: PASSWORD_OPTIONS, - useValue: passwordOptions, - }, -]; +// const gaurds = [RefreshGuard]; +// const options = [ +// { provide: JWT_OPTIONS, useValue: jwtOptions }, +// { +// provide: PASSWORD_OPTIONS, +// useValue: passwordOptions, +// }, +// ]; -@Global() -@Module({ - imports: [SmsModule, UserModule], - controllers: [AuthController], - providers: [...providers, ...options, ...gaurds], - exports: [...providers], -}) -export class AuthModule {} +// @Global() +// @Module({ +// imports: [SmsModule, UserModule], +// controllers: [AuthController], +// providers: [...providers, ...options, ...gaurds], +// exports: [...providers], +// }) +// export class AuthModule {} diff --git a/src/auth/implement/auth.local.service.ts b/src/auth/implement/auth.local.service.ts index 918dce0..ed1f9d9 100644 --- a/src/auth/implement/auth.local.service.ts +++ b/src/auth/implement/auth.local.service.ts @@ -1,162 +1,162 @@ -import { AUTH_ERROR } from '@/constant/error/auth.error'; -import { UserService } from '@/providers/user/user.service'; -import { PrismaService } from '@common/prisma/prisma.service'; -import { Either, Left, Right } from '@common/util/Either'; -import { Injectable } from '@nestjs/common'; -import { CertificationCode } from '@prisma/client'; +// import { AUTH_ERROR } from '@/constant/error/auth.error'; +// import { UserService } from '@/providers/user/user.service'; +// import { PrismaService } from '@common/prisma/prisma.service'; +// import { Either, Left, Right } from '@common/util/Either'; +// import { Injectable } from '@nestjs/common'; +// import { CertificationCode } from '@prisma/client'; -import { Auth } from '@type/auth'; -import { AuthError } from '@type/auth/error'; -import { v4 } from 'uuid'; -import { AuthJWTService } from '../provider/auth.jwt.service'; -import { AuthPasswordService } from './../provider/auth.password.service'; +// import { Auth } from '@type/auth'; +// import { AuthError } from '@type/auth/error'; +// import { v4 } from 'uuid'; +// import { AuthJWTService } from '../provider/auth.jwt.service'; +// import { AuthPasswordService } from './../provider/auth.password.service'; -//* Service for local authentication -@Injectable() -export class AuthLocalService { - constructor( - private readonly authPasswordService: AuthPasswordService, - private readonly authJwtService: AuthJWTService, - private readonly userService: UserService, - private readonly prismaService: PrismaService, - ) {} +// //* Service for local authentication +// @Injectable() +// export class AuthLocalService { +// constructor( +// private readonly authPasswordService: AuthPasswordService, +// private readonly authJwtService: AuthJWTService, +// private readonly userService: UserService, +// private readonly prismaService: PrismaService, +// ) {} - async login(dto: Auth.Login.Request.LocalDto): Promise< - Either< - AuthError.AUTH_INVALID, - { - accessToken: string; - refreshToken: string; - nickname: string; - userId: string; - } - > - > { - const { account, password } = dto; - const user = await this.userService.findUser({ account }); - if (!user) { - return Left.create(AUTH_ERROR.AUTH_INVALID()); - } - const { password: hashedPassword } = user; - const isMatch = await this.authPasswordService.compare( - password, - hashedPassword, - ); - if (isMatch.isLeft()) { - return isMatch; - } - const accessToken = this.authJwtService.accessTokenSign({ - id: user.id, - account: user.account, - type: dto.type, - }); - const refreshToken = this.authJwtService.refreshTokenSign({ - id: user.id, - account: user.account, - type: dto.type, - }); +// async login(dto: Auth.Login.Request.LocalDto): Promise< +// Either< +// AuthError.AUTH_INVALID, +// { +// accessToken: string; +// refreshToken: string; +// nickname: string; +// userId: string; +// } +// > +// > { +// const { account, password } = dto; +// const user = await this.userService.findUser({ account }); +// if (!user) { +// return Left.create(AUTH_ERROR.AUTH_INVALID()); +// } +// const { password: hashedPassword } = user; +// const isMatch = await this.authPasswordService.compare( +// password, +// hashedPassword, +// ); +// if (isMatch.isLeft()) { +// return isMatch; +// } +// const accessToken = this.authJwtService.accessTokenSign({ +// id: user.id, +// account: user.account, +// type: dto.type, +// }); +// const refreshToken = this.authJwtService.refreshTokenSign({ +// id: user.id, +// account: user.account, +// type: dto.type, +// }); - return Right.create({ - accessToken, - refreshToken, - nickname: user.nickname, - userId: user.id, - }); - } +// return Right.create({ +// accessToken, +// refreshToken, +// nickname: user.nickname, +// userId: user.id, +// }); +// } - async signup( - dto: Auth.Signup.Request.LocalDto, - ): Promise< - Either< - | AuthError.CERTIFICATION_INVALID - | AuthError.CERTIFICATION_NOT_FOUND - | AuthError.USER_ALREADY_EXISTS, - { userId: string } - > - > { - const { certificationId, account, password, phone, countryCode, nickname } = - dto; - const phonefull = `${countryCode}${phone}`; - const accountExists = await this.userService.checkUserExists({ - account, - }); - if (accountExists) { - return Left.create(AUTH_ERROR.USER_ALREADY_EXISTS()); - } +// async signup( +// dto: Auth.Signup.Request.LocalDto, +// ): Promise< +// Either< +// | AuthError.CERTIFICATION_INVALID +// | AuthError.CERTIFICATION_NOT_FOUND +// | AuthError.USER_ALREADY_EXISTS, +// { userId: string } +// > +// > { +// const { certificationId, account, password, phone, countryCode, nickname } = +// dto; +// const phonefull = `${countryCode}${phone}`; +// const accountExists = await this.userService.checkUserExists({ +// account, +// }); +// if (accountExists) { +// return Left.create(AUTH_ERROR.USER_ALREADY_EXISTS()); +// } - const phoneExists = await this.userService.checkUserExists({ - phone, - }); - if (phoneExists) { - return Left.create(AUTH_ERROR.USER_ALREADY_EXISTS()); - } - const certificationCode = await this.validateSignupCertificationCode({ - certificationId, - phone: phonefull, - }); - if (certificationCode.isLeft()) { - return certificationCode; - } +// const phoneExists = await this.userService.checkUserExists({ +// phone, +// }); +// if (phoneExists) { +// return Left.create(AUTH_ERROR.USER_ALREADY_EXISTS()); +// } +// const certificationCode = await this.validateSignupCertificationCode({ +// certificationId, +// phone: phonefull, +// }); +// if (certificationCode.isLeft()) { +// return certificationCode; +// } - const hashedPassword = await this.authPasswordService.hash(password); - return await this.prismaService.$transaction(async (tx) => { - const newUser = await this.userService.createUser( - { - account, - phone: phone, - countryCode: countryCode, - password: hashedPassword, - nickname, - }, - tx, - ); - const { id: userId } = newUser; - await tx.certification.create({ - data: { - id: v4(), - certificationCodeId: certificationId, - userId: userId, - targetType: 'PHONE', - type: 'SIGN_UP', - }, - }); - await tx.certificationCode.update({ - where: { id: certificationId }, - data: { status: 'SUCCESS' }, - }); - return Right.create({ userId }); - }); - } +// const hashedPassword = await this.authPasswordService.hash(password); +// return await this.prismaService.$transaction(async (tx) => { +// const newUser = await this.userService.createUser( +// { +// account, +// phone: phone, +// countryCode: countryCode, +// password: hashedPassword, +// nickname, +// }, +// tx, +// ); +// const { id: userId } = newUser; +// await tx.certificationCode.create({ +// data: { +// id: v4(), +// certificationCodeId: certificationId, +// userId: userId, +// targetType: 'PHONE', +// type: 'SIGN_UP', +// }, +// }); +// await tx.certificationCode.update({ +// where: { id: certificationId }, +// data: { status: 'SUCCESS' }, +// }); +// return Right.create({ userId }); +// }); +// } - private async validateSignupCertificationCode(dto: { - certificationId: string; - phone: string; - }): Promise< - Either< - AuthError.CERTIFICATION_INVALID | AuthError.CERTIFICATION_NOT_FOUND, - CertificationCode - > - > { - const { certificationId, phone } = dto; - const certificationCode = - await this.prismaService.certificationCode.findUnique({ - where: { id: certificationId }, - }); - if (!certificationCode) { - return Left.create(AUTH_ERROR.CERTIFICATION_NOT_FOUND()); - } - if (certificationCode.status !== 'VERIFIED') { - return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); - } - if (certificationCode.type !== 'SIGN_UP') { - return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); - } - if (certificationCode.targetType !== 'PHONE') { - return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); - } - if (certificationCode.target !== phone) { - return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); - } - return Right.create(certificationCode); - } -} +// private async validateSignupCertificationCode(dto: { +// certificationId: string; +// phone: string; +// }): Promise< +// Either< +// AuthError.CERTIFICATION_INVALID | AuthError.CERTIFICATION_NOT_FOUND, +// CertificationCode +// > +// > { +// const { certificationId, phone } = dto; +// const certificationCode = +// await this.prismaService.certificationCode.findUnique({ +// where: { id: certificationId }, +// }); +// if (!certificationCode) { +// return Left.create(AUTH_ERROR.CERTIFICATION_NOT_FOUND()); +// } +// if (certificationCode.status !== 'VERIFIED') { +// return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); +// } +// if (certificationCode.type !== 'SIGN_UP') { +// return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); +// } +// if (certificationCode.targetType !== 'PHONE') { +// return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); +// } +// if (certificationCode.target !== phone) { +// return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); +// } +// return Right.create(certificationCode); +// } +// } diff --git a/src/auth/provider/auth.service.ts b/src/auth/provider/auth.service.ts index 9d583b0..f3acf30 100644 --- a/src/auth/provider/auth.service.ts +++ b/src/auth/provider/auth.service.ts @@ -1,153 +1,153 @@ -import { AUTH_ERROR } from '@/constant/error/auth.error'; -import { Either, Left } from '@common/util/Either'; -import { Inject, Injectable } from '@nestjs/common'; -import { Auth } from '@type/auth'; -import { AuthError } from '@type/auth/error'; -import { assertPrune } from 'typia/lib/misc'; -import { AUTH_CACHE_SERVICE } from '../auth.constant'; -import { AuthLocalService } from '../implement/auth.local.service'; -import { - BasicAuthCacheService, - BasicAuthService, - JwtPayload, -} from '../interface/auth.service.interface'; -import { AuthJWTService } from './auth.jwt.service'; -import { PhoneCertificationService } from './phone.certification.service'; +// import { AUTH_ERROR } from '@/constant/error/auth.error'; +// import { Either, Left } from '@common/util/Either'; +// import { Inject, Injectable } from '@nestjs/common'; +// import { Auth } from '@type/auth'; +// import { AuthError } from '@type/auth/error'; +// import { assertPrune } from 'typia/lib/misc'; +// import { AUTH_CACHE_SERVICE } from '../auth.constant'; +// import { AuthLocalService } from '../implement/auth.local.service'; +// import { +// BasicAuthCacheService, +// BasicAuthService, +// JwtPayload, +// } from '../interface/auth.service.interface'; +// import { AuthJWTService } from './auth.jwt.service'; +// import { PhoneCertificationService } from './phone.certification.service'; -@Injectable() -export class AuthService { - constructor( - private readonly phoneCertificationService: PhoneCertificationService, - private readonly localService: AuthLocalService, - @Inject(AUTH_CACHE_SERVICE) - private readonly cacheService: BasicAuthCacheService, - private readonly jwtService: AuthJWTService, - ) {} +// @Injectable() +// export class AuthService { +// constructor( +// private readonly phoneCertificationService: PhoneCertificationService, +// private readonly localService: AuthLocalService, +// @Inject(AUTH_CACHE_SERVICE) +// private readonly cacheService: BasicAuthCacheService, +// private readonly jwtService: AuthJWTService, +// ) {} - async login(dto: Auth.Login.Request.Dto): Promise< - Either< - AuthError.AUTH_INVALID | AuthError.TYPE_NOT_SUPPORTED, - { - accessToken: string; - refreshToken: string; - nickname: string; - userId: string; - } - > - > { - switch (dto.type) { - case 'LOCAL': - // return await this.localService.login(dto); - return await this.processLogin( - this.localService.login.bind(this.localService), - )(dto); - default: - return Left.create( - AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), - ); - } - } +// async login(dto: Auth.Login.Request.Dto): Promise< +// Either< +// AuthError.AUTH_INVALID | AuthError.TYPE_NOT_SUPPORTED, +// { +// accessToken: string; +// refreshToken: string; +// nickname: string; +// userId: string; +// } +// > +// > { +// switch (dto.type) { +// case 'LOCAL': +// // return await this.localService.login(dto); +// return await this.processLogin( +// this.localService.login.bind(this.localService), +// )(dto); +// default: +// return Left.create( +// AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), +// ); +// } +// } - async signup( - dto: Auth.Signup.Request.Dto, - ): Promise< - Either< - | AuthError.CERTIFICATION_INVALID - | AuthError.CERTIFICATION_NOT_FOUND - | AuthError.USER_ALREADY_EXISTS - | AuthError.TYPE_NOT_SUPPORTED, - { userId: string } - > - > { - switch (dto.type) { - case 'LOCAL': - return await this.localService.signup(dto); - default: - return Left.create( - AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), - ); - } - } +// async signup( +// dto: Auth.Signup.Request.Dto, +// ): Promise< +// Either< +// | AuthError.CERTIFICATION_INVALID +// | AuthError.CERTIFICATION_NOT_FOUND +// | AuthError.USER_ALREADY_EXISTS +// | AuthError.TYPE_NOT_SUPPORTED, +// { userId: string } +// > +// > { +// switch (dto.type) { +// case 'LOCAL': +// return await this.localService.signup(dto); +// default: +// return Left.create( +// AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), +// ); +// } +// } - async logout(payload: JwtPayload) { - const _payload = assertPrune(payload); - await this.cacheService.addBlacklist(_payload.id); - return true; - } +// async logout(payload: JwtPayload) { +// const _payload = assertPrune(payload); +// await this.cacheService.addBlacklist(_payload.id); +// return true; +// } - async refreshToken(payload: JwtPayload) { - const _payload = assertPrune(payload); - const accessToken = this.jwtService.accessTokenSign(_payload); - const refreshToken = this.jwtService.refreshTokenSign(_payload); - await this.cacheService.setCache(_payload.id, refreshToken); - return { accessToken, refreshToken }; - } +// async refreshToken(payload: JwtPayload) { +// const _payload = assertPrune(payload); +// const accessToken = this.jwtService.accessTokenSign(_payload); +// const refreshToken = this.jwtService.refreshTokenSign(_payload); +// await this.cacheService.setCache(_payload.id, refreshToken); +// return { accessToken, refreshToken }; +// } - async requsetCertificationCode( - dto: Auth.RequsetCertificationCode.Request.Dto, - ): Promise< - Either< - | AuthError.CERTIFICATION_LIMIT_EXCEEDED - | AuthError.CERTIFICATION_FAILED - | AuthError.USER_ALREADY_EXISTS - | AuthError.TYPE_NOT_SUPPORTED, - boolean - > - > { - switch (dto.targetType) { - case 'PHONE': - const code = await this.generateCertificationCode(); - return await this.phoneCertificationService.sendCertificationCode( - `${dto.countryCode}${dto.target}`, - code, - dto.type, - ); - default: - return Left.create( - AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), - ); - } - } +// async requsetCertificationCode( +// dto: Auth.RequsetCertificationCode.Request.Dto, +// ): Promise< +// Either< +// | AuthError.CERTIFICATION_LIMIT_EXCEEDED +// | AuthError.CERTIFICATION_FAILED +// | AuthError.USER_ALREADY_EXISTS +// | AuthError.TYPE_NOT_SUPPORTED, +// boolean +// > +// > { +// switch (dto.targetType) { +// case 'PHONE': +// const code = await this.generateCertificationCode(); +// return await this.phoneCertificationService.sendCertificationCode( +// `${dto.countryCode}${dto.target}`, +// code, +// dto.type, +// ); +// default: +// return Left.create( +// AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), +// ); +// } +// } - async validateCertificationCode( - dto: Auth.ValidateCertificationCode.Request.Dto, - ): Promise< - Either< - | AuthError.CERTIFICATION_INVALID - | AuthError.CERTIFICATION_EXPIRED - | AuthError.CERTIFICATION_NOT_FOUND - | AuthError.CERTIFICATION_ALREADY_VERIFIED - | AuthError.TYPE_NOT_SUPPORTED, - { cetificationId: string } - > - > { - switch (dto.targetType) { - case 'PHONE': - return await this.phoneCertificationService.verifyCertificationCode( - `${dto.countryCode}${dto.target}`, - dto.code, - dto.type, - ); - default: - return Left.create( - AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), - ); - } - } +// async validateCertificationCode( +// dto: Auth.ValidateCertificationCode.Request.Dto, +// ): Promise< +// Either< +// | AuthError.CERTIFICATION_INVALID +// | AuthError.CERTIFICATION_EXPIRED +// | AuthError.CERTIFICATION_NOT_FOUND +// | AuthError.CERTIFICATION_ALREADY_VERIFIED +// | AuthError.TYPE_NOT_SUPPORTED, +// { cetificationId: string } +// > +// > { +// switch (dto.targetType) { +// case 'PHONE': +// return await this.phoneCertificationService.verifyCertificationCode( +// `${dto.countryCode}${dto.target}`, +// dto.code, +// dto.type, +// ); +// default: +// return Left.create( +// AUTH_ERROR.TYPE_NOT_SUPPORTED('지원하지 않는 타입입니다.'), +// ); +// } +// } - private async generateCertificationCode() { - return Math.floor(Math.random() * 1000000) - .toString() - .padStart(6, '0'); - } +// private async generateCertificationCode() { +// return Math.floor(Math.random() * 1000000) +// .toString() +// .padStart(6, '0'); +// } - private processLogin(login: BasicAuthService['login']) { - return async (dto: Auth.Login.Request.Dto) => { - const result = await login(dto); - if (result.isLeft()) return result; - const { refreshToken, userId } = result.value; - await this.cacheService.setCache(userId, refreshToken); - return result; - }; - } -} +// private processLogin(login: BasicAuthService['login']) { +// return async (dto: Auth.Login.Request.Dto) => { +// const result = await login(dto); +// if (result.isLeft()) return result; +// const { refreshToken, userId } = result.value; +// await this.cacheService.setCache(userId, refreshToken); +// return result; +// }; +// } +// } diff --git a/src/auth/provider/phone.certification.service.ts b/src/auth/provider/phone.certification.service.ts index 2cd5c7c..c896984 100644 --- a/src/auth/provider/phone.certification.service.ts +++ b/src/auth/provider/phone.certification.service.ts @@ -1,191 +1,191 @@ -import { AUTH_ERROR } from '@/constant/error/auth.error'; -import { SmsService } from '@/providers/sms.service'; -import { CertificationCodeRepository } from '@/repository/certification/certificationCode.repository'; -import { PrismaService } from '@common/prisma/prisma.service'; -import { PrismaTxType } from '@common/prisma/prisma.type'; -import { Either, Left, Right } from '@common/util/Either'; -import { Injectable, Logger } from '@nestjs/common'; -import { CERTIFICATION_TYPE } from '@prisma/client'; -import { AuthError } from '@type/auth/error'; -import { UserService } from '../../providers/user/user.service'; +// import { AUTH_ERROR } from '@/constant/error/auth.error'; +// import { SmsService } from '@/providers/sms.service'; +// import { CertificationCodeRepository } from '@/repository/certification/certificationCode.repository'; +// import { PrismaService } from '@common/prisma/prisma.service'; +// import { PrismaTxType } from '@common/prisma/prisma.type'; +// import { Either, Left, Right } from '@common/util/Either'; +// import { Injectable, Logger } from '@nestjs/common'; +// import { CERTIFICATION_TYPE } from '@prisma/client'; +// import { AuthError } from '@type/auth/error'; +// import { UserService } from '../../providers/user/user.service'; -@Injectable() -export class PhoneCertificationService { - private readonly logger = new Logger(PhoneCertificationService.name); - private readonly targetType = 'PHONE'; - constructor( - private readonly prismaService: PrismaService, - private readonly smsService: SmsService, - private readonly userService: UserService, - private readonly certificationCodeRepo: CertificationCodeRepository, - ) {} +// @Injectable() +// export class PhoneCertificationService { +// private readonly logger = new Logger(PhoneCertificationService.name); +// private readonly targetType = 'PHONE'; +// constructor( +// private readonly prismaService: PrismaService, +// private readonly smsService: SmsService, +// private readonly userService: UserService, +// private readonly certificationCodeRepo: CertificationCodeRepository, +// ) {} - async sendCertificationCode( - target: string, - code: string, - type: CERTIFICATION_TYPE, - ): Promise< - Either< - | AuthError.CERTIFICATION_LIMIT_EXCEEDED - | AuthError.CERTIFICATION_FAILED - | AuthError.USER_ALREADY_EXISTS, - boolean - > - > { - return await this.prismaService - .$transaction(async (tx) => { - // 회원가입 여부 확인 - const userExists = await this.userService.checkUserExists( - { - phone: target, - }, - tx, - ); - if (userExists) { - return Left.create(AUTH_ERROR.USER_ALREADY_EXISTS()); - } +// async sendCertificationCode( +// target: string, +// code: string, +// type: CERTIFICATION_TYPE, +// ): Promise< +// Either< +// | AuthError.CERTIFICATION_LIMIT_EXCEEDED +// | AuthError.CERTIFICATION_FAILED +// | AuthError.USER_ALREADY_EXISTS, +// boolean +// > +// > { +// return await this.prismaService +// .$transaction(async (tx) => { +// // 회원가입 여부 확인 +// const userExists = await this.userService.checkUserExists( +// { +// phone: target, +// }, +// tx, +// ); +// if (userExists) { +// return Left.create(AUTH_ERROR.USER_ALREADY_EXISTS()); +// } - // 인증번호 발송 횟수 제한 - const checkCertificationCodeCount = - await this.checkCertificationCodeCount(target, type, tx); - if (checkCertificationCodeCount.isLeft()) { - return checkCertificationCodeCount; - } - await this.createCertificationCode(target, code, type, tx); - const sms = await this.smsService.send(target, code); - if (!sms) { - throw new Error('SMS 전송에 실패했습니다.'); - } - return Right.create(true); - }) - .catch(() => { - this.logger.error(`인증번호 발송에 실패했습니다: ${target} ${code}`); - return Left.create( - AUTH_ERROR.CERTIFICATION_FAILED('인증번호 발송 실패'), - ); - }); - } +// // 인증번호 발송 횟수 제한 +// const checkCertificationCodeCount = +// await this.checkCertificationCodeCount(target, type, tx); +// if (checkCertificationCodeCount.isLeft()) { +// return checkCertificationCodeCount; +// } +// await this.createCertificationCode(target, code, type, tx); +// const sms = await this.smsService.send(target, code); +// if (!sms) { +// throw new Error('SMS 전송에 실패했습니다.'); +// } +// return Right.create(true); +// }) +// .catch(() => { +// this.logger.error(`인증번호 발송에 실패했습니다: ${target} ${code}`); +// return Left.create( +// AUTH_ERROR.CERTIFICATION_FAILED('인증번호 발송 실패'), +// ); +// }); +// } - async verifyCertificationCode( - target: string, - code: string, - type: CERTIFICATION_TYPE, - ): Promise< - Either< - | AuthError.CERTIFICATION_INVALID - | AuthError.CERTIFICATION_EXPIRED - | AuthError.CERTIFICATION_NOT_FOUND - | AuthError.CERTIFICATION_ALREADY_VERIFIED, - { cetificationId: string } - > - > { - return await this.prismaService - .$transaction(async (tx) => { - const certificationCode = await this.certificationCodeRepo.findOne( - { - target, - code, - targetType: this.targetType, - type, - }, - tx, - ); - if (!certificationCode) { - return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); - } - if (certificationCode.status === 'VERIFIED') { - return Left.create(AUTH_ERROR.CERTIFICATION_ALREADY_VERIFIED()); - } +// async verifyCertificationCode( +// target: string, +// code: string, +// type: CERTIFICATION_TYPE, +// ): Promise< +// Either< +// | AuthError.CERTIFICATION_INVALID +// | AuthError.CERTIFICATION_EXPIRED +// | AuthError.CERTIFICATION_NOT_FOUND +// | AuthError.CERTIFICATION_ALREADY_VERIFIED, +// { cetificationId: string } +// > +// > { +// return await this.prismaService +// .$transaction(async (tx) => { +// const certificationCode = await this.certificationCodeRepo.findOne( +// { +// target, +// code, +// targetType: this.targetType, +// type, +// }, +// tx, +// ); +// if (!certificationCode) { +// return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); +// } +// if (certificationCode.status === 'VERIFIED') { +// return Left.create(AUTH_ERROR.CERTIFICATION_ALREADY_VERIFIED()); +// } - if (certificationCode.expiredAt < new Date()) { - await this.certificationCodeRepo.updateManyStatus( - { - target, - status: 'PENDING', - expiredAt: { - lte: new Date(), - }, - }, - 'EXPIRED', - tx, - ); - return Left.create(AUTH_ERROR.CERTIFICATION_EXPIRED()); - } - await this.certificationCodeRepo.updateManyStatus( - { - target, - code, - targetType: this.targetType, - type, - }, - 'VERIFIED', - tx, - ); - return Right.create({ cetificationId: certificationCode.id }); - }) - .catch(() => { - this.logger.error(`인증번호 검증에 실패했습니다: ${target} ${code}`); - return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); - }); - } +// if (certificationCode.expiredAt < new Date()) { +// await this.certificationCodeRepo.updateManyStatus( +// { +// target, +// status: 'PENDING', +// expiredAt: { +// lte: new Date(), +// }, +// }, +// 'EXPIRED', +// tx, +// ); +// return Left.create(AUTH_ERROR.CERTIFICATION_EXPIRED()); +// } +// await this.certificationCodeRepo.updateManyStatus( +// { +// target, +// code, +// targetType: this.targetType, +// type, +// }, +// 'VERIFIED', +// tx, +// ); +// return Right.create({ cetificationId: certificationCode.id }); +// }) +// .catch(() => { +// this.logger.error(`인증번호 검증에 실패했습니다: ${target} ${code}`); +// return Left.create(AUTH_ERROR.CERTIFICATION_INVALID()); +// }); +// } - ////////////////////////// - // Private Methods - private async checkCertificationCodeCount( - target: string, - type: CERTIFICATION_TYPE, - tx?: PrismaTxType, - ) { - const ONE_DAY_IN_MS = 1000 * 60 * 60 * 24; - const MAX_DAILY_CODES = 5; - const todayCodes = await this.certificationCodeRepo.findMany( - { - target, - targetType: this.targetType, - type, - createdAt: { - gte: new Date(Date.now() - ONE_DAY_IN_MS), - lte: new Date(), - }, - }, - tx, - ); - if (todayCodes.length >= MAX_DAILY_CODES) { - this.logger.error( - `인증번호 발송 횟수 초과: ${target} ${todayCodes.length}`, - ); - return Left.create(AUTH_ERROR.CERTIFICATION_LIMIT_EXCEEDED()); - } - return Right.create(true); - } +// ////////////////////////// +// // Private Methods +// private async checkCertificationCodeCount( +// target: string, +// type: CERTIFICATION_TYPE, +// tx?: PrismaTxType, +// ) { +// const ONE_DAY_IN_MS = 1000 * 60 * 60 * 24; +// const MAX_DAILY_CODES = 5; +// const todayCodes = await this.certificationCodeRepo.findMany( +// { +// target, +// targetType: this.targetType, +// type, +// createdAt: { +// gte: new Date(Date.now() - ONE_DAY_IN_MS), +// lte: new Date(), +// }, +// }, +// tx, +// ); +// if (todayCodes.length >= MAX_DAILY_CODES) { +// this.logger.error( +// `인증번호 발송 횟수 초과: ${target} ${todayCodes.length}`, +// ); +// return Left.create(AUTH_ERROR.CERTIFICATION_LIMIT_EXCEEDED()); +// } +// return Right.create(true); +// } - private async createCertificationCode( - target: string, - code: string, - type: CERTIFICATION_TYPE, - tx?: PrismaTxType, - ) { - const FIVE_MINUTES_IN_MS = 1000 * 60 * 5; - await this.certificationCodeRepo.updateManyStatus( - { - target, - status: { - in: ['PENDING', 'VERIFIED'], - }, - }, - 'EXPIRED', - tx, - ); - await this.certificationCodeRepo.create( - { - code, - target, - status: 'PENDING', - expiredAt: new Date(Date.now() + FIVE_MINUTES_IN_MS), /// 3분 - targetType: this.targetType, - type, - }, - tx, - ); - } -} +// private async createCertificationCode( +// target: string, +// code: string, +// type: CERTIFICATION_TYPE, +// tx?: PrismaTxType, +// ) { +// const FIVE_MINUTES_IN_MS = 1000 * 60 * 5; +// await this.certificationCodeRepo.updateManyStatus( +// { +// target, +// status: { +// in: ['PENDING', 'VERIFIED'], +// }, +// }, +// 'EXPIRED', +// tx, +// ); +// await this.certificationCodeRepo.create( +// { +// code, +// target, +// status: 'PENDING', +// expiredAt: new Date(Date.now() + FIVE_MINUTES_IN_MS), /// 3분 +// targetType: this.targetType, +// type, +// }, +// tx, +// ); +// } +// } diff --git a/src/controller/car/car.controller.ts b/src/controller/car/car.controller.ts index 2ceed55..744685c 100644 --- a/src/controller/car/car.controller.ts +++ b/src/controller/car/car.controller.ts @@ -1,38 +1,37 @@ -import { JwtPayload } from '@/auth/interface/auth.service.interface'; -import { CarService } from '@/providers/car/car.service'; -import { CurrentUser } from '@common/decorator/CurrentUser'; -import { LoginOnly } from '@common/decorator/LoginOnly'; -import { TypedBody, TypedRoute } from '@nestia/core'; -import { Controller } from '@nestjs/common'; -import { Car } from '@type/car'; +// import { JwtPayload } from '@/auth/interface/auth.service.interface'; +// import { CarService } from '@/providers/car/car.service'; +// import { CurrentUser } from '@common/decorator/CurrentUser'; +// import { TypedBody, TypedRoute } from '@nestia/core'; +// import { Controller } from '@nestjs/common'; +// import { Car } from '@type/car'; -@Controller('car') -export class CarController { - constructor(private readonly carService: CarService) {} +// @Controller('car') +// export class CarController { +// constructor(private readonly carService: CarService) {} - @TypedRoute.Get('/') - @LoginOnly() - async getMyCar(@CurrentUser() user: JwtPayload) { - return this.carService.getMyCarList(user); - } +// @TypedRoute.Get('/') +// // @LoginOnly() +// async getMyCar(@CurrentUser() user: JwtPayload) { +// return this.carService.getMyCarList(user); +// } - @TypedRoute.Post('/') - @LoginOnly() - async create( - @CurrentUser() user: JwtPayload, - @TypedBody() dto: Car.Create.Request.Dto, - ) { - const result = await this.carService.create(dto, user); +// @TypedRoute.Post('/') +// // @LoginOnly() +// async create( +// @CurrentUser() user: JwtPayload, +// @TypedBody() dto: Car.Create.Request.Dto, +// ) { +// const result = await this.carService.create(dto, user); - return result; - } +// return result; +// } - // @TypedRoute.Patch('/:id') - // @LoginOnly() - // async update() {} +// // @TypedRoute.Patch('/:id') +// // @LoginOnly() +// // async update() {} - // /// soft delete를 사용하기에 delete는 put으로 대체 - // @TypedRoute.Put('/:id') - // @LoginOnly() - // async delete() {} -} +// // /// soft delete를 사용하기에 delete는 put으로 대체 +// // @TypedRoute.Put('/:id') +// // @LoginOnly() +// // async delete() {} +// } diff --git a/src/controller/driving/driving.controller.ts b/src/controller/driving/driving.controller.ts index 31f33be..aaeae80 100644 --- a/src/controller/driving/driving.controller.ts +++ b/src/controller/driving/driving.controller.ts @@ -1,33 +1,33 @@ -import { JwtPayload } from '@/auth/interface/auth.service.interface'; -import { DrivingService } from '@/providers/driving/driving.service'; -import { CurrentUser } from '@common/decorator/CurrentUser'; -import { LoginOnly } from '@common/decorator/LoginOnly'; -import { TypedBody, TypedRoute } from '@nestia/core'; -import { Controller } from '@nestjs/common'; -import { Driving } from '@type/driving'; +// import { JwtPayload } from '@/auth/interface/auth.service.interface'; +// import { DrivingService } from '@/providers/driving/driving.service'; +// import { CurrentUser } from '@common/decorator/CurrentUser'; +// import { LoginOnly } from '@common/decorator/LoginOnly'; +// import { TypedBody, TypedRoute } from '@nestia/core'; +// import { Controller } from '@nestjs/common'; +// import { Driving } from '@type/driving'; -@Controller() -export class DrivingController { - constructor(private readonly drivingService: DrivingService) {} +// @Controller() +// export class DrivingController { +// constructor(private readonly drivingService: DrivingService) {} - // 운행 목록 - @TypedRoute.Get('/driving') - @LoginOnly() - async getMyDrivingList() {} +// // 운행 목록 +// @TypedRoute.Get('/driving') +// @LoginOnly() +// async getMyDrivingList() {} - // 운행 시작 - @TypedRoute.Post('/driving') - @LoginOnly() - async start( - @TypedBody() dto: Driving.Start.Request.Dto, - @CurrentUser() user: JwtPayload, - ) { - dto; - user; - } +// // 운행 시작 +// @TypedRoute.Post('/driving') +// @LoginOnly() +// async start( +// @TypedBody() dto: Driving.Start.Request.Dto, +// @CurrentUser() user: JwtPayload, +// ) { +// dto; +// user; +// } - // 운행 상태 변경 - @TypedRoute.Patch('/driving/:id') - @LoginOnly() - async updateStatus() {} -} +// // 운행 상태 변경 +// @TypedRoute.Patch('/driving/:id') +// @LoginOnly() +// async updateStatus() {} +// } diff --git a/src/module/car.module.ts b/src/module/car.module.ts index ef50c89..7b5abd2 100644 --- a/src/module/car.module.ts +++ b/src/module/car.module.ts @@ -1,10 +1,10 @@ -import { CarController } from '@/controller/car/car.controller'; -import { CarService } from '@/providers/car/car.service'; -import { CarRepository } from '@/repository/car/car.respository'; -import { Module } from '@nestjs/common'; +// import { CarController } from '@/controller/car/car.controller'; +// import { CarService } from '@/providers/car/car.service'; +// import { CarRepository } from '@/repository/car/car.respository'; +// import { Module } from '@nestjs/common'; -@Module({ - controllers: [CarController], - providers: [CarRepository, CarService], -}) -export class CarModule {} +// @Module({ +// controllers: [CarController], +// providers: [CarRepository, CarService], +// }) +// export class CarModule {} diff --git a/src/module/driving.module.ts b/src/module/driving.module.ts index 66fa5ff..9bd95b7 100644 --- a/src/module/driving.module.ts +++ b/src/module/driving.module.ts @@ -1,8 +1,8 @@ -import { DrivingService } from '@/providers/driving/driving.service'; -import { DrivingRepository } from '@/repository/driving/driving.repository'; -import { Module } from '@nestjs/common'; +// import { DrivingService } from '@/providers/driving/driving.service'; +// import { DrivingRepository } from '@/repository/driving/driving.repository'; +// import { Module } from '@nestjs/common'; -@Module({ - providers: [DrivingRepository, DrivingService], -}) -export class DrivingModule {} +// @Module({ +// providers: [DrivingRepository, DrivingService], +// }) +// export class DrivingModule {} diff --git a/src/module/parking.module.ts b/src/module/parking.module.ts index 81acbf6..a0a41e9 100644 --- a/src/module/parking.module.ts +++ b/src/module/parking.module.ts @@ -1,9 +1,13 @@ -import { ParkingService } from '@/providers/parking/parking.service'; +// import { ParkingService } from '@/providers/parking/parking.service'; import { ParkingRepository } from '@/repository/parking/parking.repository'; import { ParkingSnapshotRepository } from '@/repository/parking/parking.snapshot.repository'; import { Module } from '@nestjs/common'; @Module({ - providers: [ParkingRepository, ParkingSnapshotRepository, ParkingService], + providers: [ + ParkingRepository, + ParkingSnapshotRepository, + // ParkingService + ], }) export class ParkingModule {} diff --git a/src/providers/car/car.service.ts b/src/providers/car/car.service.ts index b857103..c576c32 100644 --- a/src/providers/car/car.service.ts +++ b/src/providers/car/car.service.ts @@ -1,82 +1,82 @@ -import { JwtPayload } from '@/auth/interface/auth.service.interface'; -import { CarRepository } from '@/repository/car/car.respository'; -import { PrismaService } from '@common/prisma/prisma.service'; -import { Left, Right } from '@common/util/Either'; -import { BAD_REQUEST_ERROR, NOT_FOUND_ERROR } from '@common/util/Error'; -import { Injectable } from '@nestjs/common'; -import { Car } from '@type/car'; -import { v4 } from 'uuid'; +// import { JwtPayload } from '@/auth/interface/auth.service.interface'; +// import { CarRepository } from '@/repository/car/car.respository'; +// import { PrismaService } from '@common/prisma/prisma.service'; +// import { Left, Right } from '@common/util/Either'; +// import { BAD_REQUEST_ERROR, NOT_FOUND_ERROR } from '@common/util/Error'; +// import { Injectable } from '@nestjs/common'; +// import { Car } from '@type/car'; +// import { v4 } from 'uuid'; -@Injectable() -export class CarService { - constructor( - private readonly carRepository: CarRepository, - private readonly prismaService: PrismaService, - ) {} +// @Injectable() +// export class CarService { +// constructor( +// private readonly carRepository: CarRepository, +// private readonly prismaService: PrismaService, +// ) {} - async create(dto: Car.Create.Request.Dto, user: JwtPayload) { - const { id } = user; - const checkExist = await this.carRepository.findOne({ - number: dto.number, - status: 'ACTIVE', - }); - if (checkExist) - return Left.create(BAD_REQUEST_ERROR('CAR_ALREADY_EXISTS')()); +// async create(dto: Car.Create.Request.Dto, user: JwtPayload) { +// const { id } = user; +// const checkExist = await this.carRepository.findOne({ +// number: dto.number, +// status: 'ACTIVE', +// }); +// if (checkExist) +// return Left.create(BAD_REQUEST_ERROR('CAR_ALREADY_EXISTS')()); - const newCar = await this.carRepository.create({ - ...dto, - ownerId: id, - status: 'ACTIVE', - snapshots: { - create: { - id: v4(), - ownerId: id, - status: 'ACTIVE', - ...dto, - }, - }, - }); +// const newCar = await this.carRepository.create({ +// ...dto, +// ownerId: id, +// status: 'ACTIVE', +// snapshots: { +// create: { +// id: v4(), +// ownerId: id, +// status: 'ACTIVE', +// ...dto, +// }, +// }, +// }); - return Right.create(newCar); - } +// return Right.create(newCar); +// } - async getMyCarList(user: JwtPayload) { - return this.prismaService.car.findMany({ - where: { ownerId: user.id, status: 'ACTIVE' }, - include: { - drivings: { - where: { - userId: user.id, - }, - include: { - parking: true, - }, - }, - }, - }); - } +// async getMyCarList(user: JwtPayload) { +// return this.prismaService.car.findMany({ +// where: { ownerId: user.id, status: 'ACTIVE' }, +// include: { +// drivings: { +// where: { +// userId: user.id, +// }, +// include: { +// parking: true, +// }, +// }, +// }, +// }); +// } - // 폐차처리 - async deleteCar(id: string, user: JwtPayload) { - const car = await this.carRepository.findOne({ id, ownerId: user.id }); - if (!car) return Left.create(NOT_FOUND_ERROR('CAR_NOT_FOUND')()); - await this.prismaService.$transaction(async (tx) => { - const updatedCar = await this.carRepository.update( - { id }, - { status: 'SCRAPPED' }, - tx, - ); - tx.carSnapshot.create({ - data: { - id: v4(), - carId: id, - ownerId: user.id, - status: 'SCRAPPED', - type: updatedCar.type, - number: updatedCar.number, - }, - }); - }); - return Right.create('SUCCESS'); - } -} +// // 폐차처리 +// async deleteCar(id: string, user: JwtPayload) { +// const car = await this.carRepository.findOne({ id, ownerId: user.id }); +// if (!car) return Left.create(NOT_FOUND_ERROR('CAR_NOT_FOUND')()); +// await this.prismaService.$transaction(async (tx) => { +// const updatedCar = await this.carRepository.update( +// { id }, +// { status: 'SCRAPPED' }, +// tx, +// ); +// tx.carSnapshot.create({ +// data: { +// id: v4(), +// carId: id, +// ownerId: user.id, +// status: 'SCRAPPED', +// type: updatedCar.type, +// number: updatedCar.number, +// }, +// }); +// }); +// return Right.create('SUCCESS'); +// } +// } diff --git a/src/providers/driving/driving.service.ts b/src/providers/driving/driving.service.ts index 2a892bf..c84113a 100644 --- a/src/providers/driving/driving.service.ts +++ b/src/providers/driving/driving.service.ts @@ -1,84 +1,84 @@ -import { JwtPayload } from '@/auth/interface/auth.service.interface'; -import { CAR_ERROR } from '@/constant/error/car.error'; -import { RENTAL_ERROR } from '@/constant/error/rental.error'; -import { DrivingRepository } from '@/repository/driving/driving.repository'; -import { PrismaService } from '@common/prisma/prisma.service'; -import { Left, Right } from '@common/util/Either'; -import { Injectable } from '@nestjs/common'; -import { Driving } from '@type/driving'; -import { v4 } from 'uuid'; +// import { JwtPayload } from '@/auth/interface/auth.service.interface'; +// import { CAR_ERROR } from '@/constant/error/car.error'; +// import { RENTAL_ERROR } from '@/constant/error/rental.error'; +// import { DrivingRepository } from '@/repository/driving/driving.repository'; +// import { PrismaService } from '@common/prisma/prisma.service'; +// import { Left, Right } from '@common/util/Either'; +// import { Injectable } from '@nestjs/common'; +// import { Driving } from '@type/driving'; +// import { v4 } from 'uuid'; -@Injectable() -export class DrivingService { - constructor( - private readonly prismaService: PrismaService, - private readonly drivingRepository: DrivingRepository, - ) {} +// @Injectable() +// export class DrivingService { +// constructor( +// private readonly prismaService: PrismaService, +// private readonly drivingRepository: DrivingRepository, +// ) {} - // 운행 시작 - async startDriving(dto: Driving.Start.Request.Dto, user: JwtPayload) { - switch (dto.type) { - case 'MY_CAR': - return this.startDrivingMyCar(dto, user.id); - case 'RENT_CAR': - return this.startDrivingRentCar(dto, user.id); - default: - break; - } - } +// // 운행 시작 +// async startDriving(dto: Driving.Start.Request.Dto, user: JwtPayload) { +// switch (dto.type) { +// case 'MY_CAR': +// return this.startDrivingMyCar(dto, user.id); +// case 'RENT_CAR': +// return this.startDrivingRentCar(dto, user.id); +// default: +// break; +// } +// } - async startDrivingMyCar(dto: Driving.Start.Request.MyCarDto, userId: string) { - dto; - userId; - const { carId } = dto; - const isExistMyCar = await this.prismaService.car.findUnique({ - where: { - id: carId, - ownerId: userId, - }, - }); - if (!isExistMyCar) { - return Left.create(CAR_ERROR.CAR_NOT_FOUND('존재하지 않는 차량입니다.')); - } +// async startDrivingMyCar(dto: Driving.Start.Request.MyCarDto, userId: string) { +// dto; +// userId; +// const { carId } = dto; +// const isExistMyCar = await this.prismaService.car.findUnique({ +// where: { +// id: carId, +// ownerId: userId, +// }, +// }); +// if (!isExistMyCar) { +// return Left.create(CAR_ERROR.CAR_NOT_FOUND('존재하지 않는 차량입니다.')); +// } - const newDriving = await this.drivingRepository.create({ - id: v4(), - userId, - carId, - }); +// const newDriving = await this.drivingRepository.create({ +// id: v4(), +// userId, +// carId, +// }); - return Right.create(newDriving); - } +// return Right.create(newDriving); +// } - async startDrivingRentCar( - dto: Driving.Start.Request.RentCarDto, - userId: string, - ) { - dto; - userId; +// async startDrivingRentCar( +// dto: Driving.Start.Request.RentCarDto, +// userId: string, +// ) { +// dto; +// userId; - const { rentalId } = dto; - const rentalInfo = await this.prismaService.rental.findUnique({ - where: { - id: rentalId, - userId, - }, - }); - if (!rentalInfo) { - return Left.create( - RENTAL_ERROR.RENTAL_NOT_FOUND('대여 정보가 존재하지 않습니다.'), - ); - } - const newDriving = await this.drivingRepository.create({ - id: v4(), - userId, - carId: rentalInfo.carId, - rentalId, - }); - return Right.create(newDriving); - } +// const { rentalId } = dto; +// const rentalInfo = await this.prismaService.rental.findUnique({ +// where: { +// id: rentalId, +// userId, +// }, +// }); +// if (!rentalInfo) { +// return Left.create( +// RENTAL_ERROR.RENTAL_NOT_FOUND('대여 정보가 존재하지 않습니다.'), +// ); +// } +// const newDriving = await this.drivingRepository.create({ +// id: v4(), +// userId, +// carId: rentalInfo.carId, +// rentalId, +// }); +// return Right.create(newDriving); +// } - async endDriving() {} +// async endDriving() {} - async getMyDrivingList() {} -} +// async getMyDrivingList() {} +// } diff --git a/src/providers/parking/parking.service.ts b/src/providers/parking/parking.service.ts index ced504f..61db8c4 100644 --- a/src/providers/parking/parking.service.ts +++ b/src/providers/parking/parking.service.ts @@ -1,46 +1,46 @@ -import { JwtPayload } from '@/auth/interface/auth.service.interface'; -import { PrismaService } from '@common/prisma/prisma.service'; -import { Injectable } from '@nestjs/common'; -import { Parking } from '@type/parking'; -import { v4 } from 'uuid'; -import { ParkingRepository } from '../../repository/parking/parking.repository'; -import { ParkingSnapshotRepository } from '../../repository/parking/parking.snapshot.repository'; +// import { JwtPayload } from '@/auth/interface/auth.service.interface'; +// import { PrismaService } from '@common/prisma/prisma.service'; +// import { Injectable } from '@nestjs/common'; +// import { Parking } from '@type/parking'; +// import { v4 } from 'uuid'; +// import { ParkingRepository } from '../../repository/parking/parking.repository'; +// import { ParkingSnapshotRepository } from '../../repository/parking/parking.snapshot.repository'; -@Injectable() -export class ParkingService { - constructor( - private readonly parkingRepository: ParkingRepository, - private readonly parkingSnapshotService: ParkingSnapshotRepository, - private readonly prismaService: PrismaService, - ) {} +// @Injectable() +// export class ParkingService { +// constructor( +// private readonly parkingRepository: ParkingRepository, +// private readonly parkingSnapshotService: ParkingSnapshotRepository, +// private readonly prismaService: PrismaService, +// ) {} - async create(dto: Parking.Create.Request.Dto, user: JwtPayload) { - dto; - user; +// async create(dto: Parking.Create.Request.Dto, user: JwtPayload) { +// dto; +// user; - const checkDriving = await this.prismaService.driving.findUnique({ - where: { - id: dto.drivingId, - userId: user.id, - }, - }); - if (!checkDriving) { - // TODO: ERROR 작성 - throw new Error('주행 정보가 존재하지 않습니다.'); - } +// const checkDriving = await this.prismaService.driving.findUnique({ +// where: { +// id: dto.drivingId, +// userId: user.id, +// }, +// }); +// if (!checkDriving) { +// // TODO: ERROR 작성 +// throw new Error('주행 정보가 존재하지 않습니다.'); +// } - const { latitude, longitude, address } = dto; - const parking = await this.parkingRepository.create({ - id: v4(), - carId: checkDriving.carId, - drivingId: dto.drivingId, - location: address, - latitude, - longitude, - status: 'PARKING', - startDate: dto.startDate, - endDate: dto.endDate, - }); - return parking; - } -} +// const { latitude, longitude, address } = dto; +// const parking = await this.parkingRepository.create({ +// id: v4(), +// carId: checkDriving.carId, +// drivingId: dto.drivingId, +// location: address, +// latitude, +// longitude, +// status: 'PARKED', +// startDate: dto.startDate, +// endDate: dto.endDate, +// }); +// return parking; +// } +// } diff --git a/uncar/bruno.json b/uncar/bruno.json new file mode 100644 index 0000000..a60711f --- /dev/null +++ b/uncar/bruno.json @@ -0,0 +1,6 @@ +{ + "version": "1", + "name": "uncar", + "type": "collection", + "ignore": ["node_modules", ".git"] +}