From ce48890a663f32da294bb7d9226a313746b00a7e Mon Sep 17 00:00:00 2001 From: sbriat Date: Wed, 16 Aug 2023 12:28:20 +0200 Subject: [PATCH 01/24] refactor to ddh, first commit --- .env.dist | 30 +- ci/.env.ci | 5 +- old/app.constants.ts | 2 + old/app.module.ts | 66 + old/interfaces/message-publisher.ts | 3 + old/modules/ad/ad.constants.ts | 4 + old/modules/ad/ad.module.ts | 61 + .../adapters/primaries/ad-messager.service.ts | 25 +- .../ad/adapters/secondaries/ad.repository.ts | 0 .../secondaries/default-params.provider.ts | 0 .../adapters/secondaries/message-publisher.ts | 16 + .../adapters/secondaries/timezone-finder.ts | 0 .../modules/ad/commands/create-ad.command.ts | 0 .../ad/domain/dtos/create-ad.request.ts | 2 +- .../domain/dtos/has-truthy-with.validator.ts | 0 {src => old}/modules/ad/domain/entities/ad.ts | 0 .../modules/ad/domain/entities/geography.ts | 22 +- .../ad/domain/entities/time-converter.ts | 0 .../interfaces/params-provider.interface.ts | 0 .../ad/domain/types/default-params.type.ts | 0 .../modules/ad/domain/types/frequency.enum.ts | 0 .../modules/ad/domain/types/role.enum.ts | 0 .../ad/domain/usecases/create-ad.usecase.ts | 20 +- {src => old}/modules/ad/mappers/ad.profile.ts | 0 .../tests/integration/ad.repository.spec.ts | 0 .../default-params.provider.spec.ts | 0 .../secondaries/message-publisher.spec.ts | 36 + .../secondaries/timezone-finder.spec.ts | 0 .../unit/domain/create-ad.usecase.spec.ts | 24 +- .../ad/tests/unit/domain/geography.spec.ts | 0 .../tests/unit/domain/time-converter.spec.ts | 0 .../secondaries/prisma.repository.abstract.ts | 0 .../adapters/secondaries/prisma.service.ts | 0 .../modules/database/database.module.ts | 0 .../database/domain/database.repository.ts | 0 .../database/exceptions/database.exception.ts | 0 .../interfaces/collection.interface.ts | 0 .../interfaces/repository.interface.ts | 0 .../tests/unit/prisma-repository.spec.ts | 0 .../secondaries/geo-timezone-finder.ts | 0 .../adapters/secondaries/geodesic.ts | 0 .../adapters/secondaries/georouter-creator.ts | 2 +- .../secondaries/graphhopper-georouter.ts | 4 +- .../secondaries/postgres-direction-encoder.ts | 0 .../geography/domain/entities/coordinate.ts | 0 .../geography/domain/entities/route.ts | 0 .../domain/entities/spacetime-point.ts | 0 .../interfaces/direction-encoder.interface.ts | 0 .../domain/interfaces/geodesic.interface.ts | 0 .../interfaces/georouter-creator.interface.ts | 0 .../domain/interfaces/georouter.interface.ts | 0 .../interfaces/timezone-finder.interface.ts | 0 .../domain/types/georouter-settings.type.ts | 0 .../geography/domain/types/named-route.ts | 0 .../geography/domain/types/path.type.ts | 6 + .../geography/domain/types/point-type.enum.ts | 0 .../geography/domain/types/point.type.ts | 0 .../geography/domain/types/timezoner.ts | 0 .../exceptions/geography.exception.ts | 0 .../modules/geography/geography.module.ts | 0 .../geography/tests/unit/coordinate.spec.ts | 0 .../tests/unit/geo-timezone-finder.spec.ts | 0 .../geography/tests/unit/geodesic.spec.ts | 0 .../tests/unit/georouter-creator.spec.ts | 0 .../tests/unit/graphhopper-georouter.spec.ts | 0 .../unit/postgres-direction-encoder.spec.ts | 0 .../geography/tests/unit/route.spec.ts | 0 .../primaries/health-server.controller.ts | 10 +- .../adapters/primaries/health.controller.ts | 37 + .../health/adapters/primaries/health.proto | 0 .../adapters/secondaries/message-publisher.ts | 16 + .../interfaces/check-repository.interface.ts | 3 + .../repositories.health-indicator.usecase.ts | 33 + old/modules/health/health.module.ts | 28 + .../tests/unit/message-publisher.spec.ts | 36 + ...ositories.health-indicator.usecase.spec.ts | 29 +- .../adapters/primaries/matcher.controller.ts | 0 .../matcher/adapters/primaries/matcher.proto | 0 .../secondaries/default-params.provider.ts | 0 .../matcher/adapters/secondaries/geodesic.ts | 0 .../adapters/secondaries/georouter-creator.ts | 0 .../secondaries/graphhopper-georouter.ts | 0 .../adapters/secondaries/match.presenter.ts | 0 .../adapters/secondaries/message-publisher.ts | 16 + .../adapters/secondaries/time-converter.ts | 0 .../adapters/secondaries/timezone-finder.ts | 0 .../matcher/domain/dtos/match.request.ts | 0 .../domain/entities/ecosystem/actor.ts | 0 .../matcher/domain/entities/ecosystem/ad.ts | 0 .../entities/ecosystem/algorithm-settings.ts | 0 .../domain/entities/ecosystem/geography.ts | 0 .../domain/entities/ecosystem/match.ts | 0 .../entities/ecosystem/matcher-route.ts | 0 .../domain/entities/ecosystem/named-route.ts | 0 .../domain/entities/ecosystem/requirement.ts | 0 .../entities/ecosystem/spacetime-point.ts | 0 .../matcher/domain/entities/ecosystem/time.ts | 0 .../domain/entities/ecosystem/timezoner.ts | 0 .../domain/entities/ecosystem/waypoint.ts | 0 .../domain/entities/engine/candidate.ts | 0 .../factory/algorithm-factory-creator.ts | 0 .../factory/algorithm-factory.abstract.ts | 0 .../domain/entities/engine/factory/classic.ts | 0 .../matcher/domain/entities/engine/matcher.ts | 0 .../classic-waypoint.completer.processor.ts | 0 .../processor/completer/completer.abstract.ts | 0 .../completer/journey.completer.processor.ts | 0 .../completer/route.completer.processor.ts | 0 .../processor/filter/filter.abstract.ts | 0 .../geofilter/classic.filter.processor.ts | 0 .../timefilter/classic.filter.processor.ts | 0 .../engine/processor/processor.abstract.ts | 0 .../engine/selector/classic.selector.ts | 0 .../engine/selector/selector.abstract.ts | 0 .../domain/interfaces/ad-request.interface.ts | 0 .../algorithm-settings-request.interface.ts | 0 .../interfaces/geography-request.interface.ts | 0 .../interfaces/georouter-creator.interface.ts | 0 .../domain/interfaces/georouter.interface.ts | 0 .../requirement-request.interface.ts | 0 .../interfaces/time-converter.interface.ts | 0 .../interfaces/time-request.interface.ts | 0 .../matcher/domain/types/actor.type..ts | 0 .../matcher/domain/types/algorithm.enum.ts | 0 .../modules/matcher/domain/types/day.type.ts | 0 .../matcher/domain/types/days.const.ts | 0 .../types/default-algorithm-settings.type.ts | 0 .../domain/types/default-params.type.ts | 0 .../domain/types/georouter-settings.type.ts | 0 .../domain/types/margin-durations.type.ts | 0 .../modules/matcher/domain/types/mode.enum.ts | 0 .../matcher}/domain/types/path.type.ts | 0 .../modules/matcher/domain/types/role.enum.ts | 0 .../matcher/domain/types/schedule.type.ts | 0 .../modules/matcher/domain/types/step.enum.ts | 0 .../domain/types/time-schedule.type.ts | 0 .../modules/matcher/domain/types/waypoint.ts | 0 .../matcher/domain/usecases/match.usecase.ts | 11 +- .../matcher/exceptions/matcher.exception.ts | 0 .../modules/matcher/mappers/match.profile.ts | 0 .../modules/matcher/matcher.module.ts | 28 +- .../modules/matcher/queries/match.query.ts | 0 .../default-params.provider.spec.ts | 0 .../adapters/secondaries/geodesic.spec.ts | 0 .../secondaries/georouter-creator.spec.ts | 0 .../secondaries/graphhopper-georouter.spec.ts | 0 .../secondaries/message-publisher.spec.ts | 36 + .../secondaries/timezone-finder.spec.ts | 0 .../unit/domain/ecosystem/geography.spec.ts | 0 .../domain/ecosystem/matcher-route.spec.ts | 0 .../unit/domain/ecosystem/person.spec.ts | 0 .../tests/unit/domain/ecosystem/time.spec.ts | 0 .../engine/algorithm-factory-creator.spec.ts | 0 .../engine/algorithm-factory.abstract.spec.ts | 0 .../engine/classic-algorithm-factory.spec.ts | 0 .../classic-geo.filter.processor.spec.ts | 0 .../classic-time.filter.processor.spec.ts | 0 ...assic-waypoint.completer.processor.spec.ts | 0 .../domain/engine/classic.selector.spec.ts | 0 .../domain/engine/completer.abstract.spec.ts | 0 .../domain/engine/filter.abstract.spec.ts | 0 .../journey.completer.processor.spec.ts | 0 .../tests/unit/domain/engine/matcher.spec.ts | 0 .../domain/engine/processor.abstract.spec.ts | 0 .../engine/route.completer.processor.spec.ts | 0 .../domain/engine/selector.abstract.spec.ts | 0 .../tests/unit/domain/match.usecase.spec.ts | 8 +- .../tests/unit/queries/match.query.spec.ts | 0 .../modules/utils/exception-code.enum.ts | 0 .../utils/pipes/rpc.validation-pipe.ts | 0 .../unit/rpc-validation-pipe.usecase.spec.ts | 0 package-lock.json | 2914 +++++++++-------- package.json | 61 +- .../20230512130750_init/migration.sql | 68 - prisma/migrations/migration_lock.toml | 3 - prisma/schema.prisma | 36 +- src/app.module.ts | 74 +- src/health.proto | 21 + src/modules/ad/ad.di-tokens.ts | 5 + src/modules/ad/ad.mapper.ts | 111 + src/modules/ad/ad.module.ts | 119 +- .../ad/adapters/secondaries/message-broker.ts | 12 - .../ad/adapters/secondaries/messager.ts | 18 - .../application/ports/ad.repository.port.ts | 4 + .../ports/default-params-provider.port.ts | 5 + .../application/ports/default-params.type.ts | 5 + .../application/ports/timezone-finder.port.ts | 3 + src/modules/ad/core/domain/ad.entity.ts | 16 + src/modules/ad/core/domain/ad.types.ts | 51 + .../schedule-item.value-object.ts | 31 + .../ad/infrastructure/ad.repository.ts | 83 + .../infrastructure/default-params-provider.ts | 14 + .../ad/infrastructure/prisma.service.ts | 15 + .../ad/infrastructure/timezone-finder.ts | 16 + .../adapters/secondaries/messager.spec.ts | 47 - .../adapters/primaries/health.controller.ts | 34 - .../adapters/secondaries/message-broker.ts | 12 - .../health/adapters/secondaries/messager.ts | 18 - .../prisma.health-indicator.usecase.ts | 25 - src/modules/health/health.module.ts | 34 - .../health/tests/unit/messager.spec.ts | 47 - .../adapters/secondaries/message-broker.ts | 12 - .../matcher/adapters/secondaries/messager.ts | 18 - src/modules/matcher/domain/types/path.type.ts | 6 - .../adapters/secondaries/messager.spec.ts | 47 - src/modules/messager/messager.di-tokens.ts | 1 + src/modules/messager/messager.module.ts | 36 + tsconfig.json | 7 +- 208 files changed, 2596 insertions(+), 2052 deletions(-) create mode 100644 old/app.constants.ts create mode 100644 old/app.module.ts create mode 100644 old/interfaces/message-publisher.ts create mode 100644 old/modules/ad/ad.constants.ts create mode 100644 old/modules/ad/ad.module.ts rename src/modules/ad/adapters/primaries/ad-messager.controller.ts => old/modules/ad/adapters/primaries/ad-messager.service.ts (77%) rename {src => old}/modules/ad/adapters/secondaries/ad.repository.ts (100%) rename {src => old}/modules/ad/adapters/secondaries/default-params.provider.ts (100%) create mode 100644 old/modules/ad/adapters/secondaries/message-publisher.ts rename {src => old}/modules/ad/adapters/secondaries/timezone-finder.ts (100%) rename {src => old}/modules/ad/commands/create-ad.command.ts (100%) rename {src => old}/modules/ad/domain/dtos/create-ad.request.ts (98%) rename {src => old}/modules/ad/domain/dtos/has-truthy-with.validator.ts (100%) rename {src => old}/modules/ad/domain/entities/ad.ts (100%) rename {src => old}/modules/ad/domain/entities/geography.ts (81%) rename {src => old}/modules/ad/domain/entities/time-converter.ts (100%) rename {src => old}/modules/ad/domain/interfaces/params-provider.interface.ts (100%) rename {src => old}/modules/ad/domain/types/default-params.type.ts (100%) rename {src => old}/modules/ad/domain/types/frequency.enum.ts (100%) rename {src => old}/modules/ad/domain/types/role.enum.ts (100%) rename {src => old}/modules/ad/domain/usecases/create-ad.usecase.ts (92%) rename {src => old}/modules/ad/mappers/ad.profile.ts (100%) rename {src => old}/modules/ad/tests/integration/ad.repository.spec.ts (100%) rename {src => old}/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts (100%) create mode 100644 old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts rename {src => old}/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts (100%) rename {src => old}/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts (91%) rename {src => old}/modules/ad/tests/unit/domain/geography.spec.ts (100%) rename {src => old}/modules/ad/tests/unit/domain/time-converter.spec.ts (100%) rename {src => old}/modules/database/adapters/secondaries/prisma.repository.abstract.ts (100%) rename {src => old}/modules/database/adapters/secondaries/prisma.service.ts (100%) rename {src => old}/modules/database/database.module.ts (100%) rename {src => old}/modules/database/domain/database.repository.ts (100%) rename {src => old}/modules/database/exceptions/database.exception.ts (100%) rename {src => old}/modules/database/interfaces/collection.interface.ts (100%) rename {src => old}/modules/database/interfaces/repository.interface.ts (100%) rename {src => old}/modules/database/tests/unit/prisma-repository.spec.ts (100%) rename {src => old}/modules/geography/adapters/secondaries/geo-timezone-finder.ts (100%) rename {src => old}/modules/geography/adapters/secondaries/geodesic.ts (100%) rename {src => old}/modules/geography/adapters/secondaries/georouter-creator.ts (93%) rename {src => old}/modules/geography/adapters/secondaries/graphhopper-georouter.ts (98%) rename {src => old}/modules/geography/adapters/secondaries/postgres-direction-encoder.ts (100%) rename {src => old}/modules/geography/domain/entities/coordinate.ts (100%) rename {src => old}/modules/geography/domain/entities/route.ts (100%) rename {src => old}/modules/geography/domain/entities/spacetime-point.ts (100%) rename {src => old}/modules/geography/domain/interfaces/direction-encoder.interface.ts (100%) rename {src => old}/modules/geography/domain/interfaces/geodesic.interface.ts (100%) rename {src => old}/modules/geography/domain/interfaces/georouter-creator.interface.ts (100%) rename {src => old}/modules/geography/domain/interfaces/georouter.interface.ts (100%) rename {src => old}/modules/geography/domain/interfaces/timezone-finder.interface.ts (100%) rename {src => old}/modules/geography/domain/types/georouter-settings.type.ts (100%) rename {src => old}/modules/geography/domain/types/named-route.ts (100%) create mode 100644 old/modules/geography/domain/types/path.type.ts rename {src => old}/modules/geography/domain/types/point-type.enum.ts (100%) rename {src => old}/modules/geography/domain/types/point.type.ts (100%) rename {src => old}/modules/geography/domain/types/timezoner.ts (100%) rename {src => old}/modules/geography/exceptions/geography.exception.ts (100%) rename {src => old}/modules/geography/geography.module.ts (100%) rename {src => old}/modules/geography/tests/unit/coordinate.spec.ts (100%) rename {src => old}/modules/geography/tests/unit/geo-timezone-finder.spec.ts (100%) rename {src => old}/modules/geography/tests/unit/geodesic.spec.ts (100%) rename {src => old}/modules/geography/tests/unit/georouter-creator.spec.ts (100%) rename {src => old}/modules/geography/tests/unit/graphhopper-georouter.spec.ts (100%) rename {src => old}/modules/geography/tests/unit/postgres-direction-encoder.spec.ts (100%) rename {src => old}/modules/geography/tests/unit/route.spec.ts (100%) rename {src => old}/modules/health/adapters/primaries/health-server.controller.ts (67%) create mode 100644 old/modules/health/adapters/primaries/health.controller.ts rename {src => old}/modules/health/adapters/primaries/health.proto (100%) create mode 100644 old/modules/health/adapters/secondaries/message-publisher.ts create mode 100644 old/modules/health/domain/interfaces/check-repository.interface.ts create mode 100644 old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts create mode 100644 old/modules/health/health.module.ts create mode 100644 old/modules/health/tests/unit/message-publisher.spec.ts rename src/modules/health/tests/unit/prisma.health-indicator.usecase.spec.ts => old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts (54%) rename {src => old}/modules/matcher/adapters/primaries/matcher.controller.ts (100%) rename {src => old}/modules/matcher/adapters/primaries/matcher.proto (100%) rename {src => old}/modules/matcher/adapters/secondaries/default-params.provider.ts (100%) rename {src => old}/modules/matcher/adapters/secondaries/geodesic.ts (100%) rename {src => old}/modules/matcher/adapters/secondaries/georouter-creator.ts (100%) rename {src => old}/modules/matcher/adapters/secondaries/graphhopper-georouter.ts (100%) rename {src => old}/modules/matcher/adapters/secondaries/match.presenter.ts (100%) create mode 100644 old/modules/matcher/adapters/secondaries/message-publisher.ts rename {src => old}/modules/matcher/adapters/secondaries/time-converter.ts (100%) rename {src => old}/modules/matcher/adapters/secondaries/timezone-finder.ts (100%) rename {src => old}/modules/matcher/domain/dtos/match.request.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/actor.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/ad.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/geography.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/match.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/matcher-route.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/named-route.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/requirement.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/spacetime-point.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/time.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/timezoner.ts (100%) rename {src => old}/modules/matcher/domain/entities/ecosystem/waypoint.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/candidate.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/factory/classic.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/matcher.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/processor/processor.abstract.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/selector/classic.selector.ts (100%) rename {src => old}/modules/matcher/domain/entities/engine/selector/selector.abstract.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/ad-request.interface.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/geography-request.interface.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/georouter-creator.interface.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/georouter.interface.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/requirement-request.interface.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/time-converter.interface.ts (100%) rename {src => old}/modules/matcher/domain/interfaces/time-request.interface.ts (100%) rename {src => old}/modules/matcher/domain/types/actor.type..ts (100%) rename {src => old}/modules/matcher/domain/types/algorithm.enum.ts (100%) rename {src => old}/modules/matcher/domain/types/day.type.ts (100%) rename {src => old}/modules/matcher/domain/types/days.const.ts (100%) rename {src => old}/modules/matcher/domain/types/default-algorithm-settings.type.ts (100%) rename {src => old}/modules/matcher/domain/types/default-params.type.ts (100%) rename {src => old}/modules/matcher/domain/types/georouter-settings.type.ts (100%) rename {src => old}/modules/matcher/domain/types/margin-durations.type.ts (100%) rename {src => old}/modules/matcher/domain/types/mode.enum.ts (100%) rename {src/modules/geography => old/modules/matcher}/domain/types/path.type.ts (100%) rename {src => old}/modules/matcher/domain/types/role.enum.ts (100%) rename {src => old}/modules/matcher/domain/types/schedule.type.ts (100%) rename {src => old}/modules/matcher/domain/types/step.enum.ts (100%) rename {src => old}/modules/matcher/domain/types/time-schedule.type.ts (100%) rename {src => old}/modules/matcher/domain/types/waypoint.ts (100%) rename {src => old}/modules/matcher/domain/usecases/match.usecase.ts (83%) rename {src => old}/modules/matcher/exceptions/matcher.exception.ts (100%) rename {src => old}/modules/matcher/mappers/match.profile.ts (100%) rename {src => old}/modules/matcher/matcher.module.ts (79%) rename {src => old}/modules/matcher/queries/match.query.ts (100%) rename {src => old}/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts (100%) create mode 100644 old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts rename {src => old}/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/matcher.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts (100%) rename {src => old}/modules/matcher/tests/unit/domain/match.usecase.spec.ts (95%) rename {src => old}/modules/matcher/tests/unit/queries/match.query.spec.ts (100%) rename {src => old}/modules/utils/exception-code.enum.ts (100%) rename {src => old}/modules/utils/pipes/rpc.validation-pipe.ts (100%) rename {src => old}/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts (100%) delete mode 100644 prisma/migrations/20230512130750_init/migration.sql delete mode 100644 prisma/migrations/migration_lock.toml create mode 100644 src/health.proto create mode 100644 src/modules/ad/ad.di-tokens.ts create mode 100644 src/modules/ad/ad.mapper.ts delete mode 100644 src/modules/ad/adapters/secondaries/message-broker.ts delete mode 100644 src/modules/ad/adapters/secondaries/messager.ts create mode 100644 src/modules/ad/core/application/ports/ad.repository.port.ts create mode 100644 src/modules/ad/core/application/ports/default-params-provider.port.ts create mode 100644 src/modules/ad/core/application/ports/default-params.type.ts create mode 100644 src/modules/ad/core/application/ports/timezone-finder.port.ts create mode 100644 src/modules/ad/core/domain/ad.entity.ts create mode 100644 src/modules/ad/core/domain/ad.types.ts create mode 100644 src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts create mode 100644 src/modules/ad/infrastructure/ad.repository.ts create mode 100644 src/modules/ad/infrastructure/default-params-provider.ts create mode 100644 src/modules/ad/infrastructure/prisma.service.ts create mode 100644 src/modules/ad/infrastructure/timezone-finder.ts delete mode 100644 src/modules/ad/tests/unit/adapters/secondaries/messager.spec.ts delete mode 100644 src/modules/health/adapters/primaries/health.controller.ts delete mode 100644 src/modules/health/adapters/secondaries/message-broker.ts delete mode 100644 src/modules/health/adapters/secondaries/messager.ts delete mode 100644 src/modules/health/domain/usecases/prisma.health-indicator.usecase.ts delete mode 100644 src/modules/health/health.module.ts delete mode 100644 src/modules/health/tests/unit/messager.spec.ts delete mode 100644 src/modules/matcher/adapters/secondaries/message-broker.ts delete mode 100644 src/modules/matcher/adapters/secondaries/messager.ts delete mode 100644 src/modules/matcher/domain/types/path.type.ts delete mode 100644 src/modules/matcher/tests/unit/adapters/secondaries/messager.spec.ts create mode 100644 src/modules/messager/messager.di-tokens.ts create mode 100644 src/modules/messager/messager.module.ts diff --git a/.env.dist b/.env.dist index b0a4889..151c967 100644 --- a/.env.dist +++ b/.env.dist @@ -4,6 +4,21 @@ SERVICE_PORT=5005 SERVICE_CONFIGURATION_DOMAIN=MATCHER HEALTH_SERVICE_PORT=6005 +# PRISMA +DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=matcher" + +# MESSAGE BROKER +MESSAGE_BROKER_URI=amqp://v3-broker:5672 +MESSAGE_BROKER_EXCHANGE=mobicoop + +# REDIS +REDIS_HOST=v3-redis +REDIS_PASSWORD=redis +REDIS_PORT=6379 + +# CACHE +CACHE_TTL=5000 + # DEFAULT CONFIGURATION # default identifier used for match requests @@ -41,18 +56,3 @@ MAX_DETOUR_DURATION_RATIO=0.3 GEOROUTER_TYPE=graphhopper # georouter url GEOROUTER_URL=http://localhost:8989 - -# PRISMA -DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=matcher" - -# RABBIT MQ -RMQ_URI=amqp://v3-broker:5672 -RMQ_EXCHANGE=mobicoop - -# REDIS -REDIS_HOST=v3-redis -REDIS_PASSWORD=redis -REDIS_PORT=6379 - -# CACHE -CACHE_TTL=5000 diff --git a/ci/.env.ci b/ci/.env.ci index 334e653..fce2397 100644 --- a/ci/.env.ci +++ b/ci/.env.ci @@ -44,8 +44,9 @@ GEOROUTER_URL=http://localhost:8989 # PRISMA DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=public" -# RABBIT MQ -RMQ_URI=amqp://v3-broker:5672 +# MESSAGE BROKER +MESSAGE_BROKER_URI=amqp://v3-broker:5672 +MESSAGE_BROKER_EXCHANGE=mobicoop # REDIS REDIS_IMAGE=redis:7.0-alpine diff --git a/old/app.constants.ts b/old/app.constants.ts new file mode 100644 index 0000000..28001cd --- /dev/null +++ b/old/app.constants.ts @@ -0,0 +1,2 @@ +export const MESSAGE_BROKER_PUBLISHER = Symbol('MESSAGE_BROKER_PUBLISHER'); +export const MESSAGE_PUBLISHER = Symbol('MESSAGE_PUBLISHER'); diff --git a/old/app.module.ts b/old/app.module.ts new file mode 100644 index 0000000..25543ee --- /dev/null +++ b/old/app.module.ts @@ -0,0 +1,66 @@ +import { classes } from '@automapper/classes'; +import { AutomapperModule } from '@automapper/nestjs'; +import { Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { HealthModule } from './modules/health/health.module'; +import { MatcherModule } from './modules/matcher/matcher.module'; +import { AdModule } from './modules/ad/ad.module'; +import { + ConfigurationModule, + ConfigurationModuleOptions, +} from '@mobicoop/configuration-module'; +import { + MessageBrokerModule, + MessageBrokerModuleOptions, +} from '@mobicoop/message-broker-module'; + +@Module({ + imports: [ + ConfigModule.forRoot({ isGlobal: true }), + ConfigurationModule.forRootAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: async ( + configService: ConfigService, + ): Promise => ({ + domain: configService.get('SERVICE_CONFIGURATION_DOMAIN'), + messageBroker: { + uri: configService.get('MESSAGE_BROKER_URI'), + exchange: configService.get('MESSAGE_BROKER_EXCHANGE'), + }, + redis: { + host: configService.get('REDIS_HOST'), + password: configService.get('REDIS_PASSWORD'), + port: configService.get('REDIS_PORT'), + }, + setConfigurationBrokerQueue: 'matcher-configuration-create-update', + deleteConfigurationQueue: 'matcher-configuration-delete', + propagateConfigurationQueue: 'matcher-configuration-propagate', + }), + }), + MessageBrokerModule.forRootAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: async ( + configService: ConfigService, + ): Promise => ({ + uri: configService.get('MESSAGE_BROKER_URI'), + exchange: configService.get('MESSAGE_BROKER_EXCHANGE'), + handlers: { + adCreated: { + routingKey: 'ad.created', + queue: 'matcher-ad-created', + }, + }, + name: 'matcher', + }), + }), + AutomapperModule.forRoot({ strategyInitializer: classes() }), + HealthModule, + MatcherModule, + AdModule, + ], + controllers: [], + providers: [], +}) +export class AppModule {} diff --git a/old/interfaces/message-publisher.ts b/old/interfaces/message-publisher.ts new file mode 100644 index 0000000..29ad456 --- /dev/null +++ b/old/interfaces/message-publisher.ts @@ -0,0 +1,3 @@ +export interface IPublishMessage { + publish(routingKey: string, message: string): void; +} diff --git a/old/modules/ad/ad.constants.ts b/old/modules/ad/ad.constants.ts new file mode 100644 index 0000000..2f044c9 --- /dev/null +++ b/old/modules/ad/ad.constants.ts @@ -0,0 +1,4 @@ +export const PARAMS_PROVIDER = Symbol(); +export const GEOROUTER_CREATOR = Symbol(); +export const TIMEZONE_FINDER = Symbol(); +export const DIRECTION_ENCODER = Symbol(); diff --git a/old/modules/ad/ad.module.ts b/old/modules/ad/ad.module.ts new file mode 100644 index 0000000..4a36f22 --- /dev/null +++ b/old/modules/ad/ad.module.ts @@ -0,0 +1,61 @@ +import { Module } from '@nestjs/common'; +import { AdMessagerService } from './adapters/primaries/ad-messager.service'; +import { AdProfile } from './mappers/ad.profile'; +import { CreateAdUseCase } from './domain/usecases/create-ad.usecase'; +import { AdRepository } from './adapters/secondaries/ad.repository'; +import { DatabaseModule } from '../database/database.module'; +import { CqrsModule } from '@nestjs/cqrs'; +import { GeoTimezoneFinder } from '../geography/adapters/secondaries/geo-timezone-finder'; +import { DefaultParamsProvider } from './adapters/secondaries/default-params.provider'; +import { GeorouterCreator } from '../geography/adapters/secondaries/georouter-creator'; +import { GeographyModule } from '../geography/geography.module'; +import { HttpModule } from '@nestjs/axios'; +import { PostgresDirectionEncoder } from '../geography/adapters/secondaries/postgres-direction-encoder'; +import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; +import { + MESSAGE_BROKER_PUBLISHER, + MESSAGE_PUBLISHER, +} from '../../app.constants'; +import { MessagePublisher } from './adapters/secondaries/message-publisher'; +import { + DIRECTION_ENCODER, + GEOROUTER_CREATOR, + PARAMS_PROVIDER, + TIMEZONE_FINDER, +} from './ad.constants'; + +@Module({ + imports: [GeographyModule, DatabaseModule, CqrsModule, HttpModule], + providers: [ + { + provide: PARAMS_PROVIDER, + useClass: DefaultParamsProvider, + }, + { + provide: GEOROUTER_CREATOR, + useClass: GeorouterCreator, + }, + { + provide: TIMEZONE_FINDER, + useClass: GeoTimezoneFinder, + }, + { + provide: DIRECTION_ENCODER, + useClass: PostgresDirectionEncoder, + }, + { + provide: MESSAGE_BROKER_PUBLISHER, + useClass: MessageBrokerPublisher, + }, + { + provide: MESSAGE_PUBLISHER, + useClass: MessagePublisher, + }, + AdProfile, + AdRepository, + CreateAdUseCase, + AdMessagerService, + ], + exports: [], +}) +export class AdModule {} diff --git a/src/modules/ad/adapters/primaries/ad-messager.controller.ts b/old/modules/ad/adapters/primaries/ad-messager.service.ts similarity index 77% rename from src/modules/ad/adapters/primaries/ad-messager.controller.ts rename to old/modules/ad/adapters/primaries/ad-messager.service.ts index 99f2d87..d5f2b5a 100644 --- a/src/modules/ad/adapters/primaries/ad-messager.controller.ts +++ b/old/modules/ad/adapters/primaries/ad-messager.service.ts @@ -1,20 +1,21 @@ -import { RabbitSubscribe } from '@golevelup/nestjs-rabbitmq'; -import { Controller } from '@nestjs/common'; -import { CommandBus, QueryBus } from '@nestjs/cqrs'; +import { Controller, Inject } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; import { CreateAdCommand } from '../../commands/create-ad.command'; import { CreateAdRequest } from '../../domain/dtos/create-ad.request'; import { validateOrReject } from 'class-validator'; -import { Messager } from '../secondaries/messager'; import { plainToInstance } from 'class-transformer'; import { DatabaseException } from 'src/modules/database/exceptions/database.exception'; import { ExceptionCode } from 'src/modules/utils/exception-code.enum'; +import { IPublishMessage } from 'src/interfaces/message-publisher'; +import { MESSAGE_PUBLISHER } from 'src/app.constants'; +import { RabbitSubscribe } from '@mobicoop/message-broker-module'; @Controller() -export class AdMessagerController { +export class AdMessagerService { constructor( - private readonly messager: Messager, + @Inject(MESSAGE_PUBLISHER) + private readonly messagePublisher: IPublishMessage, private readonly commandBus: CommandBus, - private readonly queryBus: QueryBus, ) {} @RabbitSubscribe({ @@ -28,7 +29,7 @@ export class AdMessagerController { // validate instance await validateOrReject(createAdRequest); // validate nested objects (fixes direct nested validation bug) - for (const waypoint of createAdRequest.waypoints) { + for (const waypoint of createAdRequest.addresses) { try { await validateOrReject(waypoint); } catch (e) { @@ -36,7 +37,7 @@ export class AdMessagerController { } } } catch (e) { - this.messager.publish( + this.messagePublisher.publish( 'matcher.ad.crit', JSON.stringify({ message: `Can't validate message : ${message}`, @@ -49,7 +50,7 @@ export class AdMessagerController { } catch (e) { if (e instanceof DatabaseException) { if (e.message.includes('already exists')) { - this.messager.publish( + this.messagePublisher.publish( 'matcher.ad.crit', JSON.stringify({ code: ExceptionCode.ALREADY_EXISTS, @@ -59,7 +60,7 @@ export class AdMessagerController { ); } if (e.message.includes("Can't reach database server")) { - this.messager.publish( + this.messagePublisher.publish( 'matcher.ad.crit', JSON.stringify({ code: ExceptionCode.UNAVAILABLE, @@ -69,7 +70,7 @@ export class AdMessagerController { ); } } - this.messager.publish( + this.messagePublisher.publish( 'logging.matcher.ad.crit', JSON.stringify({ message, diff --git a/src/modules/ad/adapters/secondaries/ad.repository.ts b/old/modules/ad/adapters/secondaries/ad.repository.ts similarity index 100% rename from src/modules/ad/adapters/secondaries/ad.repository.ts rename to old/modules/ad/adapters/secondaries/ad.repository.ts diff --git a/src/modules/ad/adapters/secondaries/default-params.provider.ts b/old/modules/ad/adapters/secondaries/default-params.provider.ts similarity index 100% rename from src/modules/ad/adapters/secondaries/default-params.provider.ts rename to old/modules/ad/adapters/secondaries/default-params.provider.ts diff --git a/old/modules/ad/adapters/secondaries/message-publisher.ts b/old/modules/ad/adapters/secondaries/message-publisher.ts new file mode 100644 index 0000000..315bb6b --- /dev/null +++ b/old/modules/ad/adapters/secondaries/message-publisher.ts @@ -0,0 +1,16 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; +import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; +import { IPublishMessage } from '../../../../interfaces/message-publisher'; + +@Injectable() +export class MessagePublisher implements IPublishMessage { + constructor( + @Inject(MESSAGE_BROKER_PUBLISHER) + private readonly messageBrokerPublisher: MessageBrokerPublisher, + ) {} + + publish = (routingKey: string, message: string): void => { + this.messageBrokerPublisher.publish(routingKey, message); + }; +} diff --git a/src/modules/ad/adapters/secondaries/timezone-finder.ts b/old/modules/ad/adapters/secondaries/timezone-finder.ts similarity index 100% rename from src/modules/ad/adapters/secondaries/timezone-finder.ts rename to old/modules/ad/adapters/secondaries/timezone-finder.ts diff --git a/src/modules/ad/commands/create-ad.command.ts b/old/modules/ad/commands/create-ad.command.ts similarity index 100% rename from src/modules/ad/commands/create-ad.command.ts rename to old/modules/ad/commands/create-ad.command.ts diff --git a/src/modules/ad/domain/dtos/create-ad.request.ts b/old/modules/ad/domain/dtos/create-ad.request.ts similarity index 98% rename from src/modules/ad/domain/dtos/create-ad.request.ts rename to old/modules/ad/domain/dtos/create-ad.request.ts index 58a1bb0..06bb0d6 100644 --- a/src/modules/ad/domain/dtos/create-ad.request.ts +++ b/old/modules/ad/domain/dtos/create-ad.request.ts @@ -119,7 +119,7 @@ export class CreateAdRequest { @IsArray() @ArrayMinSize(2) @AutoMap(() => [Coordinate]) - waypoints: Coordinate[]; + addresses: Coordinate[]; @IsNumber() @AutoMap() diff --git a/src/modules/ad/domain/dtos/has-truthy-with.validator.ts b/old/modules/ad/domain/dtos/has-truthy-with.validator.ts similarity index 100% rename from src/modules/ad/domain/dtos/has-truthy-with.validator.ts rename to old/modules/ad/domain/dtos/has-truthy-with.validator.ts diff --git a/src/modules/ad/domain/entities/ad.ts b/old/modules/ad/domain/entities/ad.ts similarity index 100% rename from src/modules/ad/domain/entities/ad.ts rename to old/modules/ad/domain/entities/ad.ts diff --git a/src/modules/ad/domain/entities/geography.ts b/old/modules/ad/domain/entities/geography.ts similarity index 81% rename from src/modules/ad/domain/entities/geography.ts rename to old/modules/ad/domain/entities/geography.ts index b720399..e1ba54c 100644 --- a/src/modules/ad/domain/entities/geography.ts +++ b/old/modules/ad/domain/entities/geography.ts @@ -21,22 +21,22 @@ export class Geography { ): Promise => { const paths: Path[] = this.getPaths(roles); const routes = await georouter.route(paths, settings); - if (routes.some((route) => route.key == RouteKey.COMMON)) { + if (routes.some((route) => route.key == RouteType.COMMON)) { this.driverRoute = routes.find( - (route) => route.key == RouteKey.COMMON, + (route) => route.key == RouteType.COMMON, ).route; this.passengerRoute = routes.find( - (route) => route.key == RouteKey.COMMON, + (route) => route.key == RouteType.COMMON, ).route; } else { - if (routes.some((route) => route.key == RouteKey.DRIVER)) { + if (routes.some((route) => route.key == RouteType.DRIVER)) { this.driverRoute = routes.find( - (route) => route.key == RouteKey.DRIVER, + (route) => route.key == RouteType.DRIVER, ).route; } - if (routes.some((route) => route.key == RouteKey.PASSENGER)) { + if (routes.some((route) => route.key == RouteType.PASSENGER)) { this.passengerRoute = routes.find( - (route) => route.key == RouteKey.PASSENGER, + (route) => route.key == RouteType.PASSENGER, ).route; } } @@ -48,7 +48,7 @@ export class Geography { if (this.coordinates.length == 2) { // 2 points => same route for driver and passenger const commonPath: Path = { - key: RouteKey.COMMON, + key: RouteType.COMMON, points: this.coordinates, }; paths.push(commonPath); @@ -69,14 +69,14 @@ export class Geography { private createDriverPath = (): Path => { return { - key: RouteKey.DRIVER, + key: RouteType.DRIVER, points: this.coordinates, }; }; private createPassengerPath = (): Path => { return { - key: RouteKey.PASSENGER, + key: RouteType.PASSENGER, points: [ this.coordinates[0], this.coordinates[this.coordinates.length - 1], @@ -85,7 +85,7 @@ export class Geography { }; } -export enum RouteKey { +export enum RouteType { COMMON = 'common', DRIVER = 'driver', PASSENGER = 'passenger', diff --git a/src/modules/ad/domain/entities/time-converter.ts b/old/modules/ad/domain/entities/time-converter.ts similarity index 100% rename from src/modules/ad/domain/entities/time-converter.ts rename to old/modules/ad/domain/entities/time-converter.ts diff --git a/src/modules/ad/domain/interfaces/params-provider.interface.ts b/old/modules/ad/domain/interfaces/params-provider.interface.ts similarity index 100% rename from src/modules/ad/domain/interfaces/params-provider.interface.ts rename to old/modules/ad/domain/interfaces/params-provider.interface.ts diff --git a/src/modules/ad/domain/types/default-params.type.ts b/old/modules/ad/domain/types/default-params.type.ts similarity index 100% rename from src/modules/ad/domain/types/default-params.type.ts rename to old/modules/ad/domain/types/default-params.type.ts diff --git a/src/modules/ad/domain/types/frequency.enum.ts b/old/modules/ad/domain/types/frequency.enum.ts similarity index 100% rename from src/modules/ad/domain/types/frequency.enum.ts rename to old/modules/ad/domain/types/frequency.enum.ts diff --git a/src/modules/ad/domain/types/role.enum.ts b/old/modules/ad/domain/types/role.enum.ts similarity index 100% rename from src/modules/ad/domain/types/role.enum.ts rename to old/modules/ad/domain/types/role.enum.ts diff --git a/src/modules/ad/domain/usecases/create-ad.usecase.ts b/old/modules/ad/domain/usecases/create-ad.usecase.ts similarity index 92% rename from src/modules/ad/domain/usecases/create-ad.usecase.ts rename to old/modules/ad/domain/usecases/create-ad.usecase.ts index 71fcc98..506a82a 100644 --- a/src/modules/ad/domain/usecases/create-ad.usecase.ts +++ b/old/modules/ad/domain/usecases/create-ad.usecase.ts @@ -16,6 +16,12 @@ import { Geography } from '../entities/geography'; import { IEncodeDirection } from '../../../geography/domain/interfaces/direction-encoder.interface'; import { TimeConverter } from '../entities/time-converter'; import { Coordinate } from '../../../geography/domain/entities/coordinate'; +import { + DIRECTION_ENCODER, + GEOROUTER_CREATOR, + PARAMS_PROVIDER, + TIMEZONE_FINDER, +} from '../../ad.constants'; @CommandHandler(CreateAdCommand) export class CreateAdUseCase { @@ -29,13 +35,13 @@ export class CreateAdUseCase { constructor( @InjectMapper() private readonly mapper: Mapper, private readonly adRepository: AdRepository, - @Inject('ParamsProvider') + @Inject(PARAMS_PROVIDER) private readonly defaultParamsProvider: IProvideParams, - @Inject('GeorouterCreator') + @Inject(GEOROUTER_CREATOR) private readonly georouterCreator: ICreateGeorouter, - @Inject('TimezoneFinder') + @Inject(TIMEZONE_FINDER) private readonly timezoneFinder: IFindTimezone, - @Inject('DirectionEncoder') + @Inject(DIRECTION_ENCODER) private readonly directionEncoder: IEncodeDirection, ) { this.defaultParams = defaultParamsProvider.getParams(); @@ -48,8 +54,8 @@ export class CreateAdUseCase { async execute(command: CreateAdCommand): Promise { try { this.ad = this.mapper.map(command.createAdRequest, CreateAdRequest, Ad); - this.setTimezone(command.createAdRequest.waypoints); - this.setGeography(command.createAdRequest.waypoints); + this.setTimezone(command.createAdRequest.addresses); + this.setGeography(command.createAdRequest.addresses); this.setRoles(command.createAdRequest); await this.geography.createRoutes(this.roles, this.georouter, { withDistance: false, @@ -97,7 +103,7 @@ export class CreateAdUseCase { ? this.geography.driverRoute.backAzimuth : this.geography.passengerRoute.backAzimuth; this.ad.waypoints = this.directionEncoder.encode( - command.createAdRequest.waypoints, + command.createAdRequest.addresses, ); this.ad.direction = this.geography.driverRoute ? this.directionEncoder.encode(this.geography.driverRoute.points) diff --git a/src/modules/ad/mappers/ad.profile.ts b/old/modules/ad/mappers/ad.profile.ts similarity index 100% rename from src/modules/ad/mappers/ad.profile.ts rename to old/modules/ad/mappers/ad.profile.ts diff --git a/src/modules/ad/tests/integration/ad.repository.spec.ts b/old/modules/ad/tests/integration/ad.repository.spec.ts similarity index 100% rename from src/modules/ad/tests/integration/ad.repository.spec.ts rename to old/modules/ad/tests/integration/ad.repository.spec.ts diff --git a/src/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts b/old/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts similarity index 100% rename from src/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts rename to old/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts diff --git a/old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts b/old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts new file mode 100644 index 0000000..a60708f --- /dev/null +++ b/old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts @@ -0,0 +1,36 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { MessagePublisher } from '../../../../adapters/secondaries/message-publisher'; +import { MESSAGE_BROKER_PUBLISHER } from '../../../../../../app.constants'; + +const mockMessageBrokerPublisher = { + publish: jest.fn().mockImplementation(), +}; + +describe('Messager', () => { + let messagePublisher: MessagePublisher; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [], + providers: [ + MessagePublisher, + { + provide: MESSAGE_BROKER_PUBLISHER, + useValue: mockMessageBrokerPublisher, + }, + ], + }).compile(); + + messagePublisher = module.get(MessagePublisher); + }); + + it('should be defined', () => { + expect(messagePublisher).toBeDefined(); + }); + + it('should publish a message', async () => { + jest.spyOn(mockMessageBrokerPublisher, 'publish'); + messagePublisher.publish('ad.info', 'my-test'); + expect(mockMessageBrokerPublisher.publish).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts b/old/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts similarity index 100% rename from src/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts rename to old/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts diff --git a/src/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts b/old/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts similarity index 91% rename from src/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts rename to old/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts index 040c763..d6819c1 100644 --- a/src/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts +++ b/old/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts @@ -8,9 +8,15 @@ import { CreateAdCommand } from '../../../commands/create-ad.command'; import { Ad } from '../../../domain/entities/ad'; import { AdProfile } from '../../../mappers/ad.profile'; import { Frequency } from '../../../domain/types/frequency.enum'; -import { RouteKey } from '../../../domain/entities/geography'; +import { RouteType } from '../../../domain/entities/geography'; import { DatabaseException } from '../../../../database/exceptions/database.exception'; import { Route } from '../../../../geography/domain/entities/route'; +import { + DIRECTION_ENCODER, + GEOROUTER_CREATOR, + PARAMS_PROVIDER, + TIMEZONE_FINDER, +} from '../../../ad.constants'; const mockAdRepository = { createAd: jest.fn().mockImplementation((ad) => { @@ -23,7 +29,7 @@ const mockGeorouterCreator = { create: jest.fn().mockImplementation(() => ({ route: jest.fn().mockImplementation(() => [ { - key: RouteKey.DRIVER, + key: RouteType.DRIVER, route: { points: [], fwdAzimuth: 0, @@ -33,7 +39,7 @@ const mockGeorouterCreator = { }, }, { - key: RouteKey.PASSENGER, + key: RouteType.PASSENGER, route: { points: [], fwdAzimuth: 0, @@ -43,7 +49,7 @@ const mockGeorouterCreator = { }, }, { - key: RouteKey.COMMON, + key: RouteType.COMMON, route: { points: [], fwdAzimuth: 0, @@ -94,7 +100,7 @@ const createAdRequest: CreateAdRequest = { seatsDriver: 3, seatsPassenger: 1, strict: false, - waypoints: [ + addresses: [ { lon: 6, lat: 45 }, { lon: 6.5, lat: 45.5 }, ], @@ -124,19 +130,19 @@ describe('CreateAdUseCase', () => { useValue: mockAdRepository, }, { - provide: 'GeorouterCreator', + provide: GEOROUTER_CREATOR, useValue: mockGeorouterCreator, }, { - provide: 'ParamsProvider', + provide: PARAMS_PROVIDER, useValue: mockParamsProvider, }, { - provide: 'TimezoneFinder', + provide: TIMEZONE_FINDER, useValue: mockTimezoneFinder, }, { - provide: 'DirectionEncoder', + provide: DIRECTION_ENCODER, useValue: mockDirectionEncoder, }, AdProfile, diff --git a/src/modules/ad/tests/unit/domain/geography.spec.ts b/old/modules/ad/tests/unit/domain/geography.spec.ts similarity index 100% rename from src/modules/ad/tests/unit/domain/geography.spec.ts rename to old/modules/ad/tests/unit/domain/geography.spec.ts diff --git a/src/modules/ad/tests/unit/domain/time-converter.spec.ts b/old/modules/ad/tests/unit/domain/time-converter.spec.ts similarity index 100% rename from src/modules/ad/tests/unit/domain/time-converter.spec.ts rename to old/modules/ad/tests/unit/domain/time-converter.spec.ts diff --git a/src/modules/database/adapters/secondaries/prisma.repository.abstract.ts b/old/modules/database/adapters/secondaries/prisma.repository.abstract.ts similarity index 100% rename from src/modules/database/adapters/secondaries/prisma.repository.abstract.ts rename to old/modules/database/adapters/secondaries/prisma.repository.abstract.ts diff --git a/src/modules/database/adapters/secondaries/prisma.service.ts b/old/modules/database/adapters/secondaries/prisma.service.ts similarity index 100% rename from src/modules/database/adapters/secondaries/prisma.service.ts rename to old/modules/database/adapters/secondaries/prisma.service.ts diff --git a/src/modules/database/database.module.ts b/old/modules/database/database.module.ts similarity index 100% rename from src/modules/database/database.module.ts rename to old/modules/database/database.module.ts diff --git a/src/modules/database/domain/database.repository.ts b/old/modules/database/domain/database.repository.ts similarity index 100% rename from src/modules/database/domain/database.repository.ts rename to old/modules/database/domain/database.repository.ts diff --git a/src/modules/database/exceptions/database.exception.ts b/old/modules/database/exceptions/database.exception.ts similarity index 100% rename from src/modules/database/exceptions/database.exception.ts rename to old/modules/database/exceptions/database.exception.ts diff --git a/src/modules/database/interfaces/collection.interface.ts b/old/modules/database/interfaces/collection.interface.ts similarity index 100% rename from src/modules/database/interfaces/collection.interface.ts rename to old/modules/database/interfaces/collection.interface.ts diff --git a/src/modules/database/interfaces/repository.interface.ts b/old/modules/database/interfaces/repository.interface.ts similarity index 100% rename from src/modules/database/interfaces/repository.interface.ts rename to old/modules/database/interfaces/repository.interface.ts diff --git a/src/modules/database/tests/unit/prisma-repository.spec.ts b/old/modules/database/tests/unit/prisma-repository.spec.ts similarity index 100% rename from src/modules/database/tests/unit/prisma-repository.spec.ts rename to old/modules/database/tests/unit/prisma-repository.spec.ts diff --git a/src/modules/geography/adapters/secondaries/geo-timezone-finder.ts b/old/modules/geography/adapters/secondaries/geo-timezone-finder.ts similarity index 100% rename from src/modules/geography/adapters/secondaries/geo-timezone-finder.ts rename to old/modules/geography/adapters/secondaries/geo-timezone-finder.ts diff --git a/src/modules/geography/adapters/secondaries/geodesic.ts b/old/modules/geography/adapters/secondaries/geodesic.ts similarity index 100% rename from src/modules/geography/adapters/secondaries/geodesic.ts rename to old/modules/geography/adapters/secondaries/geodesic.ts diff --git a/src/modules/geography/adapters/secondaries/georouter-creator.ts b/old/modules/geography/adapters/secondaries/georouter-creator.ts similarity index 93% rename from src/modules/geography/adapters/secondaries/georouter-creator.ts rename to old/modules/geography/adapters/secondaries/georouter-creator.ts index f147a62..69b5a35 100644 --- a/src/modules/geography/adapters/secondaries/georouter-creator.ts +++ b/old/modules/geography/adapters/secondaries/georouter-creator.ts @@ -5,7 +5,7 @@ import { GraphhopperGeorouter } from './graphhopper-georouter'; import { HttpService } from '@nestjs/axios'; import { Geodesic } from './geodesic'; import { GeographyException } from '../../exceptions/geography.exception'; -import { ExceptionCode } from '../../..//utils/exception-code.enum'; +import { ExceptionCode } from '../../../utils/exception-code.enum'; @Injectable() export class GeorouterCreator implements ICreateGeorouter { diff --git a/src/modules/geography/adapters/secondaries/graphhopper-georouter.ts b/old/modules/geography/adapters/secondaries/graphhopper-georouter.ts similarity index 98% rename from src/modules/geography/adapters/secondaries/graphhopper-georouter.ts rename to old/modules/geography/adapters/secondaries/graphhopper-georouter.ts index fd83d2b..42087c4 100644 --- a/src/modules/geography/adapters/secondaries/graphhopper-georouter.ts +++ b/old/modules/geography/adapters/secondaries/graphhopper-georouter.ts @@ -3,12 +3,12 @@ import { IGeorouter } from '../../domain/interfaces/georouter.interface'; import { Injectable } from '@nestjs/common'; import { catchError, lastValueFrom, map } from 'rxjs'; import { AxiosError, AxiosResponse } from 'axios'; -import { IGeodesic } from '../../../geography/domain/interfaces/geodesic.interface'; +import { IGeodesic } from '../../domain/interfaces/geodesic.interface'; import { GeorouterSettings } from '../../domain/types/georouter-settings.type'; import { Path } from '../../domain/types/path.type'; import { NamedRoute } from '../../domain/types/named-route'; import { GeographyException } from '../../exceptions/geography.exception'; -import { ExceptionCode } from '../../..//utils/exception-code.enum'; +import { ExceptionCode } from '../../../utils/exception-code.enum'; import { Route } from '../../domain/entities/route'; import { SpacetimePoint } from '../../domain/entities/spacetime-point'; diff --git a/src/modules/geography/adapters/secondaries/postgres-direction-encoder.ts b/old/modules/geography/adapters/secondaries/postgres-direction-encoder.ts similarity index 100% rename from src/modules/geography/adapters/secondaries/postgres-direction-encoder.ts rename to old/modules/geography/adapters/secondaries/postgres-direction-encoder.ts diff --git a/src/modules/geography/domain/entities/coordinate.ts b/old/modules/geography/domain/entities/coordinate.ts similarity index 100% rename from src/modules/geography/domain/entities/coordinate.ts rename to old/modules/geography/domain/entities/coordinate.ts diff --git a/src/modules/geography/domain/entities/route.ts b/old/modules/geography/domain/entities/route.ts similarity index 100% rename from src/modules/geography/domain/entities/route.ts rename to old/modules/geography/domain/entities/route.ts diff --git a/src/modules/geography/domain/entities/spacetime-point.ts b/old/modules/geography/domain/entities/spacetime-point.ts similarity index 100% rename from src/modules/geography/domain/entities/spacetime-point.ts rename to old/modules/geography/domain/entities/spacetime-point.ts diff --git a/src/modules/geography/domain/interfaces/direction-encoder.interface.ts b/old/modules/geography/domain/interfaces/direction-encoder.interface.ts similarity index 100% rename from src/modules/geography/domain/interfaces/direction-encoder.interface.ts rename to old/modules/geography/domain/interfaces/direction-encoder.interface.ts diff --git a/src/modules/geography/domain/interfaces/geodesic.interface.ts b/old/modules/geography/domain/interfaces/geodesic.interface.ts similarity index 100% rename from src/modules/geography/domain/interfaces/geodesic.interface.ts rename to old/modules/geography/domain/interfaces/geodesic.interface.ts diff --git a/src/modules/geography/domain/interfaces/georouter-creator.interface.ts b/old/modules/geography/domain/interfaces/georouter-creator.interface.ts similarity index 100% rename from src/modules/geography/domain/interfaces/georouter-creator.interface.ts rename to old/modules/geography/domain/interfaces/georouter-creator.interface.ts diff --git a/src/modules/geography/domain/interfaces/georouter.interface.ts b/old/modules/geography/domain/interfaces/georouter.interface.ts similarity index 100% rename from src/modules/geography/domain/interfaces/georouter.interface.ts rename to old/modules/geography/domain/interfaces/georouter.interface.ts diff --git a/src/modules/geography/domain/interfaces/timezone-finder.interface.ts b/old/modules/geography/domain/interfaces/timezone-finder.interface.ts similarity index 100% rename from src/modules/geography/domain/interfaces/timezone-finder.interface.ts rename to old/modules/geography/domain/interfaces/timezone-finder.interface.ts diff --git a/src/modules/geography/domain/types/georouter-settings.type.ts b/old/modules/geography/domain/types/georouter-settings.type.ts similarity index 100% rename from src/modules/geography/domain/types/georouter-settings.type.ts rename to old/modules/geography/domain/types/georouter-settings.type.ts diff --git a/src/modules/geography/domain/types/named-route.ts b/old/modules/geography/domain/types/named-route.ts similarity index 100% rename from src/modules/geography/domain/types/named-route.ts rename to old/modules/geography/domain/types/named-route.ts diff --git a/old/modules/geography/domain/types/path.type.ts b/old/modules/geography/domain/types/path.type.ts new file mode 100644 index 0000000..60766e6 --- /dev/null +++ b/old/modules/geography/domain/types/path.type.ts @@ -0,0 +1,6 @@ +import { Point } from './point.type'; + +export type Path = { + key: string; + points: Point[]; +}; diff --git a/src/modules/geography/domain/types/point-type.enum.ts b/old/modules/geography/domain/types/point-type.enum.ts similarity index 100% rename from src/modules/geography/domain/types/point-type.enum.ts rename to old/modules/geography/domain/types/point-type.enum.ts diff --git a/src/modules/geography/domain/types/point.type.ts b/old/modules/geography/domain/types/point.type.ts similarity index 100% rename from src/modules/geography/domain/types/point.type.ts rename to old/modules/geography/domain/types/point.type.ts diff --git a/src/modules/geography/domain/types/timezoner.ts b/old/modules/geography/domain/types/timezoner.ts similarity index 100% rename from src/modules/geography/domain/types/timezoner.ts rename to old/modules/geography/domain/types/timezoner.ts diff --git a/src/modules/geography/exceptions/geography.exception.ts b/old/modules/geography/exceptions/geography.exception.ts similarity index 100% rename from src/modules/geography/exceptions/geography.exception.ts rename to old/modules/geography/exceptions/geography.exception.ts diff --git a/src/modules/geography/geography.module.ts b/old/modules/geography/geography.module.ts similarity index 100% rename from src/modules/geography/geography.module.ts rename to old/modules/geography/geography.module.ts diff --git a/src/modules/geography/tests/unit/coordinate.spec.ts b/old/modules/geography/tests/unit/coordinate.spec.ts similarity index 100% rename from src/modules/geography/tests/unit/coordinate.spec.ts rename to old/modules/geography/tests/unit/coordinate.spec.ts diff --git a/src/modules/geography/tests/unit/geo-timezone-finder.spec.ts b/old/modules/geography/tests/unit/geo-timezone-finder.spec.ts similarity index 100% rename from src/modules/geography/tests/unit/geo-timezone-finder.spec.ts rename to old/modules/geography/tests/unit/geo-timezone-finder.spec.ts diff --git a/src/modules/geography/tests/unit/geodesic.spec.ts b/old/modules/geography/tests/unit/geodesic.spec.ts similarity index 100% rename from src/modules/geography/tests/unit/geodesic.spec.ts rename to old/modules/geography/tests/unit/geodesic.spec.ts diff --git a/src/modules/geography/tests/unit/georouter-creator.spec.ts b/old/modules/geography/tests/unit/georouter-creator.spec.ts similarity index 100% rename from src/modules/geography/tests/unit/georouter-creator.spec.ts rename to old/modules/geography/tests/unit/georouter-creator.spec.ts diff --git a/src/modules/geography/tests/unit/graphhopper-georouter.spec.ts b/old/modules/geography/tests/unit/graphhopper-georouter.spec.ts similarity index 100% rename from src/modules/geography/tests/unit/graphhopper-georouter.spec.ts rename to old/modules/geography/tests/unit/graphhopper-georouter.spec.ts diff --git a/src/modules/geography/tests/unit/postgres-direction-encoder.spec.ts b/old/modules/geography/tests/unit/postgres-direction-encoder.spec.ts similarity index 100% rename from src/modules/geography/tests/unit/postgres-direction-encoder.spec.ts rename to old/modules/geography/tests/unit/postgres-direction-encoder.spec.ts diff --git a/src/modules/geography/tests/unit/route.spec.ts b/old/modules/geography/tests/unit/route.spec.ts similarity index 100% rename from src/modules/geography/tests/unit/route.spec.ts rename to old/modules/geography/tests/unit/route.spec.ts diff --git a/src/modules/health/adapters/primaries/health-server.controller.ts b/old/modules/health/adapters/primaries/health-server.controller.ts similarity index 67% rename from src/modules/health/adapters/primaries/health-server.controller.ts rename to old/modules/health/adapters/primaries/health-server.controller.ts index c0d63c8..3cdc70d 100644 --- a/src/modules/health/adapters/primaries/health-server.controller.ts +++ b/old/modules/health/adapters/primaries/health-server.controller.ts @@ -1,6 +1,6 @@ import { Controller } from '@nestjs/common'; import { GrpcMethod } from '@nestjs/microservices'; -import { PrismaHealthIndicatorUseCase } from '../../domain/usecases/prisma.health-indicator.usecase'; +import { RepositoriesHealthIndicatorUseCase } from '../../domain/usecases/repositories.health-indicator.usecase'; enum ServingStatus { UNKNOWN = 0, @@ -19,7 +19,7 @@ interface HealthCheckResponse { @Controller() export class HealthServerController { constructor( - private readonly prismaHealthIndicatorUseCase: PrismaHealthIndicatorUseCase, + private readonly repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase, ) {} @GrpcMethod('Health', 'Check') @@ -29,12 +29,12 @@ export class HealthServerController { // eslint-disable-next-line @typescript-eslint/no-unused-vars metadata: any, ): Promise { - const healthCheck = await this.prismaHealthIndicatorUseCase.isHealthy( - 'prisma', + const healthCheck = await this.repositoriesHealthIndicatorUseCase.isHealthy( + 'repositories', ); return { status: - healthCheck['prisma'].status == 'up' + healthCheck['repositories'].status == 'up' ? ServingStatus.SERVING : ServingStatus.NOT_SERVING, }; diff --git a/old/modules/health/adapters/primaries/health.controller.ts b/old/modules/health/adapters/primaries/health.controller.ts new file mode 100644 index 0000000..ba6ad9f --- /dev/null +++ b/old/modules/health/adapters/primaries/health.controller.ts @@ -0,0 +1,37 @@ +import { Controller, Get, Inject } from '@nestjs/common'; +import { + HealthCheckService, + HealthCheck, + HealthCheckResult, +} from '@nestjs/terminus'; +import { MESSAGE_PUBLISHER } from 'src/app.constants'; +import { IPublishMessage } from 'src/interfaces/message-publisher'; +import { RepositoriesHealthIndicatorUseCase } from '../../domain/usecases/repositories.health-indicator.usecase'; + +@Controller('health') +export class HealthController { + constructor( + private readonly repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase, + private healthCheckService: HealthCheckService, + @Inject(MESSAGE_PUBLISHER) + private readonly messagePublisher: IPublishMessage, + ) {} + + @Get() + @HealthCheck() + async check() { + try { + return await this.healthCheckService.check([ + async () => + this.repositoriesHealthIndicatorUseCase.isHealthy('repositories'), + ]); + } catch (error) { + const healthCheckResult: HealthCheckResult = error.response; + this.messagePublisher.publish( + 'logging.user.health.crit', + JSON.stringify(healthCheckResult.error), + ); + throw error; + } + } +} diff --git a/src/modules/health/adapters/primaries/health.proto b/old/modules/health/adapters/primaries/health.proto similarity index 100% rename from src/modules/health/adapters/primaries/health.proto rename to old/modules/health/adapters/primaries/health.proto diff --git a/old/modules/health/adapters/secondaries/message-publisher.ts b/old/modules/health/adapters/secondaries/message-publisher.ts new file mode 100644 index 0000000..98a963b --- /dev/null +++ b/old/modules/health/adapters/secondaries/message-publisher.ts @@ -0,0 +1,16 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; +import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; +import { IPublishMessage } from 'src/interfaces/message-publisher'; + +@Injectable() +export class MessagePublisher implements IPublishMessage { + constructor( + @Inject(MESSAGE_BROKER_PUBLISHER) + private readonly messageBrokerPublisher: MessageBrokerPublisher, + ) {} + + publish = (routingKey: string, message: string): void => { + this.messageBrokerPublisher.publish(routingKey, message); + }; +} diff --git a/old/modules/health/domain/interfaces/check-repository.interface.ts b/old/modules/health/domain/interfaces/check-repository.interface.ts new file mode 100644 index 0000000..68c3178 --- /dev/null +++ b/old/modules/health/domain/interfaces/check-repository.interface.ts @@ -0,0 +1,3 @@ +export interface ICheckRepository { + healthCheck(): Promise; +} diff --git a/old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts b/old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts new file mode 100644 index 0000000..7aaecfa --- /dev/null +++ b/old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; +import { + HealthCheckError, + HealthIndicator, + HealthIndicatorResult, +} from '@nestjs/terminus'; +import { ICheckRepository } from '../interfaces/check-repository.interface'; +import { AdRepository } from '../../../ad/adapters/secondaries/ad.repository'; + +@Injectable() +export class RepositoriesHealthIndicatorUseCase extends HealthIndicator { + private checkRepositories: ICheckRepository[]; + constructor(private readonly adRepository: AdRepository) { + super(); + this.checkRepositories = [adRepository]; + } + isHealthy = async (key: string): Promise => { + try { + await Promise.all( + this.checkRepositories.map( + async (checkRepository: ICheckRepository) => { + await checkRepository.healthCheck(); + }, + ), + ); + return this.getStatus(key, true); + } catch (e: any) { + throw new HealthCheckError('Repository', { + repository: e.message, + }); + } + }; +} diff --git a/old/modules/health/health.module.ts b/old/modules/health/health.module.ts new file mode 100644 index 0000000..0c2511a --- /dev/null +++ b/old/modules/health/health.module.ts @@ -0,0 +1,28 @@ +import { Module } from '@nestjs/common'; +import { HealthServerController } from './adapters/primaries/health-server.controller'; +import { DatabaseModule } from '../database/database.module'; +import { HealthController } from './adapters/primaries/health.controller'; +import { TerminusModule } from '@nestjs/terminus'; +import { MESSAGE_BROKER_PUBLISHER, MESSAGE_PUBLISHER } from 'src/app.constants'; +import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; +import { MessagePublisher } from './adapters/secondaries/message-publisher'; +import { RepositoriesHealthIndicatorUseCase } from './domain/usecases/repositories.health-indicator.usecase'; +import { AdRepository } from '../ad/adapters/secondaries/ad.repository'; + +@Module({ + imports: [TerminusModule, DatabaseModule], + controllers: [HealthServerController, HealthController], + providers: [ + RepositoriesHealthIndicatorUseCase, + AdRepository, + { + provide: MESSAGE_BROKER_PUBLISHER, + useClass: MessageBrokerPublisher, + }, + { + provide: MESSAGE_PUBLISHER, + useClass: MessagePublisher, + }, + ], +}) +export class HealthModule {} diff --git a/old/modules/health/tests/unit/message-publisher.spec.ts b/old/modules/health/tests/unit/message-publisher.spec.ts new file mode 100644 index 0000000..eec02ea --- /dev/null +++ b/old/modules/health/tests/unit/message-publisher.spec.ts @@ -0,0 +1,36 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { MessagePublisher } from '../../adapters/secondaries/message-publisher'; +import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; + +const mockMessageBrokerPublisher = { + publish: jest.fn().mockImplementation(), +}; + +describe('Messager', () => { + let messagePublisher: MessagePublisher; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [], + providers: [ + MessagePublisher, + { + provide: MESSAGE_BROKER_PUBLISHER, + useValue: mockMessageBrokerPublisher, + }, + ], + }).compile(); + + messagePublisher = module.get(MessagePublisher); + }); + + it('should be defined', () => { + expect(messagePublisher).toBeDefined(); + }); + + it('should publish a message', async () => { + jest.spyOn(mockMessageBrokerPublisher, 'publish'); + messagePublisher.publish('health.info', 'my-test'); + expect(mockMessageBrokerPublisher.publish).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/modules/health/tests/unit/prisma.health-indicator.usecase.spec.ts b/old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts similarity index 54% rename from src/modules/health/tests/unit/prisma.health-indicator.usecase.spec.ts rename to old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts index 8c30654..c726f27 100644 --- a/src/modules/health/tests/unit/prisma.health-indicator.usecase.spec.ts +++ b/old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts @@ -1,8 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { PrismaHealthIndicatorUseCase } from '../../domain/usecases/prisma.health-indicator.usecase'; import { HealthCheckError, HealthIndicatorResult } from '@nestjs/terminus'; +import { RepositoriesHealthIndicatorUseCase } from '../../domain/usecases/repositories.health-indicator.usecase'; import { AdRepository } from '../../../ad/adapters/secondaries/ad.repository'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'; const mockAdRepository = { healthCheck: jest @@ -11,47 +10,45 @@ const mockAdRepository = { return Promise.resolve(true); }) .mockImplementation(() => { - throw new PrismaClientKnownRequestError('Service unavailable', { - code: 'code', - clientVersion: 'version', - }); + throw new Error('an error occured in the repository'); }), }; -describe('PrismaHealthIndicatorUseCase', () => { - let prismaHealthIndicatorUseCase: PrismaHealthIndicatorUseCase; +describe('RepositoriesHealthIndicatorUseCase', () => { + let repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ + RepositoriesHealthIndicatorUseCase, { provide: AdRepository, useValue: mockAdRepository, }, - PrismaHealthIndicatorUseCase, ], }).compile(); - prismaHealthIndicatorUseCase = module.get( - PrismaHealthIndicatorUseCase, - ); + repositoriesHealthIndicatorUseCase = + module.get( + RepositoriesHealthIndicatorUseCase, + ); }); it('should be defined', () => { - expect(prismaHealthIndicatorUseCase).toBeDefined(); + expect(repositoriesHealthIndicatorUseCase).toBeDefined(); }); describe('execute', () => { it('should check health successfully', async () => { const healthIndicatorResult: HealthIndicatorResult = - await prismaHealthIndicatorUseCase.isHealthy('prisma'); + await repositoriesHealthIndicatorUseCase.isHealthy('repositories'); - expect(healthIndicatorResult['prisma'].status).toBe('up'); + expect(healthIndicatorResult['repositories'].status).toBe('up'); }); it('should throw an error if database is unavailable', async () => { await expect( - prismaHealthIndicatorUseCase.isHealthy('prisma'), + repositoriesHealthIndicatorUseCase.isHealthy('repositories'), ).rejects.toBeInstanceOf(HealthCheckError); }); }); diff --git a/src/modules/matcher/adapters/primaries/matcher.controller.ts b/old/modules/matcher/adapters/primaries/matcher.controller.ts similarity index 100% rename from src/modules/matcher/adapters/primaries/matcher.controller.ts rename to old/modules/matcher/adapters/primaries/matcher.controller.ts diff --git a/src/modules/matcher/adapters/primaries/matcher.proto b/old/modules/matcher/adapters/primaries/matcher.proto similarity index 100% rename from src/modules/matcher/adapters/primaries/matcher.proto rename to old/modules/matcher/adapters/primaries/matcher.proto diff --git a/src/modules/matcher/adapters/secondaries/default-params.provider.ts b/old/modules/matcher/adapters/secondaries/default-params.provider.ts similarity index 100% rename from src/modules/matcher/adapters/secondaries/default-params.provider.ts rename to old/modules/matcher/adapters/secondaries/default-params.provider.ts diff --git a/src/modules/matcher/adapters/secondaries/geodesic.ts b/old/modules/matcher/adapters/secondaries/geodesic.ts similarity index 100% rename from src/modules/matcher/adapters/secondaries/geodesic.ts rename to old/modules/matcher/adapters/secondaries/geodesic.ts diff --git a/src/modules/matcher/adapters/secondaries/georouter-creator.ts b/old/modules/matcher/adapters/secondaries/georouter-creator.ts similarity index 100% rename from src/modules/matcher/adapters/secondaries/georouter-creator.ts rename to old/modules/matcher/adapters/secondaries/georouter-creator.ts diff --git a/src/modules/matcher/adapters/secondaries/graphhopper-georouter.ts b/old/modules/matcher/adapters/secondaries/graphhopper-georouter.ts similarity index 100% rename from src/modules/matcher/adapters/secondaries/graphhopper-georouter.ts rename to old/modules/matcher/adapters/secondaries/graphhopper-georouter.ts diff --git a/src/modules/matcher/adapters/secondaries/match.presenter.ts b/old/modules/matcher/adapters/secondaries/match.presenter.ts similarity index 100% rename from src/modules/matcher/adapters/secondaries/match.presenter.ts rename to old/modules/matcher/adapters/secondaries/match.presenter.ts diff --git a/old/modules/matcher/adapters/secondaries/message-publisher.ts b/old/modules/matcher/adapters/secondaries/message-publisher.ts new file mode 100644 index 0000000..315bb6b --- /dev/null +++ b/old/modules/matcher/adapters/secondaries/message-publisher.ts @@ -0,0 +1,16 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; +import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; +import { IPublishMessage } from '../../../../interfaces/message-publisher'; + +@Injectable() +export class MessagePublisher implements IPublishMessage { + constructor( + @Inject(MESSAGE_BROKER_PUBLISHER) + private readonly messageBrokerPublisher: MessageBrokerPublisher, + ) {} + + publish = (routingKey: string, message: string): void => { + this.messageBrokerPublisher.publish(routingKey, message); + }; +} diff --git a/src/modules/matcher/adapters/secondaries/time-converter.ts b/old/modules/matcher/adapters/secondaries/time-converter.ts similarity index 100% rename from src/modules/matcher/adapters/secondaries/time-converter.ts rename to old/modules/matcher/adapters/secondaries/time-converter.ts diff --git a/src/modules/matcher/adapters/secondaries/timezone-finder.ts b/old/modules/matcher/adapters/secondaries/timezone-finder.ts similarity index 100% rename from src/modules/matcher/adapters/secondaries/timezone-finder.ts rename to old/modules/matcher/adapters/secondaries/timezone-finder.ts diff --git a/src/modules/matcher/domain/dtos/match.request.ts b/old/modules/matcher/domain/dtos/match.request.ts similarity index 100% rename from src/modules/matcher/domain/dtos/match.request.ts rename to old/modules/matcher/domain/dtos/match.request.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/actor.ts b/old/modules/matcher/domain/entities/ecosystem/actor.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/actor.ts rename to old/modules/matcher/domain/entities/ecosystem/actor.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/ad.ts b/old/modules/matcher/domain/entities/ecosystem/ad.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/ad.ts rename to old/modules/matcher/domain/entities/ecosystem/ad.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts b/old/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts rename to old/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/geography.ts b/old/modules/matcher/domain/entities/ecosystem/geography.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/geography.ts rename to old/modules/matcher/domain/entities/ecosystem/geography.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/match.ts b/old/modules/matcher/domain/entities/ecosystem/match.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/match.ts rename to old/modules/matcher/domain/entities/ecosystem/match.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/matcher-route.ts b/old/modules/matcher/domain/entities/ecosystem/matcher-route.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/matcher-route.ts rename to old/modules/matcher/domain/entities/ecosystem/matcher-route.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/named-route.ts b/old/modules/matcher/domain/entities/ecosystem/named-route.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/named-route.ts rename to old/modules/matcher/domain/entities/ecosystem/named-route.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/requirement.ts b/old/modules/matcher/domain/entities/ecosystem/requirement.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/requirement.ts rename to old/modules/matcher/domain/entities/ecosystem/requirement.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/spacetime-point.ts b/old/modules/matcher/domain/entities/ecosystem/spacetime-point.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/spacetime-point.ts rename to old/modules/matcher/domain/entities/ecosystem/spacetime-point.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/time.ts b/old/modules/matcher/domain/entities/ecosystem/time.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/time.ts rename to old/modules/matcher/domain/entities/ecosystem/time.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/timezoner.ts b/old/modules/matcher/domain/entities/ecosystem/timezoner.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/timezoner.ts rename to old/modules/matcher/domain/entities/ecosystem/timezoner.ts diff --git a/src/modules/matcher/domain/entities/ecosystem/waypoint.ts b/old/modules/matcher/domain/entities/ecosystem/waypoint.ts similarity index 100% rename from src/modules/matcher/domain/entities/ecosystem/waypoint.ts rename to old/modules/matcher/domain/entities/ecosystem/waypoint.ts diff --git a/src/modules/matcher/domain/entities/engine/candidate.ts b/old/modules/matcher/domain/entities/engine/candidate.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/candidate.ts rename to old/modules/matcher/domain/entities/engine/candidate.ts diff --git a/src/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts b/old/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts rename to old/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts diff --git a/src/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts b/old/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts rename to old/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts diff --git a/src/modules/matcher/domain/entities/engine/factory/classic.ts b/old/modules/matcher/domain/entities/engine/factory/classic.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/factory/classic.ts rename to old/modules/matcher/domain/entities/engine/factory/classic.ts diff --git a/src/modules/matcher/domain/entities/engine/matcher.ts b/old/modules/matcher/domain/entities/engine/matcher.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/matcher.ts rename to old/modules/matcher/domain/entities/engine/matcher.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts b/old/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts rename to old/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts b/old/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts rename to old/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts b/old/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts rename to old/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts b/old/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts rename to old/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts b/old/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts rename to old/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts b/old/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts rename to old/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts b/old/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts rename to old/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts diff --git a/src/modules/matcher/domain/entities/engine/processor/processor.abstract.ts b/old/modules/matcher/domain/entities/engine/processor/processor.abstract.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/processor/processor.abstract.ts rename to old/modules/matcher/domain/entities/engine/processor/processor.abstract.ts diff --git a/src/modules/matcher/domain/entities/engine/selector/classic.selector.ts b/old/modules/matcher/domain/entities/engine/selector/classic.selector.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/selector/classic.selector.ts rename to old/modules/matcher/domain/entities/engine/selector/classic.selector.ts diff --git a/src/modules/matcher/domain/entities/engine/selector/selector.abstract.ts b/old/modules/matcher/domain/entities/engine/selector/selector.abstract.ts similarity index 100% rename from src/modules/matcher/domain/entities/engine/selector/selector.abstract.ts rename to old/modules/matcher/domain/entities/engine/selector/selector.abstract.ts diff --git a/src/modules/matcher/domain/interfaces/ad-request.interface.ts b/old/modules/matcher/domain/interfaces/ad-request.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/ad-request.interface.ts rename to old/modules/matcher/domain/interfaces/ad-request.interface.ts diff --git a/src/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts b/old/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts rename to old/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts diff --git a/src/modules/matcher/domain/interfaces/geography-request.interface.ts b/old/modules/matcher/domain/interfaces/geography-request.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/geography-request.interface.ts rename to old/modules/matcher/domain/interfaces/geography-request.interface.ts diff --git a/src/modules/matcher/domain/interfaces/georouter-creator.interface.ts b/old/modules/matcher/domain/interfaces/georouter-creator.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/georouter-creator.interface.ts rename to old/modules/matcher/domain/interfaces/georouter-creator.interface.ts diff --git a/src/modules/matcher/domain/interfaces/georouter.interface.ts b/old/modules/matcher/domain/interfaces/georouter.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/georouter.interface.ts rename to old/modules/matcher/domain/interfaces/georouter.interface.ts diff --git a/src/modules/matcher/domain/interfaces/requirement-request.interface.ts b/old/modules/matcher/domain/interfaces/requirement-request.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/requirement-request.interface.ts rename to old/modules/matcher/domain/interfaces/requirement-request.interface.ts diff --git a/src/modules/matcher/domain/interfaces/time-converter.interface.ts b/old/modules/matcher/domain/interfaces/time-converter.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/time-converter.interface.ts rename to old/modules/matcher/domain/interfaces/time-converter.interface.ts diff --git a/src/modules/matcher/domain/interfaces/time-request.interface.ts b/old/modules/matcher/domain/interfaces/time-request.interface.ts similarity index 100% rename from src/modules/matcher/domain/interfaces/time-request.interface.ts rename to old/modules/matcher/domain/interfaces/time-request.interface.ts diff --git a/src/modules/matcher/domain/types/actor.type..ts b/old/modules/matcher/domain/types/actor.type..ts similarity index 100% rename from src/modules/matcher/domain/types/actor.type..ts rename to old/modules/matcher/domain/types/actor.type..ts diff --git a/src/modules/matcher/domain/types/algorithm.enum.ts b/old/modules/matcher/domain/types/algorithm.enum.ts similarity index 100% rename from src/modules/matcher/domain/types/algorithm.enum.ts rename to old/modules/matcher/domain/types/algorithm.enum.ts diff --git a/src/modules/matcher/domain/types/day.type.ts b/old/modules/matcher/domain/types/day.type.ts similarity index 100% rename from src/modules/matcher/domain/types/day.type.ts rename to old/modules/matcher/domain/types/day.type.ts diff --git a/src/modules/matcher/domain/types/days.const.ts b/old/modules/matcher/domain/types/days.const.ts similarity index 100% rename from src/modules/matcher/domain/types/days.const.ts rename to old/modules/matcher/domain/types/days.const.ts diff --git a/src/modules/matcher/domain/types/default-algorithm-settings.type.ts b/old/modules/matcher/domain/types/default-algorithm-settings.type.ts similarity index 100% rename from src/modules/matcher/domain/types/default-algorithm-settings.type.ts rename to old/modules/matcher/domain/types/default-algorithm-settings.type.ts diff --git a/src/modules/matcher/domain/types/default-params.type.ts b/old/modules/matcher/domain/types/default-params.type.ts similarity index 100% rename from src/modules/matcher/domain/types/default-params.type.ts rename to old/modules/matcher/domain/types/default-params.type.ts diff --git a/src/modules/matcher/domain/types/georouter-settings.type.ts b/old/modules/matcher/domain/types/georouter-settings.type.ts similarity index 100% rename from src/modules/matcher/domain/types/georouter-settings.type.ts rename to old/modules/matcher/domain/types/georouter-settings.type.ts diff --git a/src/modules/matcher/domain/types/margin-durations.type.ts b/old/modules/matcher/domain/types/margin-durations.type.ts similarity index 100% rename from src/modules/matcher/domain/types/margin-durations.type.ts rename to old/modules/matcher/domain/types/margin-durations.type.ts diff --git a/src/modules/matcher/domain/types/mode.enum.ts b/old/modules/matcher/domain/types/mode.enum.ts similarity index 100% rename from src/modules/matcher/domain/types/mode.enum.ts rename to old/modules/matcher/domain/types/mode.enum.ts diff --git a/src/modules/geography/domain/types/path.type.ts b/old/modules/matcher/domain/types/path.type.ts similarity index 100% rename from src/modules/geography/domain/types/path.type.ts rename to old/modules/matcher/domain/types/path.type.ts diff --git a/src/modules/matcher/domain/types/role.enum.ts b/old/modules/matcher/domain/types/role.enum.ts similarity index 100% rename from src/modules/matcher/domain/types/role.enum.ts rename to old/modules/matcher/domain/types/role.enum.ts diff --git a/src/modules/matcher/domain/types/schedule.type.ts b/old/modules/matcher/domain/types/schedule.type.ts similarity index 100% rename from src/modules/matcher/domain/types/schedule.type.ts rename to old/modules/matcher/domain/types/schedule.type.ts diff --git a/src/modules/matcher/domain/types/step.enum.ts b/old/modules/matcher/domain/types/step.enum.ts similarity index 100% rename from src/modules/matcher/domain/types/step.enum.ts rename to old/modules/matcher/domain/types/step.enum.ts diff --git a/src/modules/matcher/domain/types/time-schedule.type.ts b/old/modules/matcher/domain/types/time-schedule.type.ts similarity index 100% rename from src/modules/matcher/domain/types/time-schedule.type.ts rename to old/modules/matcher/domain/types/time-schedule.type.ts diff --git a/src/modules/matcher/domain/types/waypoint.ts b/old/modules/matcher/domain/types/waypoint.ts similarity index 100% rename from src/modules/matcher/domain/types/waypoint.ts rename to old/modules/matcher/domain/types/waypoint.ts diff --git a/src/modules/matcher/domain/usecases/match.usecase.ts b/old/modules/matcher/domain/usecases/match.usecase.ts similarity index 83% rename from src/modules/matcher/domain/usecases/match.usecase.ts rename to old/modules/matcher/domain/usecases/match.usecase.ts index 8af7355..1e0616e 100644 --- a/src/modules/matcher/domain/usecases/match.usecase.ts +++ b/old/modules/matcher/domain/usecases/match.usecase.ts @@ -1,31 +1,34 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { QueryHandler } from '@nestjs/cqrs'; -import { Messager } from '../../adapters/secondaries/messager'; import { MatchQuery } from '../../queries/match.query'; import { Match } from '../entities/ecosystem/match'; import { ICollection } from '../../../database/interfaces/collection.interface'; import { Matcher } from '../entities/engine/matcher'; +import { MESSAGE_PUBLISHER } from '../../../../app.constants'; +import { Inject } from '@nestjs/common'; +import { IPublishMessage } from '../../../../interfaces/message-publisher'; @QueryHandler(MatchQuery) export class MatchUseCase { constructor( private readonly matcher: Matcher, - private readonly messager: Messager, + @Inject(MESSAGE_PUBLISHER) + private readonly messagePublisher: IPublishMessage, @InjectMapper() private readonly mapper: Mapper, ) {} execute = async (matchQuery: MatchQuery): Promise> => { try { const data: Match[] = await this.matcher.match(matchQuery); - this.messager.publish('matcher.match', 'match !'); + this.messagePublisher.publish('matcher.match', 'match !'); return { data, total: data.length, }; } catch (error) { const err: Error = error; - this.messager.publish( + this.messagePublisher.publish( 'logging.matcher.match.crit', JSON.stringify({ matchQuery, diff --git a/src/modules/matcher/exceptions/matcher.exception.ts b/old/modules/matcher/exceptions/matcher.exception.ts similarity index 100% rename from src/modules/matcher/exceptions/matcher.exception.ts rename to old/modules/matcher/exceptions/matcher.exception.ts diff --git a/src/modules/matcher/mappers/match.profile.ts b/old/modules/matcher/mappers/match.profile.ts similarity index 100% rename from src/modules/matcher/mappers/match.profile.ts rename to old/modules/matcher/mappers/match.profile.ts diff --git a/src/modules/matcher/matcher.module.ts b/old/modules/matcher/matcher.module.ts similarity index 79% rename from src/modules/matcher/matcher.module.ts rename to old/modules/matcher/matcher.module.ts index fe84110..7b736aa 100644 --- a/src/modules/matcher/matcher.module.ts +++ b/old/modules/matcher/matcher.module.ts @@ -1,4 +1,3 @@ -import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { CqrsModule } from '@nestjs/cqrs'; @@ -6,7 +5,6 @@ import { DatabaseModule } from '../database/database.module'; import { MatcherController } from './adapters/primaries/matcher.controller'; import { MatchProfile } from './mappers/match.profile'; import { MatchUseCase } from './domain/usecases/match.usecase'; -import { Messager } from './adapters/secondaries/messager'; import { CacheModule } from '@nestjs/cache-manager'; import { RedisClientOptions } from '@liaoliaots/nestjs-redis'; import { redisStore } from 'cache-manager-ioredis-yet'; @@ -20,6 +18,9 @@ import { TimezoneFinder } from './adapters/secondaries/timezone-finder'; import { GeoTimezoneFinder } from '../geography/adapters/secondaries/geo-timezone-finder'; import { GeographyModule } from '../geography/geography.module'; import { TimeConverter } from './adapters/secondaries/time-converter'; +import { MESSAGE_BROKER_PUBLISHER, MESSAGE_PUBLISHER } from 'src/app.constants'; +import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; +import { MessagePublisher } from './adapters/secondaries/message-publisher'; @Module({ imports: [ @@ -27,20 +28,6 @@ import { TimeConverter } from './adapters/secondaries/time-converter'; DatabaseModule, CqrsModule, HttpModule, - RabbitMQModule.forRootAsync(RabbitMQModule, { - imports: [ConfigModule], - useFactory: async (configService: ConfigService) => ({ - exchanges: [ - { - name: configService.get('RMQ_EXCHANGE'), - type: 'topic', - }, - ], - uri: configService.get('RMQ_URI'), - connectionInitOptions: { wait: false }, - }), - inject: [ConfigService], - }), CacheModule.registerAsync({ imports: [ConfigModule], useFactory: async (configService: ConfigService) => ({ @@ -57,7 +44,6 @@ import { TimeConverter } from './adapters/secondaries/time-converter'; controllers: [MatcherController], providers: [ MatchProfile, - Messager, DefaultParamsProvider, MatchUseCase, GeorouterCreator, @@ -67,6 +53,14 @@ import { TimeConverter } from './adapters/secondaries/time-converter'; Matcher, AlgorithmFactoryCreator, GeoTimezoneFinder, + { + provide: MESSAGE_BROKER_PUBLISHER, + useClass: MessageBrokerPublisher, + }, + { + provide: MESSAGE_PUBLISHER, + useClass: MessagePublisher, + }, ], exports: [], }) diff --git a/src/modules/matcher/queries/match.query.ts b/old/modules/matcher/queries/match.query.ts similarity index 100% rename from src/modules/matcher/queries/match.query.ts rename to old/modules/matcher/queries/match.query.ts diff --git a/src/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts rename to old/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts diff --git a/src/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts rename to old/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts diff --git a/src/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts rename to old/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts diff --git a/src/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts rename to old/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts diff --git a/old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts new file mode 100644 index 0000000..a60708f --- /dev/null +++ b/old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts @@ -0,0 +1,36 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { MessagePublisher } from '../../../../adapters/secondaries/message-publisher'; +import { MESSAGE_BROKER_PUBLISHER } from '../../../../../../app.constants'; + +const mockMessageBrokerPublisher = { + publish: jest.fn().mockImplementation(), +}; + +describe('Messager', () => { + let messagePublisher: MessagePublisher; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [], + providers: [ + MessagePublisher, + { + provide: MESSAGE_BROKER_PUBLISHER, + useValue: mockMessageBrokerPublisher, + }, + ], + }).compile(); + + messagePublisher = module.get(MessagePublisher); + }); + + it('should be defined', () => { + expect(messagePublisher).toBeDefined(); + }); + + it('should publish a message', async () => { + jest.spyOn(mockMessageBrokerPublisher, 'publish'); + messagePublisher.publish('ad.info', 'my-test'); + expect(mockMessageBrokerPublisher.publish).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts rename to old/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts rename to old/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts rename to old/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts rename to old/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts rename to old/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts b/old/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/matcher.spec.ts b/old/modules/matcher/tests/unit/domain/engine/matcher.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/matcher.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/matcher.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts rename to old/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts diff --git a/src/modules/matcher/tests/unit/domain/match.usecase.spec.ts b/old/modules/matcher/tests/unit/domain/match.usecase.spec.ts similarity index 95% rename from src/modules/matcher/tests/unit/domain/match.usecase.spec.ts rename to old/modules/matcher/tests/unit/domain/match.usecase.spec.ts index 8ed9acf..ef7512a 100644 --- a/src/modules/matcher/tests/unit/domain/match.usecase.spec.ts +++ b/old/modules/matcher/tests/unit/domain/match.usecase.spec.ts @@ -1,5 +1,4 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { Messager } from '../../../adapters/secondaries/messager'; import { MatchUseCase } from '../../../domain/usecases/match.usecase'; import { MatchRequest } from '../../../domain/dtos/match.request'; import { MatchQuery } from '../../../queries/match.query'; @@ -13,6 +12,7 @@ import { MatcherException, MatcherExceptionCode, } from '../../../exceptions/matcher.exception'; +import { MESSAGE_PUBLISHER } from '../../../../../app.constants'; const mockMatcher = { match: jest @@ -26,7 +26,7 @@ const mockMatcher = { }), }; -const mockMessager = { +const mockMessagePublisher = { publish: jest.fn().mockImplementation(), }; @@ -84,8 +84,8 @@ describe('MatchUseCase', () => { imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })], providers: [ { - provide: Messager, - useValue: mockMessager, + provide: MESSAGE_PUBLISHER, + useValue: mockMessagePublisher, }, { provide: Matcher, diff --git a/src/modules/matcher/tests/unit/queries/match.query.spec.ts b/old/modules/matcher/tests/unit/queries/match.query.spec.ts similarity index 100% rename from src/modules/matcher/tests/unit/queries/match.query.spec.ts rename to old/modules/matcher/tests/unit/queries/match.query.spec.ts diff --git a/src/modules/utils/exception-code.enum.ts b/old/modules/utils/exception-code.enum.ts similarity index 100% rename from src/modules/utils/exception-code.enum.ts rename to old/modules/utils/exception-code.enum.ts diff --git a/src/modules/utils/pipes/rpc.validation-pipe.ts b/old/modules/utils/pipes/rpc.validation-pipe.ts similarity index 100% rename from src/modules/utils/pipes/rpc.validation-pipe.ts rename to old/modules/utils/pipes/rpc.validation-pipe.ts diff --git a/src/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts b/old/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts similarity index 100% rename from src/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts rename to old/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts diff --git a/package-lock.json b/package-lock.json index b354985..5639504 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,32 +1,32 @@ { "name": "@mobicoop/matcher", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mobicoop/matcher", - "version": "0.0.1", + "version": "0.0.2", "license": "AGPL", "dependencies": { - "@automapper/classes": "^8.7.7", - "@automapper/core": "^8.7.7", - "@automapper/nestjs": "^8.7.7", - "@golevelup/nestjs-rabbitmq": "^3.6.0", - "@grpc/grpc-js": "^1.8.13", + "@grpc/grpc-js": "^1.8.14", "@grpc/proto-loader": "^0.7.6", "@liaoliaots/nestjs-redis": "^9.0.5", - "@mobicoop/configuration-module": "^1.0.0", + "@mobicoop/configuration-module": "^1.2.0", + "@mobicoop/ddd-library": "^1.0.0", + "@mobicoop/health-module": "^2.0.0", + "@mobicoop/message-broker-module": "^1.2.0", "@nestjs/axios": "^2.0.0", "@nestjs/cache-manager": "^1.0.0", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.3.1", "@nestjs/core": "^9.0.0", "@nestjs/cqrs": "^9.0.3", + "@nestjs/event-emitter": "^1.4.2", "@nestjs/microservices": "^9.4.0", "@nestjs/platform-express": "^9.0.0", "@nestjs/terminus": "^9.2.2", - "@prisma/client": "^4.12.0", + "@prisma/client": "^4.13.0", "axios": "^1.3.5", "cache-manager": "^5.2.0", "cache-manager-ioredis-yet": "^1.1.0", @@ -35,7 +35,8 @@ "geo-tz": "^7.0.7", "geographiclib-geodesic": "^2.0.0", "got": "^11.8.6", - "ioredis": "^5.3.1", + "ioredis": "^5.3.2", + "nestjs-request-context": "^2.1.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.2.0", "timezonecomplete": "^5.12.4" @@ -56,7 +57,7 @@ "eslint-plugin-prettier": "^4.0.0", "jest": "29.5.0", "prettier": "^2.3.2", - "prisma": "^4.12.0", + "prisma": "^4.13.0", "source-map-support": "^0.5.20", "supertest": "^6.1.3", "ts-jest": "29.0.5", @@ -66,6 +67,15 @@ "typescript": "^4.7.4" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@acuminous/bitsyntax": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", @@ -79,18 +89,13 @@ "node": ">=0.8" } }, - "node_modules/@acuminous/bitsyntax/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { @@ -98,19 +103,19 @@ } }, "node_modules/@angular-devkit/core": { - "version": "15.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.4.tgz", - "integrity": "sha512-yl+0j1bMwJLKShsyCXw77tbJG8Sd21+itisPLL2MgEpLNAO252kr9zG4TLlFRJyKVftm2l1h78KjqvM5nbOXNg==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.0.1.tgz", + "integrity": "sha512-2uz98IqkKJlgnHbWQ7VeL4pb+snGAZXIama2KXi+k9GsRntdcw+udX8rL3G9SdUGUF+m6+147Y1oRBMHsO/v4w==", "dev": true, "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", "jsonc-parser": "3.2.0", - "rxjs": "6.6.7", + "rxjs": "7.8.1", "source-map": "0.7.4" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, @@ -123,50 +128,32 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular-devkit/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/@angular-devkit/schematics": { - "version": "15.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.4.tgz", - "integrity": "sha512-/W7/vvn59PAVLzhcvD4/N/E8RDhub8ny1A7I96LTRjC5o+yvVV16YJ4YJzolrRrIEN01KmLVQJ9A58VCaweMgw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.0.1.tgz", + "integrity": "sha512-A9D0LTYmiqiBa90GKcSuWb7hUouGIbm/AHbJbjL85WLLRbQA2PwKl7P5Mpd6nS/ZC0kfG4VQY3VOaDvb3qpI9g==", "dev": true, "dependencies": { - "@angular-devkit/core": "15.2.4", + "@angular-devkit/core": "16.0.1", "jsonc-parser": "3.2.0", - "magic-string": "0.29.0", + "magic-string": "0.30.0", "ora": "5.4.1", - "rxjs": "6.6.7" + "rxjs": "7.8.1" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "15.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-15.2.4.tgz", - "integrity": "sha512-QTTKEH5HOkxvQtCxb2Lna2wubehkaIzA6DKUBISijPQliLomw74tzc7lXCywmMqRTbQPVRLG3kBK97hR4x67nA==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-16.0.1.tgz", + "integrity": "sha512-6KLA125dpgd6oJGtiO2JpZAb92uOG3njQGIt7NFcuQGW/5GO7J41vMXH9cBAfdtbV8SIggSmR/cIEE9ijfj6YQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "15.2.4", - "@angular-devkit/schematics": "15.2.4", + "@angular-devkit/core": "16.0.1", + "@angular-devkit/schematics": "16.0.1", "ansi-colors": "4.1.3", "inquirer": "8.2.4", "symbol-observable": "4.0.0", @@ -176,7 +163,7 @@ "schematics": "bin/schematics.js" }, "engines": { - "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } @@ -207,99 +194,120 @@ "node": ">=12.0.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular-devkit/schematics/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/@automapper/classes": { - "version": "8.7.7", - "resolved": "https://registry.npmjs.org/@automapper/classes/-/classes-8.7.7.tgz", - "integrity": "sha512-FSbvt6QE8XnhKKQZA3kpKLuLrr9x1iW+lNYTrawVLjxQ05zsCGccLxe7moMNrg1wFAVAouQKupFgCGQ7XRjmJw==", - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@automapper/core": "8.7.7", - "reflect-metadata": "~0.1.13" - } - }, - "node_modules/@automapper/core": { - "version": "8.7.7", - "resolved": "https://registry.npmjs.org/@automapper/core/-/core-8.7.7.tgz", - "integrity": "sha512-YfpDJ/xqwUuC0S+BLNk81ZJfeL7CmjirUX/Gk9eQyx146DKvneBZgeZ9v5rDB51Ti14jTxVHis+5JuT7W/q0TA==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@automapper/nestjs": { - "version": "8.7.7", - "resolved": "https://registry.npmjs.org/@automapper/nestjs/-/nestjs-8.7.7.tgz", - "integrity": "sha512-9/uYY2cmN7SJjr2QxnfyXsteHrn/RHD+Dg0VMBflzK/e8Bh/KWyOve7+kaFixlUoyHe44aXs2LVaCslqt8wnhQ==", - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "@automapper/core": "8.7.7", - "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0", - "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", + "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.10", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", + "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-compilation-targets": "^7.22.10", + "@babel/helper-module-transforms": "^7.22.9", + "@babel/helpers": "^7.22.10", + "@babel/parser": "^7.22.10", + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.2", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -316,21 +324,21 @@ "dev": true }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", - "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", + "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", "dev": true, "dependencies": { - "@babel/types": "^7.21.4", + "@babel/types": "^7.22.10", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -339,31 +347,97 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", + "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.5", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", + "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -372,162 +446,88 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.21.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "dependencies": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", + "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", + "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.5", + "@babel/traverse": "^7.22.10", + "@babel/types": "^7.22.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", + "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -606,9 +606,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", + "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -678,12 +678,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -780,12 +780,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", - "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -795,33 +795,33 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", + "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", - "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", + "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", + "@babel/code-frame": "^7.22.10", + "@babel/generator": "^7.22.10", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.10", + "@babel/types": "^7.22.10", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -839,13 +839,13 @@ } }, "node_modules/@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", + "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -906,23 +906,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -960,28 +960,36 @@ "dev": true }, "node_modules/@eslint/js": { - "version": "8.37.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz", - "integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@golevelup/nestjs-common": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.4.tgz", - "integrity": "sha512-NTjtOhHTMuGwiR3lmBQKKaRr++mHQEsh8AxtaH+/EWOYKMK2Cv/8duaH9MQ0hI3TwnouyaA5IRxYR1ZCUyNXOQ==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.5.tgz", + "integrity": "sha512-WqxGAP4KZjvUea/lYCEfFXB8fS3NwxEWgrQpz2H8jusbz11OSrLECv5TNU9RIRKFnUPbGevy45dvKHF2JTQfJw==", "dependencies": { + "lodash": "^4.17.21", "nanoid": "^3.2.0" + }, + "peerDependencies": { + "@nestjs/common": "^9.x" } }, "node_modules/@golevelup/nestjs-discovery": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.0.tgz", - "integrity": "sha512-ZvkXtobTKxXB1LJanP/l6Z/Fing88IMBr3uabQpU2IWjfsstjh02qYDSU2cfD6CSmNldX5ewW5Pd+SdK2lU8Sw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.1.tgz", + "integrity": "sha512-kK/GBYVxb8XGlwXgtCWAkPOwDVh7dXyLRaoZuk2bBYntV3DZkYGAIbLKOFTGz+MGz71vEeQ9bGLP7cHKtCee4g==", "dependencies": { "lodash": "^4.17.15" + }, + "peerDependencies": { + "@nestjs/common": "^9.x", + "@nestjs/core": "^9.x" } }, "node_modules/@golevelup/nestjs-modules": { @@ -997,21 +1005,63 @@ } }, "node_modules/@golevelup/nestjs-rabbitmq": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-3.6.0.tgz", - "integrity": "sha512-gfa+27QlQdf49g9Y1JrFp/xXFjzXEtRTlVDW7KqJTUYqq03f2AKYdOPH0Iu8ScqpPPRt+qNv9COBJD44Sizerg==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-3.7.0.tgz", + "integrity": "sha512-wV6SA8oCTu8v66U5i3vu/k6DEvlHKM+LTb9JY7Iz8C0nUUuf6pufgvAalusAi4iJJ7/7p3Q44LF38SB4buszWw==", "dependencies": { - "@golevelup/nestjs-common": "^1.4.4", - "@golevelup/nestjs-discovery": "^3.0.0", + "@golevelup/nestjs-common": "^1.4.5", + "@golevelup/nestjs-discovery": "^3.0.1", "@golevelup/nestjs-modules": "^0.6.1", "amqp-connection-manager": "^3.0.0", - "amqplib": "^0.8.0" + "amqplib": "^0.8.0", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "@nestjs/common": "^9.x", + "@nestjs/core": "^9.x", + "reflect-metadata": "^0.1.0", + "rxjs": "^7.x" } }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "dependencies": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@golevelup/nestjs-rabbitmq/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/@grpc/grpc-js": { - "version": "1.8.13", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.13.tgz", - "integrity": "sha512-iY3jsdfbc0ARoCLFvbvUB8optgyb0r1XLPb142u+QtgBcKJYkCIFt3Fd/881KqjLYWjsBJF57N3b8Eop9NDfUA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.0.tgz", + "integrity": "sha512-H8+iZh+kCE6VR/Krj6W28Y/ZlxoZ1fOzsNt77nrdE3knkbSelW1Uus192xOFCxHyeszLj8i4APQkSIXjAoOxXg==", "dependencies": { "@grpc/proto-loader": "^0.7.0", "@types/node": ">=12.12.47" @@ -1021,15 +1071,15 @@ } }, "node_modules/@grpc/proto-loader": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.6.tgz", - "integrity": "sha512-QyAXR8Hyh7uMDmveWxDSUcJr9NAWaZ2I6IXgAYvQmfflwouTM+rArE2eEaCtLlRqO81j7pRLCt81IefUei6Zbw==", + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.8.tgz", + "integrity": "sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA==", "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", - "protobufjs": "^7.0.0", - "yargs": "^16.2.0" + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" @@ -1038,45 +1088,10 @@ "node": ">=6" } }, - "node_modules/@grpc/proto-loader/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1136,6 +1151,15 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -1220,16 +1244,16 @@ } }, "node_modules/@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.2.tgz", + "integrity": "sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2", "slash": "^3.0.0" }, "engines": { @@ -1237,16 +1261,16 @@ } }, "node_modules/@jest/core": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", - "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.2.tgz", + "integrity": "sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg==", "dev": true, "dependencies": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.6.2", + "@jest/reporters": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", @@ -1254,20 +1278,20 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", + "jest-config": "^29.6.2", + "jest-haste-map": "^29.6.2", + "jest-message-util": "^29.6.2", "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", + "jest-resolve": "^29.6.2", + "jest-resolve-dependencies": "^29.6.2", + "jest-runner": "^29.6.2", + "jest-runtime": "^29.6.2", + "jest-snapshot": "^29.6.2", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", + "jest-watcher": "^29.6.2", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.6.2", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -1284,37 +1308,37 @@ } }, "node_modules/@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.2.tgz", + "integrity": "sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/fake-timers": "^29.6.2", + "@jest/types": "^29.6.1", "@types/node": "*", - "jest-mock": "^29.5.0" + "jest-mock": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.2.tgz", + "integrity": "sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg==", "dev": true, "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" + "expect": "^29.6.2", + "jest-snapshot": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.2.tgz", + "integrity": "sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg==", "dev": true, "dependencies": { "jest-get-type": "^29.4.3" @@ -1324,49 +1348,49 @@ } }, "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.2.tgz", + "integrity": "sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-message-util": "^29.6.2", + "jest-mock": "^29.6.2", + "jest-util": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.2.tgz", + "integrity": "sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" + "@jest/environment": "^29.6.2", + "@jest/expect": "^29.6.2", + "@jest/types": "^29.6.1", + "jest-mock": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", - "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.2.tgz", + "integrity": "sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/console": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -1378,9 +1402,9 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2", + "jest-worker": "^29.6.2", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1399,24 +1423,24 @@ } }, "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.0.tgz", + "integrity": "sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" }, @@ -1425,13 +1449,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.2.tgz", + "integrity": "sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw==", "dev": true, "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.6.2", + "@jest/types": "^29.6.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1440,14 +1464,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", - "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.2.tgz", + "integrity": "sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw==", "dev": true, "dependencies": { - "@jest/test-result": "^29.5.0", + "@jest/test-result": "^29.6.2", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.6.2", "slash": "^3.0.0" }, "engines": { @@ -1455,22 +1479,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.2.tgz", + "integrity": "sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.6.2", "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", + "jest-util": "^29.6.2", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1481,12 +1505,12 @@ } }, "node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.0", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1498,22 +1522,23 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1529,43 +1554,29 @@ } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@liaoliaots/nestjs-redis": { @@ -1584,11 +1595,6 @@ "ioredis": "^5.0.0" } }, - "node_modules/@liaoliaots/nestjs-redis/node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, "node_modules/@lukeed/csprng": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", @@ -1598,13 +1604,12 @@ } }, "node_modules/@mobicoop/configuration-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@mobicoop/configuration-module/-/configuration-module-1.0.0.tgz", - "integrity": "sha512-ufpJl3YupHhpcGS26h/kEGSplmJ5C3UcE5UkX5MUHbJzJBATN6FmikU3JgKU9bdN/YxHrxylmnknQVKcr3HT1w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@mobicoop/configuration-module/-/configuration-module-1.2.0.tgz", + "integrity": "sha512-l0iDae7SgVVmjnCa2MBqAr3Er0yn4E7yiG8e7cs4XtNGUKrC1N0Ju56TEAraEYK9aZAZ36TCs06m1fep+rgwFA==", "dependencies": { "@golevelup/nestjs-rabbitmq": "^3.6.0", "@liaoliaots/nestjs-redis": "^9.0.5", - "@nestjs/config": "^2.3.2", "@nestjs/cqrs": "^9.0.4", "@types/amqplib": "^0.10.1", "amqplib": "^0.10.3", @@ -1615,40 +1620,77 @@ "@nestjs/common": "^9.4.2" } }, - "node_modules/@mobicoop/configuration-module/node_modules/amqplib": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", - "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "node_modules/@mobicoop/ddd-library": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@mobicoop/ddd-library/-/ddd-library-1.0.0.tgz", + "integrity": "sha512-uOF2n2VqgfVP4QldEPGMuR3VPn0U5+XXQw5CK1E/9IHXIgiqdmAnKHX5qUpcr29mKbU5QvQbBuIyMeQqCFVu+w==", "dependencies": { - "@acuminous/bitsyntax": "^0.1.2", - "buffer-more-ints": "~1.0.0", - "readable-stream": "1.x >=1.1.9", - "url-parse": "~1.5.10" + "@nestjs/event-emitter": "^1.4.2", + "@nestjs/microservices": "^9.4.0", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.0", + "uuid": "^9.0.0" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@nestjs/common": "^9.4.2" } }, - "node_modules/@mobicoop/configuration-module/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/@mobicoop/configuration-module/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "node_modules/@mobicoop/health-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@mobicoop/health-module/-/health-module-2.0.0.tgz", + "integrity": "sha512-r/7zrHJKVRTIiZ50ILy3lEUC/9vi6k0TRcYPMS8zcnUssQg+MPcT5DQS9B9tTB2gkKwcCyxOQlZZIppIybFX3A==", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "@grpc/grpc-js": "^1.8.14", + "@grpc/proto-loader": "^0.7.7", + "@mobicoop/ddd-library": "^0.3.0", + "@mobicoop/message-broker-module": "^1.0.5", + "@nestjs/axios": "^3.0.0", + "@nestjs/microservices": "^9.4.2", + "@nestjs/terminus": "^9.2.2", + "axios": "^1.4.0" + }, + "peerDependencies": { + "@nestjs/common": "^9.4.2" } }, - "node_modules/@mobicoop/configuration-module/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "node_modules/@mobicoop/health-module/node_modules/@mobicoop/ddd-library": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@mobicoop/ddd-library/-/ddd-library-0.3.0.tgz", + "integrity": "sha512-MoUDqlrDmJkumCFSyW9FY2DLbguT4rytFrmBt9tVNCr2Es6nlz4Ml3HVBwJTZrlJFU79XmiUQ5WAO0MHJt+nAg==", + "dependencies": { + "@nestjs/event-emitter": "^1.4.2", + "@nestjs/microservices": "^9.4.0", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.0", + "uuid": "^9.0.0" + }, + "peerDependencies": { + "@nestjs/common": "^9.4.2" + } + }, + "node_modules/@mobicoop/health-module/node_modules/@nestjs/axios": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.0.tgz", + "integrity": "sha512-ULdH03jDWkS5dy9X69XbUVbhC+0pVnrRcj7bIK/ytTZ76w7CgvTZDJqsIyisg3kNOiljRW/4NIjSf3j6YGvl+g==", + "peerDependencies": { + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", + "axios": "^1.3.1", + "reflect-metadata": "^0.1.12", + "rxjs": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/@mobicoop/message-broker-module": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@mobicoop/message-broker-module/-/message-broker-module-1.2.0.tgz", + "integrity": "sha512-RoSHHK1GyQ/QVDmm3JS/wBfh171oChvyEp6YWmJd12krFLrPVn9MoEvZdyT3I5J31oBiUabMPle5Kdpw+Nrmww==", + "dependencies": { + "@golevelup/nestjs-rabbitmq": "^3.6.0", + "@types/amqplib": "^0.10.1", + "amqplib": "^0.10.3" + }, + "peerDependencies": { + "@nestjs/common": "^9.4.2" + } }, "node_modules/@nestjs/axios": { "version": "2.0.0", @@ -1673,14 +1715,14 @@ } }, "node_modules/@nestjs/cli": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.3.0.tgz", - "integrity": "sha512-v/E8Y3zFk30+FljETvPgpoGIUiOfWuOe6WUFw3ExGfDeWrF/A8ceupDHPWNknBAqvNtz2kVrWu5mwsZUEKGIgg==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.5.0.tgz", + "integrity": "sha512-Z7q+3vNsQSG2d2r2Hl/OOj5EpfjVx3OfnJ9+KuAsOdw1sKLm7+Zc6KbhMFTd/eIvfx82ww3Nk72xdmfPYCulWA==", "dev": true, "dependencies": { - "@angular-devkit/core": "15.2.4", - "@angular-devkit/schematics": "15.2.4", - "@angular-devkit/schematics-cli": "15.2.4", + "@angular-devkit/core": "16.0.1", + "@angular-devkit/schematics": "16.0.1", + "@angular-devkit/schematics-cli": "16.0.1", "@nestjs/schematics": "^9.0.4", "chalk": "4.1.2", "chokidar": "3.5.3", @@ -1691,14 +1733,14 @@ "node-emoji": "1.11.0", "ora": "5.4.1", "os-name": "4.0.1", - "rimraf": "4.4.0", + "rimraf": "4.4.1", "shelljs": "0.8.5", "source-map-support": "0.5.21", "tree-kill": "1.2.2", - "tsconfig-paths": "4.1.2", + "tsconfig-paths": "4.2.0", "tsconfig-paths-webpack-plugin": "4.0.1", "typescript": "4.9.5", - "webpack": "5.76.2", + "webpack": "5.82.1", "webpack-node-externals": "3.0.0" }, "bin": { @@ -1708,46 +1750,23 @@ "node": ">= 12.9.0" } }, - "node_modules/@nestjs/cli/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nestjs/cli/node_modules/tsconfig-paths": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz", - "integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==", - "dev": true, - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/@nestjs/cli/node_modules/webpack": { - "version": "5.76.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.2.tgz", - "integrity": "sha512-Th05ggRm23rVzEOlX8y67NkYCHa9nTNcwHPBhdg+lKG+mtiW7XgggjAeeLnADAe7mLjJ6LUNfgHAuRRh+Z6J7w==", + "version": "5.82.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.1.tgz", + "integrity": "sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.14.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -1756,9 +1775,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.1.2", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -1779,12 +1798,12 @@ } }, "node_modules/@nestjs/common": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.4.2.tgz", - "integrity": "sha512-sea+qZnbD5x3YWZDVQT/wbVJ2NiABaM1tyZTLuW9hpkcM2KFA96xKtK3VaCxyz49zoXIgSOefsyK7HuUMCe27Q==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.4.3.tgz", + "integrity": "sha512-Gd6D4IaYj01o14Bwv81ukidn4w3bPHCblMUq+SmUmWLyosK+XQmInCS09SbDDZyL8jy86PngtBLTdhJ2bXSUig==", "dependencies": { "iterare": "1.2.1", - "tslib": "2.5.2", + "tslib": "2.5.3", "uid": "2.0.2" }, "funding": { @@ -1811,16 +1830,16 @@ } }, "node_modules/@nestjs/common/node_modules/tslib": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", - "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==" + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" }, "node_modules/@nestjs/config": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-2.3.2.tgz", - "integrity": "sha512-VtGV8PBpxzMzz68kdxTWqPm9v7SYCSZXQ0tC72AMNnjdmU+CVjUSLpEpdnm0XcWHxE1nV6wSI3HZxsATIV4ZxA==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-2.3.4.tgz", + "integrity": "sha512-IGdSF+0F9MJO6dCRTEahdxPz4iVijjtolcFBxnY+2QYM3bXYQvAgzskGZi+WkAFJN/VzR3TEp60gN5sI74GxPA==", "dependencies": { - "dotenv": "16.0.3", + "dotenv": "16.1.4", "dotenv-expand": "10.0.0", "lodash": "4.17.21", "uuid": "9.0.0" @@ -1832,16 +1851,16 @@ } }, "node_modules/@nestjs/core": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.4.0.tgz", - "integrity": "sha512-yTLryCgFD0462wPe4HIzhyTcDgibt8Stfwb5YzcX7Ma0NM4m8uBIpcPG109KBubp8ZmV85e5mw4rl20qLQQVsQ==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.4.3.tgz", + "integrity": "sha512-Qi63+wi55Jh4sDyaj5Hhx2jOpKqT386aeo+VOKsxnd+Ql9VvkO/FjmuwBGUyzkJt29ENYc+P0Sx/k5LtstNpPQ==", "hasInstallScript": true, "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", "path-to-regexp": "3.2.0", - "tslib": "2.5.0", + "tslib": "2.5.3", "uid": "2.0.2" }, "funding": { @@ -1868,6 +1887,11 @@ } } }, + "node_modules/@nestjs/core/node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + }, "node_modules/@nestjs/cqrs": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/@nestjs/cqrs/-/cqrs-9.0.4.tgz", @@ -1882,13 +1906,26 @@ "rxjs": "^7.2.0" } }, + "node_modules/@nestjs/event-emitter": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@nestjs/event-emitter/-/event-emitter-1.4.2.tgz", + "integrity": "sha512-5mskPMS4KVH6LghC+NynfdmGiMCOOv9CdgVpuWGipLrJECv5KWc7vaW5o/9BYrcqPkN7Ted6CJ+O4AfsTiRlgw==", + "dependencies": { + "eventemitter2": "6.4.9" + }, + "peerDependencies": { + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0", + "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0", + "reflect-metadata": "^0.1.12" + } + }, "node_modules/@nestjs/microservices": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-9.4.0.tgz", - "integrity": "sha512-3IlURTijN2whedrfnLbJ3QQ4giDU1SxXcepXxtUL1MMkZAJgw2gN7sTquOXVgy/Ci5OMPO+vOjVyadjFejrgKA==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-9.4.3.tgz", + "integrity": "sha512-piMw8d3C4ppc5St5AhQEtecMhyeBK2Q1VYk4AL3NKtG6U0fzz/6KLiETpWdKXmazeI/m7qac2upOvwmRzle0aA==", "dependencies": { "iterare": "1.2.1", - "tslib": "2.5.0" + "tslib": "2.5.3" }, "funding": { "type": "opencollective", @@ -1939,16 +1976,21 @@ } } }, + "node_modules/@nestjs/microservices/node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + }, "node_modules/@nestjs/platform-express": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.4.0.tgz", - "integrity": "sha512-PpnfghpNq7mwG43z3+pacHulsabUCBMla4nUikntXT525ORpZSDvh/nLi1HLfE4w5+FcINc8/RBOyYTeRVmiRQ==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.4.3.tgz", + "integrity": "sha512-FpdczWoRSC0zz2dNL9u2AQLXKXRVtq4HgHklAhbL59X0uy+mcxhlSThG7DHzDMkoSnuuHY8ojDVf7mDxk+GtCw==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", "express": "4.18.2", "multer": "1.4.4-lts.1", - "tslib": "2.5.0" + "tslib": "2.5.3" }, "funding": { "type": "opencollective", @@ -1959,14 +2001,19 @@ "@nestjs/core": "^9.0.0" } }, + "node_modules/@nestjs/platform-express/node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + }, "node_modules/@nestjs/schematics": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-9.1.0.tgz", - "integrity": "sha512-/7CyMTnPJSK9/xD9CkCqwuHPOlHVlLC2RDnbdCJ7mIO07SdbBbY14msTqtYW9VRQtsjZPLh1GTChf7ryJUImwA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-9.2.0.tgz", + "integrity": "sha512-wHpNJDPzM6XtZUOB3gW0J6mkFCSJilzCM3XrHI1o0C8vZmFE1snbmkIXNyoi1eV0Nxh1BMymcgz5vIMJgQtTqw==", "dev": true, "dependencies": { - "@angular-devkit/core": "15.2.4", - "@angular-devkit/schematics": "15.2.4", + "@angular-devkit/core": "16.0.1", + "@angular-devkit/schematics": "16.0.1", "jsonc-parser": "3.2.0", "pluralize": "8.0.0" }, @@ -2040,12 +2087,12 @@ } }, "node_modules/@nestjs/testing": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.4.0.tgz", - "integrity": "sha512-xZWp363P4otcebg++gSjUcdCfTK0RorORzyFq3aLaSAQOlq8kxfFDRIKzEATR4aOUfqTMMsAA8lhnMJWf35N6A==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.4.3.tgz", + "integrity": "sha512-LDT8Ai2eKnTzvnPaJwWOK03qTaFap5uHHsJCv6dL0uKWk6hyF9jms8DjyVaGsaujCaXDG8izl1mDEER0OmxaZA==", "dev": true, "dependencies": { - "tslib": "2.5.0" + "tslib": "2.5.3" }, "funding": { "type": "opencollective", @@ -2066,6 +2113,12 @@ } } }, + "node_modules/@nestjs/testing/node_modules/tslib": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2119,12 +2172,12 @@ } }, "node_modules/@prisma/client": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.12.0.tgz", - "integrity": "sha512-j9/ighfWwux97J2dS15nqhl60tYoH8V0IuSsgZDb6bCFcQD3fXbXmxjYC8GHhIgOk3lB7Pq+8CwElz2MiDpsSg==", + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.16.2.tgz", + "integrity": "sha512-qCoEyxv1ZrQ4bKy39GnylE8Zq31IRmm8bNhNbZx7bF2cU5aiCCnSa93J2imF88MBjn7J9eUQneNxUQVJdl/rPQ==", "hasInstallScript": true, "dependencies": { - "@prisma/engines-version": "4.12.0-67.659ef412370fa3b41cd7bf6e94587c1dfb7f67e7" + "@prisma/engines-version": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81" }, "engines": { "node": ">=14.17" @@ -2139,16 +2192,16 @@ } }, "node_modules/@prisma/engines": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.12.0.tgz", - "integrity": "sha512-0alKtnxhNB5hYU+ymESBlGI4b9XrGGSdv7Ud+8TE/fBNOEhIud0XQsAR+TrvUZgS4na5czubiMsODw0TUrgkIA==", + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.16.2.tgz", + "integrity": "sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==", "devOptional": true, "hasInstallScript": true }, "node_modules/@prisma/engines-version": { - "version": "4.12.0-67.659ef412370fa3b41cd7bf6e94587c1dfb7f67e7", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.12.0-67.659ef412370fa3b41cd7bf6e94587c1dfb7f67e7.tgz", - "integrity": "sha512-JIHNj5jlXb9mcaJwakM0vpgRYJIAurxTUqM0iX0tfEQA5XLZ9ONkIckkhuAKdAzocZ+80GYg7QSsfpjg7OxbOA==" + "version": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81.tgz", + "integrity": "sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==" }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", @@ -2205,9 +2258,9 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, "node_modules/@sindresorhus/is": { @@ -2222,21 +2275,21 @@ } }, "node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@szmarczak/http-timer": { @@ -2269,9 +2322,9 @@ "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, "node_modules/@turf/boolean-point-in-polygon": { @@ -2314,9 +2367,9 @@ } }, "node_modules/@types/babel__core": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", - "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", @@ -2346,12 +2399,12 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { @@ -2391,9 +2444,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.37.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", - "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "version": "8.44.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", + "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", "dev": true, "dependencies": { "@types/estree": "*", @@ -2411,9 +2464,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", "dev": true }, "node_modules/@types/express": { @@ -2429,14 +2482,15 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.33", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", - "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/graceful-fs": { @@ -2453,6 +2507,12 @@ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -2488,9 +2548,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, "node_modules/@types/keyv": { @@ -2507,9 +2567,9 @@ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, "node_modules/@types/node": { @@ -2523,12 +2583,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true - }, "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -2550,17 +2604,28 @@ } }, "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, - "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", "dev": true, "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", "@types/mime": "*", "@types/node": "*" } @@ -2572,9 +2637,9 @@ "dev": true }, "node_modules/@types/superagent": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.16.tgz", - "integrity": "sha512-tLfnlJf6A5mB6ddqF159GqcDizfzbMUB1/DeT59/wBNqzRTNNKsaw79A/1TZ84X+f/EwWH8FeuSkjlCLyqS/zQ==", + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.18.tgz", + "integrity": "sha512-LOWgpacIV8GHhrsQU+QMZuomfqXiqzz3ILLkCtKx3Us6AmomFViuzKT9D693QTKgyut2oCytMG8/efOop+DB+w==", "dev": true, "dependencies": { "@types/cookiejar": "*", @@ -2591,9 +2656,9 @@ } }, "node_modules/@types/validator": { - "version": "13.7.14", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.14.tgz", - "integrity": "sha512-J6OAed6rhN6zyqL9Of6ZMamhlsOEU/poBVvbHr/dKOYKTeuYYMlDkMv+b6UUV0o2i0tw73cgyv/97WTWaUl0/g==" + "version": "13.11.1", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz", + "integrity": "sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A==" }, "node_modules/@types/yargs": { "version": "17.0.24", @@ -2611,17 +2676,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.57.1.tgz", - "integrity": "sha512-1MeobQkQ9tztuleT3v72XmY0XuKXVXusAhryoLuU5YZ+mXoYKZP9SQ7Flulh1NX4DTjpGTc2b/eMu4u7M7dhnQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/type-utils": "5.57.1", - "@typescript-eslint/utils": "5.57.1", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", @@ -2645,14 +2710,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.57.1.tgz", - "integrity": "sha512-hlA0BLeVSA/wBPKdPGxoVr9Pp6GutGoY380FEhbVi0Ph4WNe8kLvqIRx76RSQt1lynZKfrXKs0/XeEk4zZycuA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/typescript-estree": "5.57.1", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -2672,13 +2737,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.57.1.tgz", - "integrity": "sha512-N/RrBwEUKMIYxSKl0oDK5sFVHd6VI7p9K5MyUlVYAY6dyNb/wHUqndkTd3XhpGlXgnQsBkRZuu4f9kAHghvgPw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/visitor-keys": "5.57.1" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2689,13 +2754,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.57.1.tgz", - "integrity": "sha512-/RIPQyx60Pt6ga86hKXesXkJ2WOS4UemFrmmq/7eOyiYjYv/MUSHPlkhU6k9T9W1ytnTJueqASW+wOmW4KrViw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.57.1", - "@typescript-eslint/utils": "5.57.1", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2716,9 +2781,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.57.1.tgz", - "integrity": "sha512-bSs4LOgyV3bJ08F5RDqO2KXqg3WAdwHCu06zOqcQ6vqbTJizyBhuh1o1ImC69X4bV2g1OJxbH71PJqiO7Y1RuA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2729,13 +2794,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.1.tgz", - "integrity": "sha512-A2MZqD8gNT0qHKbk2wRspg7cHbCDCk2tcqt6ScCFLr5Ru8cn+TCfM786DjPhqwseiS+PrYwcXht5ztpEQ6TFTw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/visitor-keys": "5.57.1", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2756,17 +2821,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.57.1.tgz", - "integrity": "sha512-kN6vzzf9NkEtawECqze6v99LtmDiUJCVpvieTFA1uL7/jDghiJGubGZ5csicYHU1Xoqb3oH/R5cN5df6W41Nfg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.57.1", - "@typescript-eslint/types": "5.57.1", - "@typescript-eslint/typescript-estree": "5.57.1", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -2782,12 +2847,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.1.tgz", - "integrity": "sha512-RjQrAniDU0CEk5r7iphkm731zKlFiUjvcBS2yHAg8WWqFMCaCrD0rKEVOMUyMMcbGPZ0bPp56srkGWrgfZqLRA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.57.1", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2799,148 +2864,148 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, @@ -2969,9 +3034,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2981,9 +3046,9 @@ } }, "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -3056,42 +3121,19 @@ } }, "node_modules/amqplib": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", - "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", "dependencies": { - "bitsyntax": "~0.1.0", - "bluebird": "^3.7.2", + "@acuminous/bitsyntax": "^0.1.2", "buffer-more-ints": "~1.0.0", "readable-stream": "1.x >=1.1.9", - "safe-buffer": "~5.2.1", - "url-parse": "~1.5.1" + "url-parse": "~1.5.10" }, "engines": { "node": ">=10" } }, - "node_modules/amqplib/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/amqplib/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/amqplib/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" - }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -3219,9 +3261,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz", - "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -3229,12 +3271,12 @@ } }, "node_modules/babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", + "integrity": "sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==", "dev": true, "dependencies": { - "@jest/transform": "^29.5.0", + "@jest/transform": "^29.6.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.5.0", @@ -3380,11 +3422,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/bitsyntax/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3410,6 +3447,35 @@ "node": ">= 6" } }, + "node_modules/bl/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -3472,17 +3538,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/boxen/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3506,9 +3561,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -3518,13 +3573,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" }, "bin": { "browserslist": "cli.js" @@ -3608,34 +3667,26 @@ } }, "node_modules/cache-manager": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.2.0.tgz", - "integrity": "sha512-jwXDLtn8tQGS2vGDTKAhee2OhuX/2cgxlh97fqMnWp328VszIn064BFyKZ87dwp9GmlBFuHYfaVQehI85hFwIw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.2.3.tgz", + "integrity": "sha512-9OErI8fksFkxAMJ8Mco0aiZSdphyd90HcKiOMJQncSlU1yq/9lHHxrT8PDayxrmr9IIIZPOAEfXuGSD7g29uog==", "dependencies": { "lodash.clonedeep": "^4.5.0", - "lru-cache": "~7.18.3" + "lru-cache": "^9.1.2" } }, "node_modules/cache-manager-ioredis-yet": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cache-manager-ioredis-yet/-/cache-manager-ioredis-yet-1.1.0.tgz", - "integrity": "sha512-bGBAq8oNzzNkO2dwlYGWBxNXrz4w8FUTpe3nfUydJ6bm1ixKEcSUKYksGokQMaRgqkQjMbIHWFkvb8p+V9ZKqw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cache-manager-ioredis-yet/-/cache-manager-ioredis-yet-1.2.2.tgz", + "integrity": "sha512-o03N/tQxfFONZ1XLGgIxOFHuQQpjpRdnSAL1THG1YWZIVp1JMUfjU3ElSAjFN1LjbJXa55IpC8waG+VEoLUCUw==", "dependencies": { - "cache-manager": "^5.1.0", - "ioredis": "^5.2.3" + "cache-manager": "^5.2.3", + "ioredis": "^5.3.2" }, "engines": { "node": ">= 16.17.0" } }, - "node_modules/cache-manager/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "engines": { - "node": ">=12" - } - }, "node_modules/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -3645,9 +3696,9 @@ } }, "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -3661,20 +3712,6 @@ "node": ">=8" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -3697,18 +3734,20 @@ } }, "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001474", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz", - "integrity": "sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q==", + "version": "1.0.30001521", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001521.tgz", + "integrity": "sha512-fnx1grfpEOvDGH+V17eccmNjucGUnCbP6KL+l5KqBIerp26WK/+RQ7CIDE37KGJjaPyqWXXlFUyKiWmvdNNKmQ==", "dev": true, "funding": [ { @@ -3815,9 +3854,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", "dev": true }, "node_modules/class-transformer": { @@ -3859,9 +3898,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.8.0.tgz", - "integrity": "sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", "dev": true, "engines": { "node": ">=6" @@ -3898,7 +3937,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -3947,9 +3985,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, "node_modules/color-convert": { @@ -4001,19 +4039,59 @@ "dev": true }, "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "engines": [ - "node >= 0.8" + "node >= 6.0" ], "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", - "readable-stream": "^2.2.2", + "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/consola": { "version": "2.15.3", "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", @@ -4030,6 +4108,25 @@ "node": ">= 0.6" } }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", @@ -4158,10 +4255,18 @@ } }, "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deep-is": { "version": "0.1.4", @@ -4293,11 +4398,14 @@ } }, "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", + "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, "node_modules/dotenv-cli": { @@ -4329,9 +4437,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.353", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.353.tgz", - "integrity": "sha512-IdJVpMHJoBT/nn0GQ02wPfbhogDVpd1ud95lP//FTf5l35wzxKJwibB4HBdY7Q+xKPA1nkZ0UDLOMyRj5U5IAQ==", + "version": "1.4.492", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.492.tgz", + "integrity": "sha512-36K9b/6skMVwAIEsC7GiQ8I8N3soCALVSHqWHzNDtGemAcI9Xu8hP02cywWM0A794rTHm0b0zHPeLJHtgFVamQ==", "dev": true }, "node_modules/emittery": { @@ -4368,9 +4476,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -4390,9 +4498,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", "dev": true }, "node_modules/escalade": { @@ -4421,27 +4529,27 @@ } }, "node_modules/eslint": { - "version": "8.37.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz", - "integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.37.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4449,22 +4557,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -4478,9 +4583,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", - "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -4524,9 +4629,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4552,9 +4657,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -4562,6 +4667,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { @@ -4592,14 +4700,14 @@ "dev": true }, "node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4689,6 +4797,11 @@ "node": ">= 0.6" } }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -4721,6 +4834,18 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execa/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -4731,16 +4856,17 @@ } }, "node_modules/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.2.tgz", + "integrity": "sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.5.0", + "@jest/expect-utils": "^29.6.2", + "@types/node": "*", "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" + "jest-matcher-utils": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4842,6 +4968,25 @@ "node": ">= 0.8" } }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -4863,15 +5008,15 @@ "dev": true }, "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -5161,9 +5306,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", + "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==", "dev": true }, "node_modules/fs.realpath": { @@ -5229,33 +5374,6 @@ "shp2geobuf": "bin/shp2geobuf" } }, - "node_modules/geobuf/node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/geobuf/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/geographiclib-geodesic": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/geographiclib-geodesic/-/geographiclib-geodesic-2.0.0.tgz", @@ -5270,12 +5388,13 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" }, "funding": { @@ -5292,12 +5411,14 @@ } }, "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5342,9 +5463,9 @@ "dev": true }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5406,10 +5527,10 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has": { @@ -5431,6 +5552,17 @@ "node": ">=8" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -5681,9 +5813,9 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -5782,9 +5914,9 @@ } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/isexe": { "version": "2.0.0", @@ -5818,26 +5950,26 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -5864,9 +5996,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -5924,28 +6056,28 @@ } }, "node_modules/jest-circus": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.2.tgz", + "integrity": "sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.6.2", + "@jest/expect": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-each": "^29.6.2", + "jest-matcher-utils": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-runtime": "^29.6.2", + "jest-snapshot": "^29.6.2", + "jest-util": "^29.6.2", "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.6.2", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -5955,21 +6087,21 @@ } }, "node_modules/jest-cli": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", - "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.2.tgz", + "integrity": "sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q==", "dev": true, "dependencies": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/types": "^29.6.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-config": "^29.6.2", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -5989,31 +6121,31 @@ } }, "node_modules/jest-config": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", - "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.2.tgz", + "integrity": "sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", + "@jest/test-sequencer": "^29.6.2", + "@jest/types": "^29.6.1", + "babel-jest": "^29.6.2", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", + "jest-circus": "^29.6.2", + "jest-environment-node": "^29.6.2", "jest-get-type": "^29.4.3", "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-resolve": "^29.6.2", + "jest-runner": "^29.6.2", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.6.2", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -6034,15 +6166,15 @@ } }, "node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.2.tgz", + "integrity": "sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==", "dev": true, "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.4.3", "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "pretty-format": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6061,33 +6193,33 @@ } }, "node_modules/jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.2.tgz", + "integrity": "sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "chalk": "^4.0.0", "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" + "jest-util": "^29.6.2", + "pretty-format": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", - "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.2.tgz", + "integrity": "sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.6.2", + "@jest/fake-timers": "^29.6.2", + "@jest/types": "^29.6.1", "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-mock": "^29.6.2", + "jest-util": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6103,20 +6235,20 @@ } }, "node_modules/jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.2.tgz", + "integrity": "sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-util": "^29.6.2", + "jest-worker": "^29.6.2", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -6128,46 +6260,46 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", - "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.2.tgz", + "integrity": "sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ==", "dev": true, "dependencies": { "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "pretty-format": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz", + "integrity": "sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.5.0", + "jest-diff": "^29.6.2", "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "pretty-format": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.2.tgz", + "integrity": "sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -6176,14 +6308,14 @@ } }, "node_modules/jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.2.tgz", + "integrity": "sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@types/node": "*", - "jest-util": "^29.5.0" + "jest-util": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -6216,17 +6348,17 @@ } }, "node_modules/jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.2.tgz", + "integrity": "sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.6.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-util": "^29.6.2", + "jest-validate": "^29.6.2", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -6236,43 +6368,43 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", - "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.2.tgz", + "integrity": "sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w==", "dev": true, "dependencies": { "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" + "jest-snapshot": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", - "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.2.tgz", + "integrity": "sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w==", "dev": true, "dependencies": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.6.2", + "@jest/environment": "^29.6.2", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-environment-node": "^29.6.2", + "jest-haste-map": "^29.6.2", + "jest-leak-detector": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-resolve": "^29.6.2", + "jest-runtime": "^29.6.2", + "jest-util": "^29.6.2", + "jest-watcher": "^29.6.2", + "jest-worker": "^29.6.2", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -6300,31 +6432,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.2.tgz", + "integrity": "sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.6.2", + "@jest/fake-timers": "^29.6.2", + "@jest/globals": "^29.6.2", + "@jest/source-map": "^29.6.0", + "@jest/test-result": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", + "jest-haste-map": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-mock": "^29.6.2", "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-resolve": "^29.6.2", + "jest-snapshot": "^29.6.2", + "jest-util": "^29.6.2", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -6333,46 +6465,43 @@ } }, "node_modules/jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.2.tgz", + "integrity": "sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", + "@jest/expect-utils": "^29.6.2", + "@jest/transform": "^29.6.2", + "@jest/types": "^29.6.1", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.5.0", + "expect": "^29.6.2", "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", + "jest-diff": "^29.6.2", "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-matcher-utils": "^29.6.2", + "jest-message-util": "^29.6.2", + "jest-util": "^29.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" + "pretty-format": "^29.6.2", + "semver": "^7.5.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.2.tgz", + "integrity": "sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -6384,47 +6513,35 @@ } }, "node_modules/jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.2.tgz", + "integrity": "sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.5.0" + "pretty-format": "^29.6.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-watcher": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", - "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.2.tgz", + "integrity": "sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA==", "dev": true, "dependencies": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/test-result": "^29.6.2", + "@jest/types": "^29.6.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.5.0", + "jest-util": "^29.6.2", "string-length": "^4.0.1" }, "engines": { @@ -6432,13 +6549,13 @@ } }, "node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.2.tgz", + "integrity": "sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.6.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -6461,16 +6578,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6555,9 +6662,9 @@ } }, "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", "dependencies": { "json-buffer": "3.0.1" } @@ -6594,9 +6701,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.10.26", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.26.tgz", - "integrity": "sha512-oB3l4J5gEhMV+ymmlIjWedsbCpsNRqbEZ/E/MpN2QVyinKNra6DcuXywxSk/72M3DZDoH/6kzurOq1erznBMwQ==" + "version": "1.10.41", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.41.tgz", + "integrity": "sha512-4rmmF4u4vD3eGNuuCGjCPwRwO+fIuu1WWcS7VwbPTiMFkJd8F02v8o5pY5tlYuMR+xOvJ88mtOHpkm0Tnu2LcQ==" }, "node_modules/lines-and-columns": { "version": "1.2.4", @@ -6695,12 +6802,11 @@ } }, "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", + "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "engines": { + "node": "14 || >=16.14" } }, "node_modules/macos-release": { @@ -6716,9 +6822,9 @@ } }, "node_modules/magic-string": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.29.0.tgz", - "integrity": "sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", + "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" @@ -6728,29 +6834,20 @@ } }, "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -6775,12 +6872,12 @@ } }, "node_modules/memfs": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", - "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "fs-monkey": "^1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -6895,9 +6992,9 @@ } }, "node_modules/minipass": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", - "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", "dev": true, "engines": { "node": ">=8" @@ -6936,6 +7033,47 @@ "node": ">= 6.0.0" } }, + "node_modules/multer/node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/multer/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/multer/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/multer/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -6985,6 +7123,14 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/nestjs-request-context": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nestjs-request-context/-/nestjs-request-context-2.1.0.tgz", + "integrity": "sha512-XSZ4CGjgVetyP0q6TSgu+urpUhS8hlY4UxDenPioqEhwpiLCjYFnWrp8NSJctn6NdON5d45LLKz/TN/5ZppL9w==", + "peerDependencies": { + "@nestjs/common": "^9.0.5" + } + }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -7001,9 +7147,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7026,9 +7172,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, "node_modules/normalize-path": { @@ -7114,17 +7260,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -7297,13 +7443,13 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.3.tgz", - "integrity": "sha512-RAmB+n30SlN+HnNx6EbcpoDy9nwdpcGPnEKrJnu6GZoDWBdIjo1UQMVtW2ybtC7LC2oKLcMq8y5g8WnKLiod9g==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "lru-cache": "^7.14.1", - "minipass": "^4.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -7312,13 +7458,13 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", "dev": true, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" } }, "node_modules/path-source": { @@ -7375,9 +7521,9 @@ } }, "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, "engines": { "node": ">= 6" @@ -7466,9 +7612,9 @@ } }, "node_modules/prettier": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", - "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -7493,12 +7639,12 @@ } }, "node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.0", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -7519,13 +7665,13 @@ } }, "node_modules/prisma": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.12.0.tgz", - "integrity": "sha512-xqVper4mbwl32BWzLpdznHAYvYDWQQWK2tBfXjdUD397XaveRyAP7SkBZ6kFlIg8kKayF4hvuaVtYwXd9BodAg==", + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.16.2.tgz", + "integrity": "sha512-SYCsBvDf0/7XSJyf2cHTLjLeTLVXYfqp7pG5eEVafFLeT0u/hLFz/9W196nDRGUOo1JfPatAEb+uEnTQImQC1g==", "devOptional": true, "hasInstallScript": true, "dependencies": { - "@prisma/engines": "4.12.0" + "@prisma/engines": "4.16.2" }, "bin": { "prisma": "build/index.js", @@ -7559,9 +7705,9 @@ } }, "node_modules/protobufjs": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz", - "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", + "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -7582,9 +7728,9 @@ } }, "node_modules/protobufjs/node_modules/long": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", - "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", @@ -7627,9 +7773,9 @@ } }, "node_modules/pure-rand": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", - "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", "dev": true, "funding": [ { @@ -7730,24 +7876,16 @@ "dev": true }, "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dependencies": { "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7819,12 +7957,12 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "dev": true, "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -7922,9 +8060,9 @@ } }, "node_modules/rimraf": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.0.tgz", - "integrity": "sha512-X36S+qpCUR0HjXlkDe4NAOhS//aHH0Z+h8Ckf2auGJk3PTnx5rLmrHkwNdbVQuCSUhOyFrlRvFEllZOYE+yZGQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", "dev": true, "dependencies": { "glob": "^9.2.0" @@ -7949,9 +8087,9 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.4.tgz", - "integrity": "sha512-qaSc49hojMOv1EPM4EuyITjDSgSKI0rthoHnvE81tcOi1SCVndHko7auqxdQ14eiQG2NDBJBE86+2xIrbIvrbA==", + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -7967,9 +8105,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.3.tgz", - "integrity": "sha512-tEEvU9TkZgnFDCtpnrEYnPsjT7iUx42aXfs4bzmQ5sMA09/6hZY0jeZcGkXyDagiBOvkUjNo8Viom+Me6+2x7g==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -8014,31 +8152,17 @@ } }, "node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -8046,9 +8170,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -8095,9 +8219,9 @@ "dev": true }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -8377,17 +8501,9 @@ } }, "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, "node_modules/string-length": { "version": "4.0.2", @@ -8457,9 +8573,9 @@ } }, "node_modules/superagent": { - "version": "8.0.9", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", - "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz", + "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", "dev": true, "dependencies": { "component-emitter": "^1.3.0", @@ -8544,13 +8660,13 @@ } }, "node_modules/terser": { - "version": "5.16.8", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.8.tgz", - "integrity": "sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==", + "version": "5.19.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", + "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -8562,16 +8678,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz", - "integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.5" + "terser": "^5.16.8" }, "engines": { "node": ">= 10.13.0" @@ -8775,9 +8891,9 @@ } }, "node_modules/ts-loader": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", - "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", + "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -8874,9 +8990,9 @@ } }, "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -8995,9 +9111,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "funding": [ { @@ -9007,6 +9123,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { @@ -9014,7 +9134,7 @@ "picocolors": "^1.0.0" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -9086,9 +9206,9 @@ "dev": true }, "node_modules/validator": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", - "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "engines": { "node": ">= 0.10" } @@ -9138,23 +9258,23 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { - "version": "5.78.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.78.0.tgz", - "integrity": "sha512-gT5DP72KInmE/3azEaQrISjTvLYlSM0j1Ezhht/KLVkrqtv10JoP/RXhwmX/frrutOPuSq3o5Vq0ehR/4Vmd1g==", + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "dev": true, "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", + "acorn-import-assertions": "^1.9.0", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -9163,9 +9283,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", + "terser-webpack-plugin": "^5.3.7", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -9276,21 +9396,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/windows-release/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/windows-release/node_modules/human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -9300,15 +9405,6 @@ "node": ">=8.12.0" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -9375,10 +9471,9 @@ } }, "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9396,7 +9491,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, "engines": { "node": ">=12" } diff --git a/package.json b/package.json index 90d5e14..3c727a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mobicoop/matcher", - "version": "0.0.1", + "version": "0.0.2", "description": "Mobicoop V3 Matcher", "author": "sbriat", "private": true, @@ -17,39 +17,37 @@ "lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix-dry-run --ignore-path .gitignore", "pretty:check": "./node_modules/.bin/prettier --check .", "pretty": "./node_modules/.bin/prettier --write .", - "test": "npm run migrate:test && dotenv -e .env.test jest", + "test": "npm run test:unit && npm run test:integration", "test:unit": "jest --testPathPattern 'tests/unit/' --verbose", "test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage", - "test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose", - "test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/' --verbose", + "test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose --runInBand", + "test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/' --runInBand", "test:cov": "jest --testPathPattern 'tests/unit/' --coverage", - "test:cov:watch": "jest --testPathPattern 'tests/unit/' --coverage --watch", "test:e2e": "jest --config ./test/jest-e2e.json", - "generate": "docker exec v3-matcher-api sh -c 'npx prisma generate'", "migrate": "docker exec v3-matcher-api sh -c 'npx prisma migrate dev'", "migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy", "migrate:test:ci": "dotenv -e ci/.env.ci -- npx prisma migrate deploy", "migrate:deploy": "npx prisma migrate deploy" }, "dependencies": { - "@automapper/classes": "^8.7.7", - "@automapper/core": "^8.7.7", - "@automapper/nestjs": "^8.7.7", - "@golevelup/nestjs-rabbitmq": "^3.6.0", - "@grpc/grpc-js": "^1.8.13", + "@grpc/grpc-js": "^1.8.14", "@grpc/proto-loader": "^0.7.6", "@liaoliaots/nestjs-redis": "^9.0.5", - "@mobicoop/configuration-module": "^1.0.0", + "@mobicoop/configuration-module": "^1.2.0", + "@mobicoop/ddd-library": "^1.0.0", + "@mobicoop/health-module": "^2.0.0", + "@mobicoop/message-broker-module": "^1.2.0", "@nestjs/axios": "^2.0.0", "@nestjs/cache-manager": "^1.0.0", "@nestjs/common": "^9.0.0", "@nestjs/config": "^2.3.1", "@nestjs/core": "^9.0.0", "@nestjs/cqrs": "^9.0.3", + "@nestjs/event-emitter": "^1.4.2", "@nestjs/microservices": "^9.4.0", "@nestjs/platform-express": "^9.0.0", "@nestjs/terminus": "^9.2.2", - "@prisma/client": "^4.12.0", + "@prisma/client": "^4.13.0", "axios": "^1.3.5", "cache-manager": "^5.2.0", "cache-manager-ioredis-yet": "^1.1.0", @@ -58,7 +56,8 @@ "geo-tz": "^7.0.7", "geographiclib-geodesic": "^2.0.0", "got": "^11.8.6", - "ioredis": "^5.3.1", + "ioredis": "^5.3.2", + "nestjs-request-context": "^2.1.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.2.0", "timezonecomplete": "^5.12.4" @@ -79,7 +78,7 @@ "eslint-plugin-prettier": "^4.0.0", "jest": "29.5.0", "prettier": "^2.3.2", - "prisma": "^4.12.0", + "prisma": "^4.13.0", "source-map-support": "^0.5.20", "supertest": "^6.1.3", "ts-jest": "29.0.5", @@ -95,15 +94,13 @@ "ts" ], "modulePathIgnorePatterns": [ - ".controller.ts", ".module.ts", - ".request.ts", - ".presenter.ts", - ".profile.ts", - ".exception.ts", - ".enum.ts", - "main.ts", - "prisma-service.ts" + ".dto.ts", + ".di-tokens.ts", + ".response.ts", + ".port.ts", + "prisma.service.ts", + "main.ts" ], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", @@ -114,17 +111,19 @@ "**/*.(t|j)s" ], "coveragePathIgnorePatterns": [ - ".controller.ts", ".module.ts", - ".request.ts", - ".presenter.ts", - ".profile.ts", - ".exception.ts", - ".enum.ts", - "main.ts", - "prisma-service.ts" + ".dto.ts", + ".di-tokens.ts", + ".response.ts", + ".port.ts", + "prisma.service.ts", + "main.ts" ], "coverageDirectory": "../coverage", + "moduleNameMapper": { + "^@modules(.*)": "/modules/$1", + "^@src(.*)": "$1" + }, "testEnvironment": "node" } } diff --git a/prisma/migrations/20230512130750_init/migration.sql b/prisma/migrations/20230512130750_init/migration.sql deleted file mode 100644 index f925dcd..0000000 --- a/prisma/migrations/20230512130750_init/migration.sql +++ /dev/null @@ -1,68 +0,0 @@ --- CreateExtension -CREATE EXTENSION IF NOT EXISTS "postgis"; - --- Required to use postgis extension : --- set the search_path to both public (where is postgis) AND the current schema -SET search_path TO matcher, public; - --- CreateEnum -CREATE TYPE "Frequency" AS ENUM ('PUNCTUAL', 'RECURRENT'); - --- CreateTable -CREATE TABLE "ad" ( - "uuid" UUID NOT NULL, - "userUuid" UUID NOT NULL, - "driver" BOOLEAN NOT NULL, - "passenger" BOOLEAN NOT NULL, - "frequency" "Frequency" NOT NULL, - "fromDate" DATE NOT NULL, - "toDate" DATE NOT NULL, - "monTime" TIMESTAMPTZ, - "tueTime" TIMESTAMPTZ, - "wedTime" TIMESTAMPTZ, - "thuTime" TIMESTAMPTZ, - "friTime" TIMESTAMPTZ, - "satTime" TIMESTAMPTZ, - "sunTime" TIMESTAMPTZ, - "monMargin" INTEGER NOT NULL, - "tueMargin" INTEGER NOT NULL, - "wedMargin" INTEGER NOT NULL, - "thuMargin" INTEGER NOT NULL, - "friMargin" INTEGER NOT NULL, - "satMargin" INTEGER NOT NULL, - "sunMargin" INTEGER NOT NULL, - "driverDuration" INTEGER, - "driverDistance" INTEGER, - "passengerDuration" INTEGER, - "passengerDistance" INTEGER, - "waypoints" geography(LINESTRING), - "direction" geography(LINESTRING), - "fwdAzimuth" INTEGER NOT NULL, - "backAzimuth" INTEGER NOT NULL, - "seatsDriver" SMALLINT NOT NULL, - "seatsPassenger" SMALLINT NOT NULL, - "seatsUsed" SMALLINT NOT NULL, - "strict" BOOLEAN NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - - CONSTRAINT "ad_pkey" PRIMARY KEY ("uuid") -); - --- CreateIndex -CREATE INDEX "ad_driver_idx" ON "ad"("driver"); - --- CreateIndex -CREATE INDEX "ad_passenger_idx" ON "ad"("passenger"); - --- CreateIndex -CREATE INDEX "ad_fromDate_idx" ON "ad"("fromDate"); - --- CreateIndex -CREATE INDEX "ad_toDate_idx" ON "ad"("toDate"); - --- CreateIndex -CREATE INDEX "ad_fwdAzimuth_idx" ON "ad"("fwdAzimuth"); - --- CreateIndex -CREATE INDEX "direction_idx" ON "ad" USING GIST ("direction"); diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml deleted file mode 100644 index fbffa92..0000000 --- a/prisma/migrations/migration_lock.toml +++ /dev/null @@ -1,3 +0,0 @@ -# Please do not edit this file manually -# It should be added in your version-control system (i.e. Git) -provider = "postgresql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 0c3717f..06df3e5 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,20 +21,11 @@ model Ad { frequency Frequency fromDate DateTime @db.Date toDate DateTime @db.Date - monTime DateTime? @db.Timestamptz() - tueTime DateTime? @db.Timestamptz() - wedTime DateTime? @db.Timestamptz() - thuTime DateTime? @db.Timestamptz() - friTime DateTime? @db.Timestamptz() - satTime DateTime? @db.Timestamptz() - sunTime DateTime? @db.Timestamptz() - monMargin Int - tueMargin Int - wedMargin Int - thuMargin Int - friMargin Int - satMargin Int - sunMargin Int + schedule ScheduleItem[] + seatsProposed Int @db.SmallInt + seatsRequested Int @db.SmallInt + seatsUsed Int @db.SmallInt + strict Boolean driverDuration Int? driverDistance Int? passengerDuration Int? @@ -43,10 +34,6 @@ model Ad { direction Unsupported("geography(LINESTRING)")? fwdAzimuth Int backAzimuth Int - seatsDriver Int @db.SmallInt - seatsPassenger Int @db.SmallInt - seatsUsed Int @db.SmallInt - strict Boolean createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt @@ -59,6 +46,19 @@ model Ad { @@map("ad") } +model ScheduleItem { + uuid String @id @default(uuid()) @db.Uuid + adUuid String @db.Uuid + day Int + time DateTime @db.Time(4) + margin Int + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + Ad Ad @relation(fields: [adUuid], references: [uuid], onDelete: Cascade) + + @@map("schedule_item") +} + enum Frequency { PUNCTUAL RECURRENT diff --git a/src/app.module.ts b/src/app.module.ts index f88e28c..e52d97c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,32 +1,66 @@ -import { classes } from '@automapper/classes'; -import { AutomapperModule } from '@automapper/nestjs'; import { Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; -import { HealthModule } from './modules/health/health.module'; -import { MatcherModule } from './modules/matcher/matcher.module'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { AdModule } from './modules/ad/ad.module'; -import { ConfigurationModule } from '@mobicoop/configuration-module'; +import { + ConfigurationModule, + ConfigurationModuleOptions, +} from '@mobicoop/configuration-module'; +import { EventEmitterModule } from '@nestjs/event-emitter'; +import { RequestContextModule } from 'nestjs-request-context'; +import { MessagerModule } from '@modules/messager/messager.module'; +import { HealthModule, HealthRepositoryPort } from '@mobicoop/health-module'; +import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens'; +import { MESSAGE_PUBLISHER } from '@modules/messager/messager.di-tokens'; +import { HealthModuleOptions } from '@mobicoop/health-module/dist/core/domain/types/health.types'; +import { MessagePublisherPort } from '@mobicoop/ddd-library'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), + EventEmitterModule.forRoot(), + RequestContextModule, ConfigurationModule.forRootAsync({ - setConfigurationBrokerRoutingKeys: [ - 'configuration.create', - 'configuration.update', - ], - deleteConfigurationRoutingKey: 'configuration.delete', - propagateConfigurationRoutingKey: 'configuration.propagate', - setConfigurationBrokerQueue: 'matcher-configuration-create-update', - deleteConfigurationQueue: 'matcher-configuration-delete', - propagateConfigurationQueue: 'matcher-configuration-propagate', + imports: [ConfigModule], + inject: [ConfigService], + useFactory: async ( + configService: ConfigService, + ): Promise => ({ + domain: configService.get('SERVICE_CONFIGURATION_DOMAIN'), + messageBroker: { + uri: configService.get('MESSAGE_BROKER_URI'), + exchange: configService.get('MESSAGE_BROKER_EXCHANGE'), + }, + redis: { + host: configService.get('REDIS_HOST'), + password: configService.get('REDIS_PASSWORD'), + port: configService.get('REDIS_PORT'), + }, + setConfigurationBrokerQueue: 'matcher-configuration-create-update', + deleteConfigurationQueue: 'matcher-configuration-delete', + propagateConfigurationQueue: 'matcher-configuration-propagate', + }), + }), + HealthModule.forRootAsync({ + imports: [AdModule, MessagerModule], + inject: [AD_REPOSITORY, MESSAGE_PUBLISHER], + useFactory: async ( + adRepository: HealthRepositoryPort, + messagePublisher: MessagePublisherPort, + ): Promise => ({ + serviceName: 'matcher', + criticalLoggingKey: 'logging.matcher.health.crit', + checkRepositories: [ + { + name: 'AdRepository', + repository: adRepository, + }, + ], + messagePublisher, + }), }), - AutomapperModule.forRoot({ strategyInitializer: classes() }), - HealthModule, - MatcherModule, AdModule, + MessagerModule, ], - controllers: [], - providers: [], + exports: [AdModule, MessagerModule], }) export class AppModule {} diff --git a/src/health.proto b/src/health.proto new file mode 100644 index 0000000..556c72b --- /dev/null +++ b/src/health.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package health; + +service Health { + rpc Check(HealthCheckRequest) returns (HealthCheckResponse); +} + +message HealthCheckRequest { + string service = 1; +} + +message HealthCheckResponse { + enum ServingStatus { + UNKNOWN = 0; + SERVING = 1; + NOT_SERVING = 2; + } + ServingStatus status = 1; + string message = 2; +} diff --git a/src/modules/ad/ad.di-tokens.ts b/src/modules/ad/ad.di-tokens.ts new file mode 100644 index 0000000..1750029 --- /dev/null +++ b/src/modules/ad/ad.di-tokens.ts @@ -0,0 +1,5 @@ +export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER'); +export const PARAMS_PROVIDER = Symbol('PARAMS_PROVIDER'); +export const TIMEZONE_FINDER = Symbol('TIMEZONE_FINDER'); +export const GEOROUTER_CREATOR = Symbol('GEOROUTER_CREATOR'); +export const AD_REPOSITORY = Symbol('AD_REPOSITORY'); diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts new file mode 100644 index 0000000..361e1f0 --- /dev/null +++ b/src/modules/ad/ad.mapper.ts @@ -0,0 +1,111 @@ +import { Mapper } from '@mobicoop/ddd-library'; +import { Injectable } from '@nestjs/common'; +import { AdEntity } from './core/domain/ad.entity'; +import { + AdWriteModel, + AdReadModel, + ScheduleItemModel, +} from './infrastructure/ad.repository'; +import { Frequency } from './core/domain/ad.types'; +import { v4 } from 'uuid'; +import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object'; + +/** + * Mapper constructs objects that are used in different layers: + * Record is an object that is stored in a database, + * Entity is an object that is used in application domain layer, + * and a ResponseDTO is an object returned to a user (usually as json). + */ + +@Injectable() +export class AdMapper + implements Mapper +{ + toPersistence = (entity: AdEntity): AdWriteModel => { + const copy = entity.getProps(); + const now = new Date(); + const record: AdWriteModel = { + uuid: copy.id, + userUuid: copy.userId, + driver: copy.driver, + passenger: copy.passenger, + frequency: copy.frequency, + fromDate: new Date(copy.fromDate), + toDate: new Date(copy.toDate), + schedule: { + create: copy.schedule.map((scheduleItem: ScheduleItemProps) => ({ + uuid: v4(), + day: scheduleItem.day, + time: new Date( + 1970, + 0, + 1, + parseInt(scheduleItem.time.split(':')[0]), + parseInt(scheduleItem.time.split(':')[1]), + ), + margin: scheduleItem.margin, + createdAt: now, + updatedAt: now, + })), + }, + seatsProposed: copy.seatsProposed, + seatsRequested: copy.seatsRequested, + strict: copy.strict, + driverDuration: copy.driverDuration, + driverDistance: copy.driverDistance, + passengerDuration: copy.passengerDuration, + passengerDistance: copy.passengerDistance, + waypoints: copy.waypoints, + direction: copy.direction, + fwdAzimuth: copy.fwdAzimuth, + backAzimuth: copy.backAzimuth, + createdAt: copy.createdAt, + updatedAt: copy.updatedAt, + }; + return record; + }; + + toDomain = (record: AdReadModel): AdEntity => { + const entity = new AdEntity({ + id: record.uuid, + createdAt: new Date(record.createdAt), + updatedAt: new Date(record.updatedAt), + props: { + userId: record.userUuid, + driver: record.driver, + passenger: record.passenger, + frequency: Frequency[record.frequency], + fromDate: record.fromDate.toISOString().split('T')[0], + toDate: record.toDate.toISOString().split('T')[0], + schedule: record.schedule.map((scheduleItem: ScheduleItemModel) => ({ + day: scheduleItem.day, + time: `${scheduleItem.time + .getUTCHours() + .toString() + .padStart(2, '0')}:${scheduleItem.time + .getUTCMinutes() + .toString() + .padStart(2, '0')}`, + margin: scheduleItem.margin, + })), + seatsProposed: record.seatsProposed, + seatsRequested: record.seatsRequested, + strict: record.strict, + driverDuration: record.driverDuration, + driverDistance: record.driverDistance, + passengerDuration: record.passengerDuration, + passengerDistance: record.passengerDistance, + waypoints: record.waypoints, + direction: record.direction, + fwdAzimuth: record.fwdAzimuth, + backAzimuth: record.backAzimuth, + }, + }); + return entity; + }; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + toResponse = (entity: AdEntity): undefined => { + return undefined; + }; +} diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index 3a936b0..1e85849 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -1,72 +1,61 @@ -import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; -import { Module } from '@nestjs/common'; -import { ConfigModule, ConfigService } from '@nestjs/config'; -import { AdMessagerController } from './adapters/primaries/ad-messager.controller'; -import { AdProfile } from './mappers/ad.profile'; -import { CreateAdUseCase } from './domain/usecases/create-ad.usecase'; -import { AdRepository } from './adapters/secondaries/ad.repository'; -import { DatabaseModule } from '../database/database.module'; +import { Module, Provider } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; -import { Messager } from './adapters/secondaries/messager'; -import { GeoTimezoneFinder } from '../geography/adapters/secondaries/geo-timezone-finder'; -import { DefaultParamsProvider } from './adapters/secondaries/default-params.provider'; -import { GeorouterCreator } from '../geography/adapters/secondaries/georouter-creator'; -import { GeographyModule } from '../geography/geography.module'; -import { HttpModule } from '@nestjs/axios'; -import { PostgresDirectionEncoder } from '../geography/adapters/secondaries/postgres-direction-encoder'; +import { + AD_MESSAGE_PUBLISHER, + AD_REPOSITORY, + PARAMS_PROVIDER, + TIMEZONE_FINDER, +} from './ad.di-tokens'; +import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; +import { AdRepository } from './infrastructure/ad.repository'; +import { PrismaService } from './infrastructure/prisma.service'; +import { DefaultParamsProvider } from './infrastructure/default-params-provider'; +import { TimezoneFinder } from './infrastructure/timezone-finder'; +import { AdMapper } from './ad.mapper'; + +const mappers: Provider[] = [AdMapper]; + +const repositories: Provider[] = [ + { + provide: AD_REPOSITORY, + useClass: AdRepository, + }, +]; + +const messagePublishers: Provider[] = [ + { + provide: AD_MESSAGE_PUBLISHER, + useExisting: MessageBrokerPublisher, + }, +]; +const orms: Provider[] = [PrismaService]; + +const adapters: Provider[] = [ + { + provide: PARAMS_PROVIDER, + useClass: DefaultParamsProvider, + }, + { + provide: TIMEZONE_FINDER, + useClass: TimezoneFinder, + }, +]; @Module({ - imports: [ - GeographyModule, - DatabaseModule, - CqrsModule, - HttpModule, - RabbitMQModule.forRootAsync(RabbitMQModule, { - imports: [ConfigModule], - useFactory: async (configService: ConfigService) => ({ - exchanges: [ - { - name: configService.get('RMQ_EXCHANGE'), - type: 'topic', - }, - ], - handlers: { - adCreated: { - exchange: configService.get('RMQ_EXCHANGE'), - routingKey: 'ad.created', - queue: 'matcher-ad-created', - }, - }, - uri: configService.get('RMQ_URI'), - connectionInitOptions: { wait: false }, - enableControllerDiscovery: true, - }), - inject: [ConfigService], - }), - ], - controllers: [AdMessagerController], + imports: [CqrsModule], providers: [ - { - provide: 'ParamsProvider', - useClass: DefaultParamsProvider, - }, - { - provide: 'GeorouterCreator', - useClass: GeorouterCreator, - }, - { - provide: 'TimezoneFinder', - useClass: GeoTimezoneFinder, - }, - { - provide: 'DirectionEncoder', - useClass: PostgresDirectionEncoder, - }, - AdProfile, - Messager, - AdRepository, - CreateAdUseCase, + ...mappers, + ...repositories, + ...messagePublishers, + ...orms, + ...adapters, + ], + exports: [ + PrismaService, + AdMapper, + AD_REPOSITORY, + PARAMS_PROVIDER, + TIMEZONE_FINDER, ], - exports: [], }) export class AdModule {} diff --git a/src/modules/ad/adapters/secondaries/message-broker.ts b/src/modules/ad/adapters/secondaries/message-broker.ts deleted file mode 100644 index 7b4f4df..0000000 --- a/src/modules/ad/adapters/secondaries/message-broker.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export abstract class MessageBroker { - exchange: string; - - constructor(exchange: string) { - this.exchange = exchange; - } - - abstract publish(routingKey: string, message: string): void; -} diff --git a/src/modules/ad/adapters/secondaries/messager.ts b/src/modules/ad/adapters/secondaries/messager.ts deleted file mode 100644 index 1888b7d..0000000 --- a/src/modules/ad/adapters/secondaries/messager.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { MessageBroker } from './message-broker'; - -@Injectable() -export class Messager extends MessageBroker { - constructor( - private readonly amqpConnection: AmqpConnection, - configService: ConfigService, - ) { - super(configService.get('RMQ_EXCHANGE')); - } - - publish = (routingKey: string, message: string): void => { - this.amqpConnection.publish(this.exchange, routingKey, message); - }; -} diff --git a/src/modules/ad/core/application/ports/ad.repository.port.ts b/src/modules/ad/core/application/ports/ad.repository.port.ts new file mode 100644 index 0000000..5b9fe49 --- /dev/null +++ b/src/modules/ad/core/application/ports/ad.repository.port.ts @@ -0,0 +1,4 @@ +import { RepositoryPort } from '@mobicoop/ddd-library'; +import { AdEntity } from '../../domain/ad.entity'; + +export type AdRepositoryPort = RepositoryPort; diff --git a/src/modules/ad/core/application/ports/default-params-provider.port.ts b/src/modules/ad/core/application/ports/default-params-provider.port.ts new file mode 100644 index 0000000..e316b77 --- /dev/null +++ b/src/modules/ad/core/application/ports/default-params-provider.port.ts @@ -0,0 +1,5 @@ +import { DefaultParams } from './default-params.type'; + +export interface DefaultParamsProviderPort { + getParams(): DefaultParams; +} diff --git a/src/modules/ad/core/application/ports/default-params.type.ts b/src/modules/ad/core/application/ports/default-params.type.ts new file mode 100644 index 0000000..bea841b --- /dev/null +++ b/src/modules/ad/core/application/ports/default-params.type.ts @@ -0,0 +1,5 @@ +export type DefaultParams = { + DEFAULT_TIMEZONE: string; + GEOROUTER_TYPE: string; + GEOROUTER_URL: string; +}; diff --git a/src/modules/ad/core/application/ports/timezone-finder.port.ts b/src/modules/ad/core/application/ports/timezone-finder.port.ts new file mode 100644 index 0000000..72ba115 --- /dev/null +++ b/src/modules/ad/core/application/ports/timezone-finder.port.ts @@ -0,0 +1,3 @@ +export interface TimezoneFinderPort { + timezones(lon: number, lat: number, defaultTimezone?: string): string[]; +} diff --git a/src/modules/ad/core/domain/ad.entity.ts b/src/modules/ad/core/domain/ad.entity.ts new file mode 100644 index 0000000..fc51d13 --- /dev/null +++ b/src/modules/ad/core/domain/ad.entity.ts @@ -0,0 +1,16 @@ +import { AggregateRoot, AggregateID } from '@mobicoop/ddd-library'; +import { AdProps, CreateAdProps } from './ad.types'; + +export class AdEntity extends AggregateRoot { + protected readonly _id: AggregateID; + + static create = (create: CreateAdProps): AdEntity => { + const props: AdProps = { ...create }; + const ad = new AdEntity({ id: create.id, props }); + return ad; + }; + + validate(): void { + // entity business rules validation to protect it's invariant before saving entity to a database + } +} diff --git a/src/modules/ad/core/domain/ad.types.ts b/src/modules/ad/core/domain/ad.types.ts new file mode 100644 index 0000000..a3dbb42 --- /dev/null +++ b/src/modules/ad/core/domain/ad.types.ts @@ -0,0 +1,51 @@ +import { ScheduleItemProps } from './value-objects/schedule-item.value-object'; + +// All properties that an Ad has +export interface AdProps { + userId: string; + driver: boolean; + passenger: boolean; + frequency: Frequency; + fromDate: string; + toDate: string; + schedule: ScheduleItemProps[]; + seatsProposed: number; + seatsRequested: number; + strict: boolean; + driverDuration: number; + driverDistance: number; + passengerDuration: number; + passengerDistance: number; + waypoints: string; + direction: string; + fwdAzimuth: number; + backAzimuth: number; +} + +// Properties that are needed for an Ad creation +export interface CreateAdProps { + id: string; + userId: string; + driver: boolean; + passenger: boolean; + frequency: Frequency; + fromDate: string; + toDate: string; + schedule: ScheduleItemProps[]; + seatsProposed: number; + seatsRequested: number; + strict: boolean; + driverDuration: number; + driverDistance: number; + passengerDuration: number; + passengerDistance: number; + waypoints: string; + direction: string; + fwdAzimuth: number; + backAzimuth: number; +} + +export enum Frequency { + PUNCTUAL = 'PUNCTUAL', + RECURRENT = 'RECURRENT', +} diff --git a/src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts b/src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts new file mode 100644 index 0000000..8303eeb --- /dev/null +++ b/src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts @@ -0,0 +1,31 @@ +import { ValueObject } from '@mobicoop/ddd-library'; + +/** Note: + * Value Objects with multiple properties can contain + * other Value Objects inside if needed. + * */ + +export interface ScheduleItemProps { + day?: number; + time: string; + margin?: number; +} + +export class ScheduleItem extends ValueObject { + get day(): number | undefined { + return this.props.day; + } + + get time(): string { + return this.props.time; + } + + get margin(): number | undefined { + return this.props.margin; + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + protected validate(props: ScheduleItemProps): void { + return; + } +} diff --git a/src/modules/ad/infrastructure/ad.repository.ts b/src/modules/ad/infrastructure/ad.repository.ts new file mode 100644 index 0000000..5a8d4e5 --- /dev/null +++ b/src/modules/ad/infrastructure/ad.repository.ts @@ -0,0 +1,83 @@ +import { Inject, Injectable, Logger } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; +import { AdRepositoryPort } from '../core/application/ports/ad.repository.port'; +import { + LoggerBase, + MessagePublisherPort, + PrismaRepositoryBase, +} from '@mobicoop/ddd-library'; +import { PrismaService } from './prisma.service'; +import { AD_MESSAGE_PUBLISHER } from '../ad.di-tokens'; +import { AdEntity } from '../core/domain/ad.entity'; +import { AdMapper } from '../ad.mapper'; + +export type AdBaseModel = { + uuid: string; + userUuid: string; + driver: boolean; + passenger: boolean; + frequency: string; + fromDate: Date; + toDate: Date; + seatsProposed: number; + seatsRequested: number; + strict: boolean; + driverDuration: number; + driverDistance: number; + passengerDuration: number; + passengerDistance: number; + waypoints: string; + direction: string; + fwdAzimuth: number; + backAzimuth: number; + createdAt: Date; + updatedAt: Date; +}; + +export type AdReadModel = AdBaseModel & { + schedule: ScheduleItemModel[]; +}; + +export type AdWriteModel = AdBaseModel & { + schedule: { + create: ScheduleItemModel[]; + }; +}; + +export type ScheduleItemModel = { + uuid: string; + day: number; + time: Date; + margin: number; + createdAt: Date; + updatedAt: Date; +}; + +/** + * Repository is used for retrieving/saving domain entities + * */ +@Injectable() +export class AdRepository + extends PrismaRepositoryBase + implements AdRepositoryPort +{ + constructor( + prisma: PrismaService, + mapper: AdMapper, + eventEmitter: EventEmitter2, + @Inject(AD_MESSAGE_PUBLISHER) + protected readonly messagePublisher: MessagePublisherPort, + ) { + super( + prisma.ad, + prisma, + mapper, + eventEmitter, + new LoggerBase({ + logger: new Logger(AdRepository.name), + domain: 'matcher', + messagePublisher, + }), + ); + } +} diff --git a/src/modules/ad/infrastructure/default-params-provider.ts b/src/modules/ad/infrastructure/default-params-provider.ts new file mode 100644 index 0000000..305987b --- /dev/null +++ b/src/modules/ad/infrastructure/default-params-provider.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { DefaultParamsProviderPort } from '../core/application/ports/default-params-provider.port'; +import { DefaultParams } from '../core/application/ports/default-params.type'; + +@Injectable() +export class DefaultParamsProvider implements DefaultParamsProviderPort { + constructor(private readonly _configService: ConfigService) {} + getParams = (): DefaultParams => ({ + GEOROUTER_TYPE: this._configService.get('GEOROUTER_TYPE'), + GEOROUTER_URL: this._configService.get('GEOROUTER_URL'), + DEFAULT_TIMEZONE: this._configService.get('DEFAULT_TIMEZONE'), + }); +} diff --git a/src/modules/ad/infrastructure/prisma.service.ts b/src/modules/ad/infrastructure/prisma.service.ts new file mode 100644 index 0000000..edf6532 --- /dev/null +++ b/src/modules/ad/infrastructure/prisma.service.ts @@ -0,0 +1,15 @@ +import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class PrismaService extends PrismaClient implements OnModuleInit { + async onModuleInit() { + await this.$connect(); + } + + async enableShutdownHooks(app: INestApplication) { + this.$on('beforeExit', async () => { + await app.close(); + }); + } +} diff --git a/src/modules/ad/infrastructure/timezone-finder.ts b/src/modules/ad/infrastructure/timezone-finder.ts new file mode 100644 index 0000000..feb0b5a --- /dev/null +++ b/src/modules/ad/infrastructure/timezone-finder.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@nestjs/common'; +import { find } from 'geo-tz'; +import { TimezoneFinderPort } from '../core/application/ports/timezone-finder.port'; + +@Injectable() +export class TimezoneFinder implements TimezoneFinderPort { + timezones = ( + lon: number, + lat: number, + defaultTimezone?: string, + ): string[] => { + const foundTimezones = find(lat, lon); + if (defaultTimezone && foundTimezones.length == 0) return [defaultTimezone]; + return foundTimezones; + }; +} diff --git a/src/modules/ad/tests/unit/adapters/secondaries/messager.spec.ts b/src/modules/ad/tests/unit/adapters/secondaries/messager.spec.ts deleted file mode 100644 index 0bd23a9..0000000 --- a/src/modules/ad/tests/unit/adapters/secondaries/messager.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { ConfigService } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { Messager } from '../../../../adapters/secondaries/messager'; - -const mockAmqpConnection = { - publish: jest.fn().mockImplementation(), -}; - -const mockConfigService = { - get: jest.fn().mockResolvedValue({ - RMQ_EXCHANGE: 'mobicoop', - }), -}; - -describe('Messager', () => { - let messager: Messager; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - Messager, - { - provide: AmqpConnection, - useValue: mockAmqpConnection, - }, - { - provide: ConfigService, - useValue: mockConfigService, - }, - ], - }).compile(); - - messager = module.get(Messager); - }); - - it('should be defined', () => { - expect(messager).toBeDefined(); - }); - - it('should publish a message', async () => { - jest.spyOn(mockAmqpConnection, 'publish'); - messager.publish('test.create.info', 'my-test'); - expect(mockAmqpConnection.publish).toHaveBeenCalledTimes(1); - }); -}); diff --git a/src/modules/health/adapters/primaries/health.controller.ts b/src/modules/health/adapters/primaries/health.controller.ts deleted file mode 100644 index f9c59ed..0000000 --- a/src/modules/health/adapters/primaries/health.controller.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { - HealthCheckService, - HealthCheck, - HealthCheckResult, -} from '@nestjs/terminus'; -import { Messager } from '../secondaries/messager'; -import { PrismaHealthIndicatorUseCase } from '../../domain/usecases/prisma.health-indicator.usecase'; - -@Controller('health') -export class HealthController { - constructor( - private readonly prismaHealthIndicatorUseCase: PrismaHealthIndicatorUseCase, - private healthCheckService: HealthCheckService, - private messager: Messager, - ) {} - - @Get() - @HealthCheck() - async check() { - try { - return await this.healthCheckService.check([ - async () => this.prismaHealthIndicatorUseCase.isHealthy('prisma'), - ]); - } catch (error) { - const healthCheckResult: HealthCheckResult = error.response; - this.messager.publish( - 'logging.matcher.health.crit', - JSON.stringify(healthCheckResult.error), - ); - throw error; - } - } -} diff --git a/src/modules/health/adapters/secondaries/message-broker.ts b/src/modules/health/adapters/secondaries/message-broker.ts deleted file mode 100644 index 594aa43..0000000 --- a/src/modules/health/adapters/secondaries/message-broker.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export abstract class IMessageBroker { - exchange: string; - - constructor(exchange: string) { - this.exchange = exchange; - } - - abstract publish(routingKey: string, message: string): void; -} diff --git a/src/modules/health/adapters/secondaries/messager.ts b/src/modules/health/adapters/secondaries/messager.ts deleted file mode 100644 index cd7e7ef..0000000 --- a/src/modules/health/adapters/secondaries/messager.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { IMessageBroker } from './message-broker'; - -@Injectable() -export class Messager extends IMessageBroker { - constructor( - private readonly amqpConnection: AmqpConnection, - configService: ConfigService, - ) { - super(configService.get('RMQ_EXCHANGE')); - } - - publish = (routingKey: string, message: string): void => { - this.amqpConnection.publish(this.exchange, routingKey, message); - }; -} diff --git a/src/modules/health/domain/usecases/prisma.health-indicator.usecase.ts b/src/modules/health/domain/usecases/prisma.health-indicator.usecase.ts deleted file mode 100644 index be8520e..0000000 --- a/src/modules/health/domain/usecases/prisma.health-indicator.usecase.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { - HealthCheckError, - HealthIndicator, - HealthIndicatorResult, -} from '@nestjs/terminus'; -import { AdRepository } from '../../../ad/adapters/secondaries/ad.repository'; - -@Injectable() -export class PrismaHealthIndicatorUseCase extends HealthIndicator { - constructor(private readonly repository: AdRepository) { - super(); - } - - isHealthy = async (key: string): Promise => { - try { - await this.repository.healthCheck(); - return this.getStatus(key, true); - } catch (e) { - throw new HealthCheckError('Prisma', { - prisma: e.message, - }); - } - }; -} diff --git a/src/modules/health/health.module.ts b/src/modules/health/health.module.ts deleted file mode 100644 index 3a62c64..0000000 --- a/src/modules/health/health.module.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Module } from '@nestjs/common'; -import { HealthServerController } from './adapters/primaries/health-server.controller'; -import { PrismaHealthIndicatorUseCase } from './domain/usecases/prisma.health-indicator.usecase'; -import { DatabaseModule } from '../database/database.module'; -import { HealthController } from './adapters/primaries/health.controller'; -import { TerminusModule } from '@nestjs/terminus'; -import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq'; -import { ConfigModule, ConfigService } from '@nestjs/config'; -import { Messager } from './adapters/secondaries/messager'; -import { AdRepository } from '../ad/adapters/secondaries/ad.repository'; - -@Module({ - imports: [ - TerminusModule, - RabbitMQModule.forRootAsync(RabbitMQModule, { - imports: [ConfigModule], - useFactory: async (configService: ConfigService) => ({ - exchanges: [ - { - name: configService.get('RMQ_EXCHANGE'), - type: 'topic', - }, - ], - uri: configService.get('RMQ_URI'), - connectionInitOptions: { wait: false }, - }), - inject: [ConfigService], - }), - DatabaseModule, - ], - controllers: [HealthServerController, HealthController], - providers: [PrismaHealthIndicatorUseCase, AdRepository, Messager], -}) -export class HealthModule {} diff --git a/src/modules/health/tests/unit/messager.spec.ts b/src/modules/health/tests/unit/messager.spec.ts deleted file mode 100644 index 0331332..0000000 --- a/src/modules/health/tests/unit/messager.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { ConfigService } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { Messager } from '../../adapters/secondaries/messager'; - -const mockAmqpConnection = { - publish: jest.fn().mockImplementation(), -}; - -const mockConfigService = { - get: jest.fn().mockResolvedValue({ - RMQ_EXCHANGE: 'mobicoop', - }), -}; - -describe('Messager', () => { - let messager: Messager; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - Messager, - { - provide: AmqpConnection, - useValue: mockAmqpConnection, - }, - { - provide: ConfigService, - useValue: mockConfigService, - }, - ], - }).compile(); - - messager = module.get(Messager); - }); - - it('should be defined', () => { - expect(messager).toBeDefined(); - }); - - it('should publish a message', async () => { - jest.spyOn(mockAmqpConnection, 'publish'); - messager.publish('test.create.info', 'my-test'); - expect(mockAmqpConnection.publish).toHaveBeenCalledTimes(1); - }); -}); diff --git a/src/modules/matcher/adapters/secondaries/message-broker.ts b/src/modules/matcher/adapters/secondaries/message-broker.ts deleted file mode 100644 index 7b4f4df..0000000 --- a/src/modules/matcher/adapters/secondaries/message-broker.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export abstract class MessageBroker { - exchange: string; - - constructor(exchange: string) { - this.exchange = exchange; - } - - abstract publish(routingKey: string, message: string): void; -} diff --git a/src/modules/matcher/adapters/secondaries/messager.ts b/src/modules/matcher/adapters/secondaries/messager.ts deleted file mode 100644 index 96fa7cc..0000000 --- a/src/modules/matcher/adapters/secondaries/messager.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { MessageBroker } from './message-broker'; - -@Injectable() -export class Messager extends MessageBroker { - constructor( - private readonly _amqpConnection: AmqpConnection, - configService: ConfigService, - ) { - super(configService.get('RMQ_EXCHANGE')); - } - - publish = (routingKey: string, message: string): void => { - this._amqpConnection.publish(this.exchange, routingKey, message); - }; -} diff --git a/src/modules/matcher/domain/types/path.type.ts b/src/modules/matcher/domain/types/path.type.ts deleted file mode 100644 index 44e03b6..0000000 --- a/src/modules/matcher/domain/types/path.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Point } from '../../../geography/domain/types/point.type'; - -export type Path = { - key: string; - points: Point[]; -}; diff --git a/src/modules/matcher/tests/unit/adapters/secondaries/messager.spec.ts b/src/modules/matcher/tests/unit/adapters/secondaries/messager.spec.ts deleted file mode 100644 index 0bd23a9..0000000 --- a/src/modules/matcher/tests/unit/adapters/secondaries/messager.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { AmqpConnection } from '@golevelup/nestjs-rabbitmq'; -import { ConfigService } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { Messager } from '../../../../adapters/secondaries/messager'; - -const mockAmqpConnection = { - publish: jest.fn().mockImplementation(), -}; - -const mockConfigService = { - get: jest.fn().mockResolvedValue({ - RMQ_EXCHANGE: 'mobicoop', - }), -}; - -describe('Messager', () => { - let messager: Messager; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - Messager, - { - provide: AmqpConnection, - useValue: mockAmqpConnection, - }, - { - provide: ConfigService, - useValue: mockConfigService, - }, - ], - }).compile(); - - messager = module.get(Messager); - }); - - it('should be defined', () => { - expect(messager).toBeDefined(); - }); - - it('should publish a message', async () => { - jest.spyOn(mockAmqpConnection, 'publish'); - messager.publish('test.create.info', 'my-test'); - expect(mockAmqpConnection.publish).toHaveBeenCalledTimes(1); - }); -}); diff --git a/src/modules/messager/messager.di-tokens.ts b/src/modules/messager/messager.di-tokens.ts new file mode 100644 index 0000000..48e8011 --- /dev/null +++ b/src/modules/messager/messager.di-tokens.ts @@ -0,0 +1 @@ +export const MESSAGE_PUBLISHER = Symbol('MESSAGE_PUBLISHER'); diff --git a/src/modules/messager/messager.module.ts b/src/modules/messager/messager.module.ts new file mode 100644 index 0000000..896c300 --- /dev/null +++ b/src/modules/messager/messager.module.ts @@ -0,0 +1,36 @@ +import { Module, Provider } from '@nestjs/common'; +import { MESSAGE_PUBLISHER } from './messager.di-tokens'; +import { + MessageBrokerModule, + MessageBrokerModuleOptions, + MessageBrokerPublisher, +} from '@mobicoop/message-broker-module'; +import { ConfigModule, ConfigService } from '@nestjs/config'; + +const imports = [ + MessageBrokerModule.forRootAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: async ( + configService: ConfigService, + ): Promise => ({ + uri: configService.get('MESSAGE_BROKER_URI'), + exchange: configService.get('MESSAGE_BROKER_EXCHANGE'), + name: 'matcher', + }), + }), +]; + +const providers: Provider[] = [ + { + provide: MESSAGE_PUBLISHER, + useClass: MessageBrokerPublisher, + }, +]; + +@Module({ + imports, + providers, + exports: [MESSAGE_PUBLISHER], +}) +export class MessagerModule {} diff --git a/tsconfig.json b/tsconfig.json index adb614c..ed12947 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,6 +16,11 @@ "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, - "noFallthroughCasesInSwitch": false + "noFallthroughCasesInSwitch": false, + "paths": { + "@libs/*": ["src/libs/*"], + "@modules/*": ["src/modules/*"], + "@src/*": ["src/*"] + } } } From db13f4d87e57fd2993d30d14a180b710f3ea8f1a Mon Sep 17 00:00:00 2001 From: sbriat Date: Fri, 18 Aug 2023 12:47:51 +0200 Subject: [PATCH 02/24] basic ad entity without direction --- .env.dist | 2 - prisma/schema.prisma | 1 - src/app.module.ts | 2 + src/modules/ad/ad.di-tokens.ts | 6 +- src/modules/ad/ad.mapper.ts | 9 +- src/modules/ad/ad.module.ts | 33 +---- .../commands/create-ad/create-ad.command.ts | 33 +++++ .../commands/create-ad/create-ad.service.ts | 42 +++++++ .../application/ports/timezone-finder.port.ts | 3 - .../application/types/schedule-item.type.ts | 5 + .../core/application/types/waypoint.type.ts | 8 ++ src/modules/ad/core/domain/ad.entity.ts | 3 +- src/modules/ad/core/domain/ad.errors.ts | 11 ++ src/modules/ad/core/domain/ad.types.ts | 35 +++--- .../schedule-item.value-object.ts | 25 +++- .../value-objects/waypoint.value-object.ts | 47 +++++++ .../ad/infrastructure/ad.repository.ts | 1 - .../ad/infrastructure/timezone-finder.ts | 16 --- .../ad-created.message-handler.ts | 34 +++++ .../ad/interface/message-handlers/ad.types.ts | 35 ++++++ src/modules/ad/tests/unit/ad.mapper.spec.ts | 107 ++++++++++++++++ .../ad/tests/unit/core/ad.entity.spec.ts | 47 +++++++ .../tests/unit/core/create-ad.service.spec.ts | 103 +++++++++++++++ .../core/schedule-item.value-object.spec.ts | 62 ++++++++++ .../unit/core/waypoint.value-object.spec.ts | 83 +++++++++++++ .../unit/infrastructure/ad.repository.spec.ts | 36 ++++++ .../ad-created.message-handler.spec.ts | 44 +++++++ .../ports/default-params-provider.port.ts | 2 +- .../ports/direction-encoder.port.ts | 5 + .../core/application/ports/geodesic.port.ts | 11 ++ .../ports/georouter-creator.port.ts | 5 + .../core/application/ports/georouter.port.ts | 7 ++ .../application/types/coordinates.type.ts | 4 + .../application/types}/default-params.type.ts | 1 - .../types/georouter-settings.type.ts | 5 + .../core/application/types/path.type.ts | 7 ++ .../core/application/types/point.type.ts | 6 + .../core/application/types/route.type.ts | 11 ++ .../geography/core/domain/route.entity.ts | 117 ++++++++++++++++++ .../geography/core/domain/route.types.ts | 54 ++++++++ .../value-objects/timepoint.value-object.ts | 42 +++++++ .../value-objects/waypoint.value-object.ts | 47 +++++++ src/modules/geography/geography.di-tokens.ts | 2 + src/modules/geography/geography.module.ts | 23 ++++ .../infrastructure/default-params-provider.ts | 3 +- .../postgres-direction-encoder.ts | 11 ++ src/modules/messager/messager.module.ts | 14 +++ 47 files changed, 1122 insertions(+), 88 deletions(-) create mode 100644 src/modules/ad/core/application/commands/create-ad/create-ad.command.ts create mode 100644 src/modules/ad/core/application/commands/create-ad/create-ad.service.ts delete mode 100644 src/modules/ad/core/application/ports/timezone-finder.port.ts create mode 100644 src/modules/ad/core/application/types/schedule-item.type.ts create mode 100644 src/modules/ad/core/application/types/waypoint.type.ts create mode 100644 src/modules/ad/core/domain/ad.errors.ts create mode 100644 src/modules/ad/core/domain/value-objects/waypoint.value-object.ts delete mode 100644 src/modules/ad/infrastructure/timezone-finder.ts create mode 100644 src/modules/ad/interface/message-handlers/ad-created.message-handler.ts create mode 100644 src/modules/ad/interface/message-handlers/ad.types.ts create mode 100644 src/modules/ad/tests/unit/ad.mapper.spec.ts create mode 100644 src/modules/ad/tests/unit/core/ad.entity.spec.ts create mode 100644 src/modules/ad/tests/unit/core/create-ad.service.spec.ts create mode 100644 src/modules/ad/tests/unit/core/schedule-item.value-object.spec.ts create mode 100644 src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts create mode 100644 src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts create mode 100644 src/modules/ad/tests/unit/interface/ad-created.message-handler.spec.ts rename src/modules/{ad => geography}/core/application/ports/default-params-provider.port.ts (55%) create mode 100644 src/modules/geography/core/application/ports/direction-encoder.port.ts create mode 100644 src/modules/geography/core/application/ports/geodesic.port.ts create mode 100644 src/modules/geography/core/application/ports/georouter-creator.port.ts create mode 100644 src/modules/geography/core/application/ports/georouter.port.ts create mode 100644 src/modules/geography/core/application/types/coordinates.type.ts rename src/modules/{ad/core/application/ports => geography/core/application/types}/default-params.type.ts (75%) create mode 100644 src/modules/geography/core/application/types/georouter-settings.type.ts create mode 100644 src/modules/geography/core/application/types/path.type.ts create mode 100644 src/modules/geography/core/application/types/point.type.ts create mode 100644 src/modules/geography/core/application/types/route.type.ts create mode 100644 src/modules/geography/core/domain/route.entity.ts create mode 100644 src/modules/geography/core/domain/route.types.ts create mode 100644 src/modules/geography/core/domain/value-objects/timepoint.value-object.ts create mode 100644 src/modules/geography/core/domain/value-objects/waypoint.value-object.ts create mode 100644 src/modules/geography/geography.di-tokens.ts create mode 100644 src/modules/geography/geography.module.ts rename src/modules/{ad => geography}/infrastructure/default-params-provider.ts (80%) create mode 100644 src/modules/geography/infrastructure/postgres-direction-encoder.ts diff --git a/.env.dist b/.env.dist index 151c967..fa384ef 100644 --- a/.env.dist +++ b/.env.dist @@ -23,8 +23,6 @@ CACHE_TTL=5000 # default identifier used for match requests DEFAULT_UUID=00000000-0000-0000-0000-000000000000 -# default timezone -DEFAULT_TIMEZONE=Europe/Paris # default number of seats proposed as driver DEFAULT_SEATS=3 # algorithm type diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 06df3e5..17ea1a0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -15,7 +15,6 @@ datasource db { model Ad { uuid String @id @db.Uuid - userUuid String @db.Uuid driver Boolean passenger Boolean frequency Frequency diff --git a/src/app.module.ts b/src/app.module.ts index e52d97c..2df816c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -13,6 +13,7 @@ import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens'; import { MESSAGE_PUBLISHER } from '@modules/messager/messager.di-tokens'; import { HealthModuleOptions } from '@mobicoop/health-module/dist/core/domain/types/health.types'; import { MessagePublisherPort } from '@mobicoop/ddd-library'; +import { GeographyModule } from '@modules/geography/geography.module'; @Module({ imports: [ @@ -59,6 +60,7 @@ import { MessagePublisherPort } from '@mobicoop/ddd-library'; }), }), AdModule, + GeographyModule, MessagerModule, ], exports: [AdModule, MessagerModule], diff --git a/src/modules/ad/ad.di-tokens.ts b/src/modules/ad/ad.di-tokens.ts index 1750029..d87cfdd 100644 --- a/src/modules/ad/ad.di-tokens.ts +++ b/src/modules/ad/ad.di-tokens.ts @@ -1,5 +1,3 @@ -export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER'); -export const PARAMS_PROVIDER = Symbol('PARAMS_PROVIDER'); -export const TIMEZONE_FINDER = Symbol('TIMEZONE_FINDER'); -export const GEOROUTER_CREATOR = Symbol('GEOROUTER_CREATOR'); export const AD_REPOSITORY = Symbol('AD_REPOSITORY'); +export const GEOROUTER = Symbol('GEOROUTER'); +export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER'); diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index 361e1f0..b4915c7 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -26,7 +26,6 @@ export class AdMapper const now = new Date(); const record: AdWriteModel = { uuid: copy.id, - userUuid: copy.userId, driver: copy.driver, passenger: copy.passenger, frequency: copy.frequency, @@ -55,8 +54,8 @@ export class AdMapper driverDistance: copy.driverDistance, passengerDuration: copy.passengerDuration, passengerDistance: copy.passengerDistance, - waypoints: copy.waypoints, - direction: copy.direction, + waypoints: '', + direction: '', fwdAzimuth: copy.fwdAzimuth, backAzimuth: copy.backAzimuth, createdAt: copy.createdAt, @@ -71,7 +70,6 @@ export class AdMapper createdAt: new Date(record.createdAt), updatedAt: new Date(record.updatedAt), props: { - userId: record.userUuid, driver: record.driver, passenger: record.passenger, frequency: Frequency[record.frequency], @@ -95,8 +93,7 @@ export class AdMapper driverDistance: record.driverDistance, passengerDuration: record.passengerDuration, passengerDistance: record.passengerDistance, - waypoints: record.waypoints, - direction: record.direction, + waypoints: [], fwdAzimuth: record.fwdAzimuth, backAzimuth: record.backAzimuth, }, diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index 1e85849..c846631 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -1,17 +1,13 @@ import { Module, Provider } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; -import { - AD_MESSAGE_PUBLISHER, - AD_REPOSITORY, - PARAMS_PROVIDER, - TIMEZONE_FINDER, -} from './ad.di-tokens'; +import { AD_MESSAGE_PUBLISHER, AD_REPOSITORY } from './ad.di-tokens'; import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; import { AdRepository } from './infrastructure/ad.repository'; import { PrismaService } from './infrastructure/prisma.service'; -import { DefaultParamsProvider } from './infrastructure/default-params-provider'; -import { TimezoneFinder } from './infrastructure/timezone-finder'; import { AdMapper } from './ad.mapper'; +import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler'; + +const messageHandlers = [AdCreatedMessageHandler]; const mappers: Provider[] = [AdMapper]; @@ -30,32 +26,15 @@ const messagePublishers: Provider[] = [ ]; const orms: Provider[] = [PrismaService]; -const adapters: Provider[] = [ - { - provide: PARAMS_PROVIDER, - useClass: DefaultParamsProvider, - }, - { - provide: TIMEZONE_FINDER, - useClass: TimezoneFinder, - }, -]; - @Module({ imports: [CqrsModule], providers: [ + ...messageHandlers, ...mappers, ...repositories, ...messagePublishers, ...orms, - ...adapters, - ], - exports: [ - PrismaService, - AdMapper, - AD_REPOSITORY, - PARAMS_PROVIDER, - TIMEZONE_FINDER, ], + exports: [PrismaService, AdMapper, AD_REPOSITORY], }) export class AdModule {} diff --git a/src/modules/ad/core/application/commands/create-ad/create-ad.command.ts b/src/modules/ad/core/application/commands/create-ad/create-ad.command.ts new file mode 100644 index 0000000..3b1e695 --- /dev/null +++ b/src/modules/ad/core/application/commands/create-ad/create-ad.command.ts @@ -0,0 +1,33 @@ +import { Frequency } from '@modules/ad/core/domain/ad.types'; +import { Command, CommandProps } from '@mobicoop/ddd-library'; +import { ScheduleItem } from '../../types/schedule-item.type'; +import { Waypoint } from '../../types/waypoint.type'; + +export class CreateAdCommand extends Command { + readonly id: string; + readonly driver: boolean; + readonly passenger: boolean; + readonly frequency: Frequency; + readonly fromDate: string; + readonly toDate: string; + readonly schedule: ScheduleItem[]; + readonly seatsProposed: number; + readonly seatsRequested: number; + readonly strict: boolean; + readonly waypoints: Waypoint[]; + + constructor(props: CommandProps) { + super(props); + this.id = props.id; + this.driver = props.driver; + this.passenger = props.passenger; + this.frequency = props.frequency; + this.fromDate = props.fromDate; + this.toDate = props.toDate; + this.schedule = props.schedule; + this.seatsProposed = props.seatsProposed; + this.seatsRequested = props.seatsRequested; + this.strict = props.strict; + this.waypoints = props.waypoints; + } +} diff --git a/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts b/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts new file mode 100644 index 0000000..776e43d --- /dev/null +++ b/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts @@ -0,0 +1,42 @@ +import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; +import { CreateAdCommand } from './create-ad.command'; +import { Inject } from '@nestjs/common'; +import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens'; +import { AdEntity } from '@modules/ad/core/domain/ad.entity'; +import { AdRepositoryPort } from '../../ports/ad.repository.port'; +import { AggregateID, ConflictException } from '@mobicoop/ddd-library'; +import { AdAlreadyExistsException } from '@modules/ad/core/domain/ad.errors'; + +@CommandHandler(CreateAdCommand) +export class CreateAdService implements ICommandHandler { + constructor( + @Inject(AD_REPOSITORY) + private readonly repository: AdRepositoryPort, + ) {} + + async execute(command: CreateAdCommand): Promise { + const ad = AdEntity.create({ + id: command.id, + driver: command.driver, + passenger: command.passenger, + frequency: command.frequency, + fromDate: command.fromDate, + toDate: command.toDate, + schedule: command.schedule, + seatsProposed: command.seatsProposed, + seatsRequested: command.seatsRequested, + strict: command.strict, + waypoints: command.waypoints, + }); + + try { + await this.repository.insert(ad); + return ad.id; + } catch (error: any) { + if (error instanceof ConflictException) { + throw new AdAlreadyExistsException(error); + } + throw error; + } + } +} diff --git a/src/modules/ad/core/application/ports/timezone-finder.port.ts b/src/modules/ad/core/application/ports/timezone-finder.port.ts deleted file mode 100644 index 72ba115..0000000 --- a/src/modules/ad/core/application/ports/timezone-finder.port.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface TimezoneFinderPort { - timezones(lon: number, lat: number, defaultTimezone?: string): string[]; -} diff --git a/src/modules/ad/core/application/types/schedule-item.type.ts b/src/modules/ad/core/application/types/schedule-item.type.ts new file mode 100644 index 0000000..92dab99 --- /dev/null +++ b/src/modules/ad/core/application/types/schedule-item.type.ts @@ -0,0 +1,5 @@ +export type ScheduleItem = { + day: number; + time: string; + margin: number; +}; diff --git a/src/modules/ad/core/application/types/waypoint.type.ts b/src/modules/ad/core/application/types/waypoint.type.ts new file mode 100644 index 0000000..f3e4a99 --- /dev/null +++ b/src/modules/ad/core/application/types/waypoint.type.ts @@ -0,0 +1,8 @@ +import { PointContext } from '../../domain/ad.types'; + +export type Waypoint = { + position: number; + context?: PointContext; + lon: number; + lat: number; +}; diff --git a/src/modules/ad/core/domain/ad.entity.ts b/src/modules/ad/core/domain/ad.entity.ts index fc51d13..011f7c7 100644 --- a/src/modules/ad/core/domain/ad.entity.ts +++ b/src/modules/ad/core/domain/ad.entity.ts @@ -6,8 +6,7 @@ export class AdEntity extends AggregateRoot { static create = (create: CreateAdProps): AdEntity => { const props: AdProps = { ...create }; - const ad = new AdEntity({ id: create.id, props }); - return ad; + return new AdEntity({ id: create.id, props }); }; validate(): void { diff --git a/src/modules/ad/core/domain/ad.errors.ts b/src/modules/ad/core/domain/ad.errors.ts new file mode 100644 index 0000000..7d14547 --- /dev/null +++ b/src/modules/ad/core/domain/ad.errors.ts @@ -0,0 +1,11 @@ +import { ExceptionBase } from '@mobicoop/ddd-library'; + +export class AdAlreadyExistsException extends ExceptionBase { + static readonly message = 'Ad already exists'; + + public readonly code = 'AD.ALREADY_EXISTS'; + + constructor(cause?: Error, metadata?: unknown) { + super(AdAlreadyExistsException.message, cause, metadata); + } +} diff --git a/src/modules/ad/core/domain/ad.types.ts b/src/modules/ad/core/domain/ad.types.ts index a3dbb42..8afef95 100644 --- a/src/modules/ad/core/domain/ad.types.ts +++ b/src/modules/ad/core/domain/ad.types.ts @@ -1,8 +1,8 @@ import { ScheduleItemProps } from './value-objects/schedule-item.value-object'; +import { WaypointProps } from './value-objects/waypoint.value-object'; // All properties that an Ad has export interface AdProps { - userId: string; driver: boolean; passenger: boolean; frequency: Frequency; @@ -12,20 +12,18 @@ export interface AdProps { seatsProposed: number; seatsRequested: number; strict: boolean; - driverDuration: number; - driverDistance: number; - passengerDuration: number; - passengerDistance: number; - waypoints: string; - direction: string; - fwdAzimuth: number; - backAzimuth: number; + driverDuration?: number; + driverDistance?: number; + passengerDuration?: number; + passengerDistance?: number; + waypoints: WaypointProps[]; + fwdAzimuth?: number; + backAzimuth?: number; } // Properties that are needed for an Ad creation export interface CreateAdProps { id: string; - userId: string; driver: boolean; passenger: boolean; frequency: Frequency; @@ -35,17 +33,18 @@ export interface CreateAdProps { seatsProposed: number; seatsRequested: number; strict: boolean; - driverDuration: number; - driverDistance: number; - passengerDuration: number; - passengerDistance: number; - waypoints: string; - direction: string; - fwdAzimuth: number; - backAzimuth: number; + waypoints: WaypointProps[]; } export enum Frequency { PUNCTUAL = 'PUNCTUAL', RECURRENT = 'RECURRENT', } + +export enum PointContext { + HOUSE_NUMBER = 'HOUSE_NUMBER', + STREET_ADDRESS = 'STREET_ADDRESS', + LOCALITY = 'LOCALITY', + VENUE = 'VENUE', + OTHER = 'OTHER', +} diff --git a/src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts b/src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts index 8303eeb..5f2d66b 100644 --- a/src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts +++ b/src/modules/ad/core/domain/value-objects/schedule-item.value-object.ts @@ -1,4 +1,8 @@ -import { ValueObject } from '@mobicoop/ddd-library'; +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, + ValueObject, +} from '@mobicoop/ddd-library'; /** Note: * Value Objects with multiple properties can contain @@ -6,9 +10,9 @@ import { ValueObject } from '@mobicoop/ddd-library'; * */ export interface ScheduleItemProps { - day?: number; + day: number; time: string; - margin?: number; + margin: number; } export class ScheduleItem extends ValueObject { @@ -26,6 +30,19 @@ export class ScheduleItem extends ValueObject { // eslint-disable-next-line @typescript-eslint/no-unused-vars protected validate(props: ScheduleItemProps): void { - return; + if (props.day < 0 || props.day > 6) + throw new ArgumentOutOfRangeException('day must be between 0 and 6'); + if (props.time.split(':').length != 2) + throw new ArgumentInvalidException('time is invalid'); + if ( + parseInt(props.time.split(':')[0]) < 0 || + parseInt(props.time.split(':')[0]) > 23 + ) + throw new ArgumentInvalidException('time is invalid'); + if ( + parseInt(props.time.split(':')[1]) < 0 || + parseInt(props.time.split(':')[1]) > 59 + ) + throw new ArgumentInvalidException('time is invalid'); } } diff --git a/src/modules/ad/core/domain/value-objects/waypoint.value-object.ts b/src/modules/ad/core/domain/value-objects/waypoint.value-object.ts new file mode 100644 index 0000000..7dcadc2 --- /dev/null +++ b/src/modules/ad/core/domain/value-objects/waypoint.value-object.ts @@ -0,0 +1,47 @@ +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, + ValueObject, +} from '@mobicoop/ddd-library'; +import { PointContext } from '../ad.types'; + +/** Note: + * Value Objects with multiple properties can contain + * other Value Objects inside if needed. + * */ + +export interface WaypointProps { + position: number; + lon: number; + lat: number; + context?: PointContext; +} + +export class Waypoint extends ValueObject { + get position(): number { + return this.props.position; + } + + get lon(): number { + return this.props.lon; + } + + get lat(): number { + return this.props.lat; + } + + get context(): PointContext { + return this.props.context; + } + + protected validate(props: WaypointProps): void { + if (props.position < 0) + throw new ArgumentInvalidException( + 'position must be greater than or equal to 0', + ); + if (props.lon > 180 || props.lon < -180) + throw new ArgumentOutOfRangeException('lon must be between -180 and 180'); + if (props.lat > 90 || props.lat < -90) + throw new ArgumentOutOfRangeException('lat must be between -90 and 90'); + } +} diff --git a/src/modules/ad/infrastructure/ad.repository.ts b/src/modules/ad/infrastructure/ad.repository.ts index 5a8d4e5..afa5d7e 100644 --- a/src/modules/ad/infrastructure/ad.repository.ts +++ b/src/modules/ad/infrastructure/ad.repository.ts @@ -13,7 +13,6 @@ import { AdMapper } from '../ad.mapper'; export type AdBaseModel = { uuid: string; - userUuid: string; driver: boolean; passenger: boolean; frequency: string; diff --git a/src/modules/ad/infrastructure/timezone-finder.ts b/src/modules/ad/infrastructure/timezone-finder.ts deleted file mode 100644 index feb0b5a..0000000 --- a/src/modules/ad/infrastructure/timezone-finder.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { find } from 'geo-tz'; -import { TimezoneFinderPort } from '../core/application/ports/timezone-finder.port'; - -@Injectable() -export class TimezoneFinder implements TimezoneFinderPort { - timezones = ( - lon: number, - lat: number, - defaultTimezone?: string, - ): string[] => { - const foundTimezones = find(lat, lon); - if (defaultTimezone && foundTimezones.length == 0) return [defaultTimezone]; - return foundTimezones; - }; -} diff --git a/src/modules/ad/interface/message-handlers/ad-created.message-handler.ts b/src/modules/ad/interface/message-handlers/ad-created.message-handler.ts new file mode 100644 index 0000000..ed5dc61 --- /dev/null +++ b/src/modules/ad/interface/message-handlers/ad-created.message-handler.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@nestjs/common'; +import { RabbitSubscribe } from '@mobicoop/message-broker-module'; +import { CommandBus } from '@nestjs/cqrs'; +import { CreateAdCommand } from '@modules/ad/core/application/commands/create-ad/create-ad.command'; +import { Ad } from './ad.types'; + +@Injectable() +export class AdCreatedMessageHandler { + constructor(private readonly commandBus: CommandBus) {} + + @RabbitSubscribe({ + name: 'adCreated', + }) + public async adCreated(message: string) { + const createdAd: Ad = JSON.parse(message); + try { + await this.commandBus.execute( + new CreateAdCommand({ + id: createdAd.id, + driver: createdAd.driver, + passenger: createdAd.passenger, + frequency: createdAd.frequency, + fromDate: createdAd.fromDate, + toDate: createdAd.toDate, + schedule: createdAd.schedule, + seatsProposed: createdAd.seatsProposed, + seatsRequested: createdAd.seatsRequested, + strict: createdAd.strict, + waypoints: createdAd.waypoints, + }), + ); + } catch (e: any) {} + } +} diff --git a/src/modules/ad/interface/message-handlers/ad.types.ts b/src/modules/ad/interface/message-handlers/ad.types.ts new file mode 100644 index 0000000..f795309 --- /dev/null +++ b/src/modules/ad/interface/message-handlers/ad.types.ts @@ -0,0 +1,35 @@ +import { Frequency, PointContext } from '@modules/ad/core/domain/ad.types'; + +export type Ad = { + id: string; + userId: string; + driver: boolean; + passenger: boolean; + frequency: Frequency; + fromDate: string; + toDate: string; + schedule: ScheduleItem[]; + seatsProposed: number; + seatsRequested: number; + strict: boolean; + waypoints: Waypoint[]; +}; + +export type ScheduleItem = { + day: number; + time: string; + margin: number; +}; + +export type Waypoint = { + position: number; + name?: string; + houseNumber?: string; + street?: string; + locality?: string; + postalCode?: string; + country: string; + lon: number; + lat: number; + context?: PointContext; +}; diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts new file mode 100644 index 0000000..bbb1143 --- /dev/null +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -0,0 +1,107 @@ +import { AdMapper } from '@modules/ad/ad.mapper'; +import { AdEntity } from '@modules/ad/core/domain/ad.entity'; +import { Frequency } from '@modules/ad/core/domain/ad.types'; +import { + AdReadModel, + AdWriteModel, +} from '@modules/ad/infrastructure/ad.repository'; +import { Test } from '@nestjs/testing'; + +const now = new Date('2023-06-21 06:00:00'); +const adEntity: AdEntity = new AdEntity({ + id: 'c160cf8c-f057-4962-841f-3ad68346df44', + props: { + driver: true, + passenger: true, + frequency: Frequency.PUNCTUAL, + fromDate: '2023-06-21', + toDate: '2023-06-21', + schedule: [ + { + day: 3, + time: '07:15', + margin: 900, + }, + ], + waypoints: [ + { + position: 0, + lat: 48.689445, + lon: 6.1765102, + }, + { + position: 1, + lat: 48.8566, + lon: 2.3522, + }, + ], + strict: false, + seatsProposed: 3, + seatsRequested: 1, + }, + createdAt: now, + updatedAt: now, +}); + +const adReadModel: AdReadModel = { + uuid: 'c160cf8c-f057-4962-841f-3ad68346df44', + driver: true, + passenger: true, + frequency: Frequency.PUNCTUAL, + fromDate: new Date('2023-06-21'), + toDate: new Date('2023-06-21'), + schedule: [ + { + uuid: '3978f3d6-560f-4a8f-83ba-9bf5aa9a2d27', + day: 3, + time: new Date('2023-06-21T07:05:00Z'), + margin: 900, + createdAt: now, + updatedAt: now, + }, + ], + waypoints: "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", + direction: + "'LINESTRING(6.1765102 48.689445,5.12345 48.76543,2.3522 48.8566)'", + driverDistance: 350000, + driverDuration: 14400, + passengerDistance: 350000, + passengerDuration: 14400, + fwdAzimuth: 273, + backAzimuth: 93, + strict: false, + seatsProposed: 3, + seatsRequested: 1, + createdAt: now, + updatedAt: now, +}; + +describe('Ad Mapper', () => { + let adMapper: AdMapper; + + beforeAll(async () => { + const module = await Test.createTestingModule({ + providers: [AdMapper], + }).compile(); + adMapper = module.get(AdMapper); + }); + + it('should be defined', () => { + expect(adMapper).toBeDefined(); + }); + + it('should map domain entity to persistence data', async () => { + const mapped: AdWriteModel = adMapper.toPersistence(adEntity); + expect(mapped.schedule.create.length).toBe(1); + }); + + it('should map persisted data to domain entity', async () => { + const mapped: AdEntity = adMapper.toDomain(adReadModel); + expect(mapped.getProps().schedule.length).toBe(1); + expect(mapped.getProps().schedule[0].time).toBe('07:05'); + }); + + it('should map domain entity to response', async () => { + expect(adMapper.toResponse(adEntity)).toBeUndefined(); + }); +}); diff --git a/src/modules/ad/tests/unit/core/ad.entity.spec.ts b/src/modules/ad/tests/unit/core/ad.entity.spec.ts new file mode 100644 index 0000000..899e3f0 --- /dev/null +++ b/src/modules/ad/tests/unit/core/ad.entity.spec.ts @@ -0,0 +1,47 @@ +import { AdEntity } from '@modules/ad/core/domain/ad.entity'; +import { CreateAdProps, Frequency } from '@modules/ad/core/domain/ad.types'; +import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.value-object'; + +const originWaypointProps: WaypointProps = { + position: 0, + lon: 48.689445, + lat: 6.17651, +}; +const destinationWaypointProps: WaypointProps = { + position: 1, + lon: 48.8566, + lat: 2.3522, +}; + +const createAdProps: CreateAdProps = { + id: 'e8fe64b1-4c33-49e1-9f69-4db48b21df36', + driver: true, + passenger: true, + fromDate: '2023-06-21', + toDate: '2023-06-21', + schedule: [ + { + day: 3, + time: '08:30', + margin: 900, + }, + ], + frequency: Frequency.PUNCTUAL, + seatsProposed: 3, + seatsRequested: 1, + strict: false, + waypoints: [originWaypointProps, destinationWaypointProps], +}; + +describe('Ad entity create', () => { + it('should create a new entity', async () => { + const ad: AdEntity = AdEntity.create(createAdProps); + expect(ad.id.length).toBe(36); + expect(ad.getProps().schedule.length).toBe(1); + expect(ad.getProps().schedule[0].day).toBe(3); + expect(ad.getProps().schedule[0].time).toBe('08:30'); + expect(ad.getProps().driver).toBeTruthy(); + expect(ad.getProps().passenger).toBeTruthy(); + expect(ad.getProps().driverDistance).toBeUndefined(); + }); +}); diff --git a/src/modules/ad/tests/unit/core/create-ad.service.spec.ts b/src/modules/ad/tests/unit/core/create-ad.service.spec.ts new file mode 100644 index 0000000..74f26e6 --- /dev/null +++ b/src/modules/ad/tests/unit/core/create-ad.service.spec.ts @@ -0,0 +1,103 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens'; +import { AggregateID } from '@mobicoop/ddd-library'; +import { AdEntity } from '@modules/ad/core/domain/ad.entity'; +import { ConflictException } from '@mobicoop/ddd-library'; +import { CreateAdProps, Frequency } from '@modules/ad/core/domain/ad.types'; +import { CreateAdService } from '@modules/ad/core/application/commands/create-ad/create-ad.service'; +import { CreateAdCommand } from '@modules/ad/core/application/commands/create-ad/create-ad.command'; +import { AdAlreadyExistsException } from '@modules/ad/core/domain/ad.errors'; +import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.value-object'; + +const originWaypoint: WaypointProps = { + position: 0, + lon: 48.689445, + lat: 6.17651, +}; +const destinationWaypoint: WaypointProps = { + position: 1, + lon: 48.8566, + lat: 2.3522, +}; +const createAdProps: CreateAdProps = { + id: '4eb6a6af-ecfd-41c3-9118-473a507014d4', + fromDate: '2023-12-21', + toDate: '2023-12-21', + schedule: [ + { + day: 4, + time: '08:15', + margin: 900, + }, + ], + driver: true, + passenger: true, + seatsProposed: 3, + seatsRequested: 1, + strict: false, + frequency: Frequency.PUNCTUAL, + waypoints: [originWaypoint, destinationWaypoint], +}; + +const mockAdRepository = { + insert: jest + .fn() + .mockImplementationOnce(() => ({})) + .mockImplementationOnce(() => { + throw new Error(); + }) + .mockImplementationOnce(() => { + throw new ConflictException('already exists'); + }), +}; + +describe('create-ad.service', () => { + let createAdService: CreateAdService; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: AD_REPOSITORY, + useValue: mockAdRepository, + }, + CreateAdService, + ], + }).compile(); + + createAdService = module.get(CreateAdService); + }); + + it('should be defined', () => { + expect(createAdService).toBeDefined(); + }); + + describe('execution', () => { + const createAdCommand = new CreateAdCommand(createAdProps); + it('should create a new ad', async () => { + AdEntity.create = jest.fn().mockReturnValue({ + id: '047a6ecf-23d4-4d3e-877c-3225d560a8da', + }); + const result: AggregateID = await createAdService.execute( + createAdCommand, + ); + expect(result).toBe('047a6ecf-23d4-4d3e-877c-3225d560a8da'); + }); + it('should throw an error if something bad happens', async () => { + AdEntity.create = jest.fn().mockReturnValue({ + id: '047a6ecf-23d4-4d3e-877c-3225d560a8da', + }); + await expect( + createAdService.execute(createAdCommand), + ).rejects.toBeInstanceOf(Error); + }); + it('should throw an exception if Ad already exists', async () => { + AdEntity.create = jest.fn().mockReturnValue({ + id: '047a6ecf-23d4-4d3e-877c-3225d560a8da', + }); + await expect( + createAdService.execute(createAdCommand), + ).rejects.toBeInstanceOf(AdAlreadyExistsException); + }); + }); +}); diff --git a/src/modules/ad/tests/unit/core/schedule-item.value-object.spec.ts b/src/modules/ad/tests/unit/core/schedule-item.value-object.spec.ts new file mode 100644 index 0000000..65bacc9 --- /dev/null +++ b/src/modules/ad/tests/unit/core/schedule-item.value-object.spec.ts @@ -0,0 +1,62 @@ +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, +} from '@mobicoop/ddd-library'; +import { ScheduleItem } from '@modules/ad/core/domain/value-objects/schedule-item.value-object'; + +describe('Schedule item value object', () => { + it('should create a schedule item value object', () => { + const scheduleItemVO = new ScheduleItem({ + day: 0, + time: '07:00', + margin: 900, + }); + expect(scheduleItemVO.day).toBe(0); + expect(scheduleItemVO.time).toBe('07:00'); + expect(scheduleItemVO.margin).toBe(900); + }); + it('should throw an exception if day is invalid', () => { + try { + new ScheduleItem({ + day: 7, + time: '07:00', + margin: 900, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); + it('should throw an exception if time is invalid', () => { + try { + new ScheduleItem({ + day: 0, + time: '07,00', + margin: 900, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentInvalidException); + } + }); + it('should throw an exception if the hour of the time is invalid', () => { + try { + new ScheduleItem({ + day: 0, + time: '25:00', + margin: 900, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentInvalidException); + } + }); + it('should throw an exception if the minutes of the time are invalid', () => { + try { + new ScheduleItem({ + day: 0, + time: '07:63', + margin: 900, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentInvalidException); + } + }); +}); diff --git a/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts new file mode 100644 index 0000000..1d6e334 --- /dev/null +++ b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts @@ -0,0 +1,83 @@ +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, +} from '@mobicoop/ddd-library'; +import { PointContext } from '@modules/ad/core/domain/ad.types'; +import { Waypoint } from '@modules/ad/core/domain/value-objects/waypoint.value-object'; + +describe('Waypoint value object', () => { + it('should create a waypoint value object without context', () => { + const waypointVO = new Waypoint({ + position: 0, + lon: 48.689445, + lat: 6.17651, + }); + expect(waypointVO.position).toBe(0); + expect(waypointVO.lon).toBe(48.689445); + expect(waypointVO.lat).toBe(6.17651); + expect(waypointVO.context).toBeUndefined(); + }); + it('should create a waypoint value object with context', () => { + const waypointVO = new Waypoint({ + position: 0, + lon: 48.689445, + lat: 6.17651, + context: PointContext.HOUSE_NUMBER, + }); + expect(waypointVO.position).toBe(0); + expect(waypointVO.lon).toBe(48.689445); + expect(waypointVO.lat).toBe(6.17651); + expect(waypointVO.context).toBe(PointContext.HOUSE_NUMBER); + }); + it('should throw an exception if position is invalid', () => { + try { + new Waypoint({ + position: -1, + lon: 48.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentInvalidException); + } + }); + it('should throw an exception if longitude is invalid', () => { + try { + new Waypoint({ + position: 0, + lon: 348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Waypoint({ + position: 0, + lon: -348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); + it('should throw an exception if longitude is invalid', () => { + try { + new Waypoint({ + position: 0, + lon: 48.689445, + lat: 96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Waypoint({ + position: 0, + lon: 48.689445, + lat: -96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); +}); diff --git a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts new file mode 100644 index 0000000..43ed4ac --- /dev/null +++ b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts @@ -0,0 +1,36 @@ +import { AdMapper } from '@modules/ad/ad.mapper'; +import { AdRepository } from '@modules/ad/infrastructure/ad.repository'; +import { PrismaService } from '@modules/ad/infrastructure/prisma.service'; +import { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter'; +import { Test, TestingModule } from '@nestjs/testing'; + +const mockMessagePublisher = { + publish: jest.fn().mockImplementation(), +}; + +describe('Ad repository', () => { + let prismaService: PrismaService; + let adMapper: AdMapper; + let eventEmitter: EventEmitter2; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [EventEmitterModule.forRoot()], + providers: [PrismaService, AdMapper], + }).compile(); + + prismaService = module.get(PrismaService); + adMapper = module.get(AdMapper); + eventEmitter = module.get(EventEmitter2); + }); + it('should be defined', () => { + expect( + new AdRepository( + prismaService, + adMapper, + eventEmitter, + mockMessagePublisher, + ), + ).toBeDefined(); + }); +}); diff --git a/src/modules/ad/tests/unit/interface/ad-created.message-handler.spec.ts b/src/modules/ad/tests/unit/interface/ad-created.message-handler.spec.ts new file mode 100644 index 0000000..df3e773 --- /dev/null +++ b/src/modules/ad/tests/unit/interface/ad-created.message-handler.spec.ts @@ -0,0 +1,44 @@ +import { AdCreatedMessageHandler } from '@modules/ad/interface/message-handlers/ad-created.message-handler'; +import { CommandBus } from '@nestjs/cqrs'; +import { Test, TestingModule } from '@nestjs/testing'; + +const adCreatedMessage = + '{"id":"4eb6a6af-ecfd-41c3-9118-473a507014d4","driver":"true","passenger":"true","frequency":"PUNCTUAL","fromDate":"2023-08-18","toDate":"2023-08-18","schedule":[{"day":"5","time":"10:00","margin":"900"}],"seatsProposed":"3","seatsRequested":"1","strict":"false","waypoints":[{"position":"0","houseNumber":"5","street":"rue de la monnaie","locality":"Nancy","postalCode":"54000","country":"France","lon":"48.689445","lat":"6.17651"},{"position":"1","locality":"Paris","postalCode":"75000","country":"France","lon":"48.8566","lat":"2.3522"}]}'; + +const mockCommandBus = { + execute: jest.fn(), +}; + +describe('Ad Created Message Handler', () => { + let adCreatedMessageHandler: AdCreatedMessageHandler; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: CommandBus, + useValue: mockCommandBus, + }, + AdCreatedMessageHandler, + ], + }).compile(); + + adCreatedMessageHandler = module.get( + AdCreatedMessageHandler, + ); + }); + + afterEach(async () => { + jest.clearAllMocks(); + }); + + it('should be defined', () => { + expect(adCreatedMessageHandler).toBeDefined(); + }); + + it('should create an ad', async () => { + jest.spyOn(mockCommandBus, 'execute'); + await adCreatedMessageHandler.adCreated(adCreatedMessage); + expect(mockCommandBus.execute).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/modules/ad/core/application/ports/default-params-provider.port.ts b/src/modules/geography/core/application/ports/default-params-provider.port.ts similarity index 55% rename from src/modules/ad/core/application/ports/default-params-provider.port.ts rename to src/modules/geography/core/application/ports/default-params-provider.port.ts index e316b77..7f4ee14 100644 --- a/src/modules/ad/core/application/ports/default-params-provider.port.ts +++ b/src/modules/geography/core/application/ports/default-params-provider.port.ts @@ -1,4 +1,4 @@ -import { DefaultParams } from './default-params.type'; +import { DefaultParams } from '../types/default-params.type'; export interface DefaultParamsProviderPort { getParams(): DefaultParams; diff --git a/src/modules/geography/core/application/ports/direction-encoder.port.ts b/src/modules/geography/core/application/ports/direction-encoder.port.ts new file mode 100644 index 0000000..333f8ba --- /dev/null +++ b/src/modules/geography/core/application/ports/direction-encoder.port.ts @@ -0,0 +1,5 @@ +import { Coordinates } from '../types/coordinates.type'; + +export interface DirectionEncoderPort { + encode(coordinates: Coordinates[]): string; +} diff --git a/src/modules/geography/core/application/ports/geodesic.port.ts b/src/modules/geography/core/application/ports/geodesic.port.ts new file mode 100644 index 0000000..77b45ba --- /dev/null +++ b/src/modules/geography/core/application/ports/geodesic.port.ts @@ -0,0 +1,11 @@ +export interface GeodesicPort { + inverse( + lon1: number, + lat1: number, + lon2: number, + lat2: number, + ): { + azimuth: number; + distance: number; + }; +} diff --git a/src/modules/geography/core/application/ports/georouter-creator.port.ts b/src/modules/geography/core/application/ports/georouter-creator.port.ts new file mode 100644 index 0000000..0f3957d --- /dev/null +++ b/src/modules/geography/core/application/ports/georouter-creator.port.ts @@ -0,0 +1,5 @@ +import { GeorouterPort } from './georouter.port'; + +export interface GeorouterCreatorPort { + create(type: string, url: string): GeorouterPort; +} diff --git a/src/modules/geography/core/application/ports/georouter.port.ts b/src/modules/geography/core/application/ports/georouter.port.ts new file mode 100644 index 0000000..51e56f7 --- /dev/null +++ b/src/modules/geography/core/application/ports/georouter.port.ts @@ -0,0 +1,7 @@ +import { GeorouterSettings } from '../types/georouter-settings.type'; +import { Path } from '../types/path.type'; +import { Route } from '../types/route.type'; + +export interface GeorouterPort { + routes(paths: Path[], settings: GeorouterSettings): Promise; +} diff --git a/src/modules/geography/core/application/types/coordinates.type.ts b/src/modules/geography/core/application/types/coordinates.type.ts new file mode 100644 index 0000000..8e149ed --- /dev/null +++ b/src/modules/geography/core/application/types/coordinates.type.ts @@ -0,0 +1,4 @@ +export type Coordinates = { + lon: number; + lat: number; +}; diff --git a/src/modules/ad/core/application/ports/default-params.type.ts b/src/modules/geography/core/application/types/default-params.type.ts similarity index 75% rename from src/modules/ad/core/application/ports/default-params.type.ts rename to src/modules/geography/core/application/types/default-params.type.ts index bea841b..12ea88e 100644 --- a/src/modules/ad/core/application/ports/default-params.type.ts +++ b/src/modules/geography/core/application/types/default-params.type.ts @@ -1,5 +1,4 @@ export type DefaultParams = { - DEFAULT_TIMEZONE: string; GEOROUTER_TYPE: string; GEOROUTER_URL: string; }; diff --git a/src/modules/geography/core/application/types/georouter-settings.type.ts b/src/modules/geography/core/application/types/georouter-settings.type.ts new file mode 100644 index 0000000..d8f73ae --- /dev/null +++ b/src/modules/geography/core/application/types/georouter-settings.type.ts @@ -0,0 +1,5 @@ +export type GeorouterSettings = { + withPoints: boolean; + withTime: boolean; + withDistance: boolean; +}; diff --git a/src/modules/geography/core/application/types/path.type.ts b/src/modules/geography/core/application/types/path.type.ts new file mode 100644 index 0000000..1f4a6eb --- /dev/null +++ b/src/modules/geography/core/application/types/path.type.ts @@ -0,0 +1,7 @@ +import { PathType } from '../../domain/route.types'; +import { Point } from './point.type'; + +export type Path = { + type: PathType; + points: Point[]; +}; diff --git a/src/modules/geography/core/application/types/point.type.ts b/src/modules/geography/core/application/types/point.type.ts new file mode 100644 index 0000000..6f71f0f --- /dev/null +++ b/src/modules/geography/core/application/types/point.type.ts @@ -0,0 +1,6 @@ +import { PointContext } from '../../domain/route.types'; +import { Coordinates } from './coordinates.type'; + +export type Point = Coordinates & { + context?: PointContext; +}; diff --git a/src/modules/geography/core/application/types/route.type.ts b/src/modules/geography/core/application/types/route.type.ts new file mode 100644 index 0000000..f202e52 --- /dev/null +++ b/src/modules/geography/core/application/types/route.type.ts @@ -0,0 +1,11 @@ +import { Point } from './point.type'; + +export type Route = { + name: string; + distance: number; + duration: number; + fwdAzimuth: number; + backAzimuth: number; + distanceAzimuth: number; + points: Point[]; +}; diff --git a/src/modules/geography/core/domain/route.entity.ts b/src/modules/geography/core/domain/route.entity.ts new file mode 100644 index 0000000..d5bf02f --- /dev/null +++ b/src/modules/geography/core/domain/route.entity.ts @@ -0,0 +1,117 @@ +import { AggregateRoot, AggregateID } from '@mobicoop/ddd-library'; +import { + CreateRouteProps, + Path, + Role, + RouteProps, + PathType, +} from './route.types'; +import { WaypointProps } from './value-objects/waypoint.value-object'; + +export class RouteEntity extends AggregateRoot { + protected readonly _id: AggregateID; + + static create = async (create: CreateRouteProps): Promise => { + const props: RouteProps = await create.georouter.routes( + this.getPaths(create.roles, create.waypoints), + create.georouterSettings, + ); + const route = new RouteEntity({ props }); + return route; + }; + + validate(): void { + // entity business rules validation to protect it's invariant before saving entity to a database + } + + private static getPaths = ( + roles: Role[], + waypoints: WaypointProps[], + ): Path[] => { + const paths: Path[] = []; + if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) { + if (waypoints.length == 2) { + // 2 points => same route for driver and passenger + const commonPath: Path = { + type: PathType.COMMON, + points: waypoints, + }; + paths.push(commonPath); + } else { + const driverPath: Path = RouteEntity.createDriverPath(waypoints); + const passengerPath: Path = RouteEntity.createPassengerPath(waypoints); + paths.push(driverPath, passengerPath); + } + } else if (roles.includes(Role.DRIVER)) { + const driverPath: Path = RouteEntity.createDriverPath(waypoints); + paths.push(driverPath); + } else if (roles.includes(Role.PASSENGER)) { + const passengerPath: Path = RouteEntity.createPassengerPath(waypoints); + paths.push(passengerPath); + } + return paths; + }; + + private static createDriverPath = (waypoints: WaypointProps[]): Path => { + return { + type: PathType.DRIVER, + points: waypoints, + }; + }; + + private static createPassengerPath = (waypoints: WaypointProps[]): Path => { + return { + type: PathType.PASSENGER, + points: [waypoints[0], waypoints[waypoints.length - 1]], + }; + }; +} + +// import { IGeodesic } from '../interfaces/geodesic.interface'; +// import { Point } from '../types/point.type'; +// import { SpacetimePoint } from './spacetime-point'; + +// export class Route { +// distance: number; +// duration: number; +// fwdAzimuth: number; +// backAzimuth: number; +// distanceAzimuth: number; +// points: Point[]; +// spacetimePoints: SpacetimePoint[]; +// private geodesic: IGeodesic; + +// constructor(geodesic: IGeodesic) { +// this.distance = undefined; +// this.duration = undefined; +// this.fwdAzimuth = undefined; +// this.backAzimuth = undefined; +// this.distanceAzimuth = undefined; +// this.points = []; +// this.spacetimePoints = []; +// this.geodesic = geodesic; +// } + +// setPoints = (points: Point[]): void => { +// this.points = points; +// this.setAzimuth(points); +// }; + +// setSpacetimePoints = (spacetimePoints: SpacetimePoint[]): void => { +// this.spacetimePoints = spacetimePoints; +// }; + +// protected setAzimuth = (points: Point[]): void => { +// const inverse = this.geodesic.inverse( +// points[0].lon, +// points[0].lat, +// points[points.length - 1].lon, +// points[points.length - 1].lat, +// ); +// this.fwdAzimuth = +// inverse.azimuth >= 0 ? inverse.azimuth : 360 - Math.abs(inverse.azimuth); +// this.backAzimuth = +// this.fwdAzimuth > 180 ? this.fwdAzimuth - 180 : this.fwdAzimuth + 180; +// this.distanceAzimuth = inverse.distance; +// }; +// } diff --git a/src/modules/geography/core/domain/route.types.ts b/src/modules/geography/core/domain/route.types.ts new file mode 100644 index 0000000..d9d3674 --- /dev/null +++ b/src/modules/geography/core/domain/route.types.ts @@ -0,0 +1,54 @@ +import { GeorouterPort } from '../application/ports/georouter.port'; +import { GeorouterSettings } from '../application/types/georouter-settings.type'; +import { SpacetimePointProps } from './value-objects/timepoint.value-object'; +import { WaypointProps } from './value-objects/waypoint.value-object'; + +// All properties that a Route has +export interface RouteProps { + name: string; + distance: number; + duration: number; + fwdAzimuth: number; + backAzimuth: number; + distanceAzimuth: number; + waypoints: WaypointProps[]; + spacetimePoints: SpacetimePointProps[]; +} + +// Properties that are needed for a Route creation +export interface CreateRouteProps { + roles: Role[]; + waypoints: WaypointProps[]; + georouter: GeorouterPort; + georouterSettings: GeorouterSettings; +} + +export type Path = { + type: PathType; + points: Point[]; +}; + +export type Point = { + lon: number; + lat: number; + context?: PointContext; +}; + +export enum Role { + DRIVER = 'DRIVER', + PASSENGER = 'PASSENGER', +} + +export enum PointContext { + HOUSE_NUMBER = 'HOUSE_NUMBER', + STREET_ADDRESS = 'STREET_ADDRESS', + LOCALITY = 'LOCALITY', + VENUE = 'VENUE', + OTHER = 'OTHER', +} + +export enum PathType { + COMMON = 'common', + DRIVER = 'driver', + PASSENGER = 'passenger', +} diff --git a/src/modules/geography/core/domain/value-objects/timepoint.value-object.ts b/src/modules/geography/core/domain/value-objects/timepoint.value-object.ts new file mode 100644 index 0000000..b6c7971 --- /dev/null +++ b/src/modules/geography/core/domain/value-objects/timepoint.value-object.ts @@ -0,0 +1,42 @@ +import { ArgumentInvalidException, ValueObject } from '@mobicoop/ddd-library'; + +/** Note: + * Value Objects with multiple properties can contain + * other Value Objects inside if needed. + * */ + +export interface SpacetimePointProps { + lon: number; + lat: number; + duration: number; + distance: number; +} + +export class SpacetimePoint extends ValueObject { + get lon(): number { + return this.props.lon; + } + + get lat(): number { + return this.props.lat; + } + + get duration(): number { + return this.props.duration; + } + + get distance(): number { + return this.props.distance; + } + + protected validate(props: SpacetimePointProps): void { + if (props.duration < 0) + throw new ArgumentInvalidException( + 'duration must be greater than or equal to 0', + ); + if (props.distance < 0) + throw new ArgumentInvalidException( + 'distance must be greater than or equal to 0', + ); + } +} diff --git a/src/modules/geography/core/domain/value-objects/waypoint.value-object.ts b/src/modules/geography/core/domain/value-objects/waypoint.value-object.ts new file mode 100644 index 0000000..9f6b493 --- /dev/null +++ b/src/modules/geography/core/domain/value-objects/waypoint.value-object.ts @@ -0,0 +1,47 @@ +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, + ValueObject, +} from '@mobicoop/ddd-library'; +import { PointContext } from '../route.types'; + +/** Note: + * Value Objects with multiple properties can contain + * other Value Objects inside if needed. + * */ + +export interface WaypointProps { + position: number; + lon: number; + lat: number; + context?: PointContext; +} + +export class Waypoint extends ValueObject { + get position(): number { + return this.props.position; + } + + get lon(): number { + return this.props.lon; + } + + get lat(): number { + return this.props.lat; + } + + get context(): PointContext { + return this.props.context; + } + + protected validate(props: WaypointProps): void { + if (props.position < 0) + throw new ArgumentInvalidException( + 'position must be greater than or equal to 0', + ); + if (props.lon > 180 || props.lon < -180) + throw new ArgumentOutOfRangeException('lon must be between -180 and 180'); + if (props.lat > 90 || props.lat < -90) + throw new ArgumentOutOfRangeException('lat must be between -90 and 90'); + } +} diff --git a/src/modules/geography/geography.di-tokens.ts b/src/modules/geography/geography.di-tokens.ts new file mode 100644 index 0000000..647e261 --- /dev/null +++ b/src/modules/geography/geography.di-tokens.ts @@ -0,0 +1,2 @@ +export const PARAMS_PROVIDER = Symbol('PARAMS_PROVIDER'); +export const DIRECTION_ENCODER = Symbol('DIRECTION_ENCODER'); diff --git a/src/modules/geography/geography.module.ts b/src/modules/geography/geography.module.ts new file mode 100644 index 0000000..c1aff74 --- /dev/null +++ b/src/modules/geography/geography.module.ts @@ -0,0 +1,23 @@ +import { Module, Provider } from '@nestjs/common'; +import { CqrsModule } from '@nestjs/cqrs'; +import { DIRECTION_ENCODER, PARAMS_PROVIDER } from './geography.di-tokens'; +import { DefaultParamsProvider } from './infrastructure/default-params-provider'; +import { PostgresDirectionEncoder } from './infrastructure/postgres-direction-encoder'; + +const adapters: Provider[] = [ + { + provide: PARAMS_PROVIDER, + useClass: DefaultParamsProvider, + }, + { + provide: DIRECTION_ENCODER, + useClass: PostgresDirectionEncoder, + }, +]; + +@Module({ + imports: [CqrsModule], + providers: [...adapters], + exports: [DIRECTION_ENCODER], +}) +export class GeographyModule {} diff --git a/src/modules/ad/infrastructure/default-params-provider.ts b/src/modules/geography/infrastructure/default-params-provider.ts similarity index 80% rename from src/modules/ad/infrastructure/default-params-provider.ts rename to src/modules/geography/infrastructure/default-params-provider.ts index 305987b..962468b 100644 --- a/src/modules/ad/infrastructure/default-params-provider.ts +++ b/src/modules/geography/infrastructure/default-params-provider.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { DefaultParamsProviderPort } from '../core/application/ports/default-params-provider.port'; -import { DefaultParams } from '../core/application/ports/default-params.type'; +import { DefaultParams } from '../core/application/types/default-params.type'; @Injectable() export class DefaultParamsProvider implements DefaultParamsProviderPort { @@ -9,6 +9,5 @@ export class DefaultParamsProvider implements DefaultParamsProviderPort { getParams = (): DefaultParams => ({ GEOROUTER_TYPE: this._configService.get('GEOROUTER_TYPE'), GEOROUTER_URL: this._configService.get('GEOROUTER_URL'), - DEFAULT_TIMEZONE: this._configService.get('DEFAULT_TIMEZONE'), }); } diff --git a/src/modules/geography/infrastructure/postgres-direction-encoder.ts b/src/modules/geography/infrastructure/postgres-direction-encoder.ts new file mode 100644 index 0000000..9ffbcba --- /dev/null +++ b/src/modules/geography/infrastructure/postgres-direction-encoder.ts @@ -0,0 +1,11 @@ +import { Coordinates } from '../core/application/types/coordinates.type'; +import { DirectionEncoderPort } from '../core/application/ports/direction-encoder.port'; + +export class PostgresDirectionEncoder implements DirectionEncoderPort { + encode = (coordinates: Coordinates[]): string => + [ + "'LINESTRING(", + coordinates.map((point) => [point.lon, point.lat].join(' ')).join(), + ")'", + ].join(''); +} diff --git a/src/modules/messager/messager.module.ts b/src/modules/messager/messager.module.ts index 896c300..64bafed 100644 --- a/src/modules/messager/messager.module.ts +++ b/src/modules/messager/messager.module.ts @@ -17,6 +17,20 @@ const imports = [ uri: configService.get('MESSAGE_BROKER_URI'), exchange: configService.get('MESSAGE_BROKER_EXCHANGE'), name: 'matcher', + handlers: { + adCreated: { + routingKey: 'ad.created', + queue: 'matcher-ad-created', + }, + adUpdated: { + routingKey: 'ad.updated', + queue: 'matcher-ad-updated', + }, + adDeleted: { + routingKey: 'ad.deleted', + queue: 'matcher-ad-deleted', + }, + }, }), }), ]; From 88326dcf6f8c06e00612aefcf01705787198b8b2 Mon Sep 17 00:00:00 2001 From: sbriat Date: Fri, 18 Aug 2023 16:50:55 +0200 Subject: [PATCH 03/24] basic ad entity without direction --- package-lock.json | 7 +++++++ package.json | 1 + src/app.module.ts | 2 +- src/modules/ad/ad.di-tokens.ts | 1 + src/modules/ad/ad.mapper.ts | 11 ++++++++-- src/modules/ad/ad.module.ts | 18 ++++++++++++++-- src/modules/ad/tests/unit/ad.mapper.spec.ts | 21 ++++++++++++++++++- .../unit/infrastructure/ad.repository.spec.ts | 15 ++++++++++++- .../infrastructure/default-params-provider.ts | 6 +++--- .../postgres-direction-encoder.ts | 2 ++ 10 files changed, 74 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5639504..b798ee2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "@types/jest": "29.5.0", "@types/node": "18.15.11", "@types/supertest": "^2.0.11", + "@types/uuid": "^9.0.2", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "dotenv-cli": "^7.2.1", @@ -2655,6 +2656,12 @@ "@types/superagent": "*" } }, + "node_modules/@types/uuid": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true + }, "node_modules/@types/validator": { "version": "13.11.1", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz", diff --git a/package.json b/package.json index 3c727a9..64b005d 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@types/jest": "29.5.0", "@types/node": "18.15.11", "@types/supertest": "^2.0.11", + "@types/uuid": "^9.0.2", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "dotenv-cli": "^7.2.1", diff --git a/src/app.module.ts b/src/app.module.ts index 2df816c..4fcc186 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -63,6 +63,6 @@ import { GeographyModule } from '@modules/geography/geography.module'; GeographyModule, MessagerModule, ], - exports: [AdModule, MessagerModule], + exports: [AdModule, GeographyModule, MessagerModule], }) export class AppModule {} diff --git a/src/modules/ad/ad.di-tokens.ts b/src/modules/ad/ad.di-tokens.ts index d87cfdd..d4d5d64 100644 --- a/src/modules/ad/ad.di-tokens.ts +++ b/src/modules/ad/ad.di-tokens.ts @@ -1,3 +1,4 @@ export const AD_REPOSITORY = Symbol('AD_REPOSITORY'); export const GEOROUTER = Symbol('GEOROUTER'); +export const AD_DIRECTION_ENCODER = Symbol('AD_DIRECTION_ENCODER'); export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER'); diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index b4915c7..ba6dafe 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -1,5 +1,5 @@ import { Mapper } from '@mobicoop/ddd-library'; -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { AdEntity } from './core/domain/ad.entity'; import { AdWriteModel, @@ -9,6 +9,8 @@ import { import { Frequency } from './core/domain/ad.types'; import { v4 } from 'uuid'; import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object'; +import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; +import { AD_DIRECTION_ENCODER } from './ad.di-tokens'; /** * Mapper constructs objects that are used in different layers: @@ -21,6 +23,11 @@ import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.val export class AdMapper implements Mapper { + constructor( + @Inject(AD_DIRECTION_ENCODER) + private readonly directionEncoder: DirectionEncoderPort, + ) {} + toPersistence = (entity: AdEntity): AdWriteModel => { const copy = entity.getProps(); const now = new Date(); @@ -54,7 +61,7 @@ export class AdMapper driverDistance: copy.driverDistance, passengerDuration: copy.passengerDuration, passengerDistance: copy.passengerDistance, - waypoints: '', + waypoints: this.directionEncoder.encode(copy.waypoints), direction: '', fwdAzimuth: copy.fwdAzimuth, backAzimuth: copy.backAzimuth, diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index c846631..2106fba 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -1,11 +1,16 @@ import { Module, Provider } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; -import { AD_MESSAGE_PUBLISHER, AD_REPOSITORY } from './ad.di-tokens'; +import { + AD_MESSAGE_PUBLISHER, + AD_REPOSITORY, + AD_DIRECTION_ENCODER, +} from './ad.di-tokens'; import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; import { AdRepository } from './infrastructure/ad.repository'; import { PrismaService } from './infrastructure/prisma.service'; import { AdMapper } from './ad.mapper'; import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler'; +import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder'; const messageHandlers = [AdCreatedMessageHandler]; @@ -24,8 +29,16 @@ const messagePublishers: Provider[] = [ useExisting: MessageBrokerPublisher, }, ]; + const orms: Provider[] = [PrismaService]; +const adapters: Provider[] = [ + { + provide: AD_DIRECTION_ENCODER, + useClass: PostgresDirectionEncoder, + }, +]; + @Module({ imports: [CqrsModule], providers: [ @@ -34,7 +47,8 @@ const orms: Provider[] = [PrismaService]; ...repositories, ...messagePublishers, ...orms, + ...adapters, ], - exports: [PrismaService, AdMapper, AD_REPOSITORY], + exports: [PrismaService, AdMapper, AD_REPOSITORY, AD_DIRECTION_ENCODER], }) export class AdModule {} diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index bbb1143..a740a4b 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -1,3 +1,4 @@ +import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens'; import { AdMapper } from '@modules/ad/ad.mapper'; import { AdEntity } from '@modules/ad/core/domain/ad.entity'; import { Frequency } from '@modules/ad/core/domain/ad.types'; @@ -5,6 +6,7 @@ import { AdReadModel, AdWriteModel, } from '@modules/ad/infrastructure/ad.repository'; +import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; import { Test } from '@nestjs/testing'; const now = new Date('2023-06-21 06:00:00'); @@ -76,12 +78,26 @@ const adReadModel: AdReadModel = { updatedAt: now, }; +const mockDirectionEncoder: DirectionEncoderPort = { + encode: jest + .fn() + .mockImplementation( + () => "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", + ), +}; + describe('Ad Mapper', () => { let adMapper: AdMapper; beforeAll(async () => { const module = await Test.createTestingModule({ - providers: [AdMapper], + providers: [ + AdMapper, + { + provide: AD_DIRECTION_ENCODER, + useValue: mockDirectionEncoder, + }, + ], }).compile(); adMapper = module.get(AdMapper); }); @@ -93,6 +109,9 @@ describe('Ad Mapper', () => { it('should map domain entity to persistence data', async () => { const mapped: AdWriteModel = adMapper.toPersistence(adEntity); expect(mapped.schedule.create.length).toBe(1); + expect(mapped.waypoints).toBe( + "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", + ); }); it('should map persisted data to domain entity', async () => { diff --git a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts index 43ed4ac..3d12f92 100644 --- a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts +++ b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts @@ -1,6 +1,8 @@ +import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens'; import { AdMapper } from '@modules/ad/ad.mapper'; import { AdRepository } from '@modules/ad/infrastructure/ad.repository'; import { PrismaService } from '@modules/ad/infrastructure/prisma.service'; +import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; import { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter'; import { Test, TestingModule } from '@nestjs/testing'; @@ -8,6 +10,10 @@ const mockMessagePublisher = { publish: jest.fn().mockImplementation(), }; +const mockDirectionEncoder: DirectionEncoderPort = { + encode: jest.fn(), +}; + describe('Ad repository', () => { let prismaService: PrismaService; let adMapper: AdMapper; @@ -16,7 +22,14 @@ describe('Ad repository', () => { beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [EventEmitterModule.forRoot()], - providers: [PrismaService, AdMapper], + providers: [ + PrismaService, + AdMapper, + { + provide: AD_DIRECTION_ENCODER, + useValue: mockDirectionEncoder, + }, + ], }).compile(); prismaService = module.get(PrismaService); diff --git a/src/modules/geography/infrastructure/default-params-provider.ts b/src/modules/geography/infrastructure/default-params-provider.ts index 962468b..53261c3 100644 --- a/src/modules/geography/infrastructure/default-params-provider.ts +++ b/src/modules/geography/infrastructure/default-params-provider.ts @@ -5,9 +5,9 @@ import { DefaultParams } from '../core/application/types/default-params.type'; @Injectable() export class DefaultParamsProvider implements DefaultParamsProviderPort { - constructor(private readonly _configService: ConfigService) {} + constructor(private readonly configService: ConfigService) {} getParams = (): DefaultParams => ({ - GEOROUTER_TYPE: this._configService.get('GEOROUTER_TYPE'), - GEOROUTER_URL: this._configService.get('GEOROUTER_URL'), + GEOROUTER_TYPE: this.configService.get('GEOROUTER_TYPE'), + GEOROUTER_URL: this.configService.get('GEOROUTER_URL'), }); } diff --git a/src/modules/geography/infrastructure/postgres-direction-encoder.ts b/src/modules/geography/infrastructure/postgres-direction-encoder.ts index 9ffbcba..5d4aa3b 100644 --- a/src/modules/geography/infrastructure/postgres-direction-encoder.ts +++ b/src/modules/geography/infrastructure/postgres-direction-encoder.ts @@ -1,6 +1,8 @@ import { Coordinates } from '../core/application/types/coordinates.type'; import { DirectionEncoderPort } from '../core/application/ports/direction-encoder.port'; +import { Injectable } from '@nestjs/common'; +@Injectable() export class PostgresDirectionEncoder implements DirectionEncoderPort { encode = (coordinates: Coordinates[]): string => [ From bff199557ab2184da9007944a74ee6b6686a73f6 Mon Sep 17 00:00:00 2001 From: sbriat Date: Mon, 21 Aug 2023 14:40:04 +0200 Subject: [PATCH 04/24] add route provider in ad module --- src/modules/ad/ad.di-tokens.ts | 2 +- src/modules/ad/ad.mapper.ts | 34 +++++-- src/modules/ad/ad.module.ts | 6 ++ .../application/ports/route-provider.port.ts | 12 +++ src/modules/ad/core/domain/ad.types.ts | 5 + src/modules/ad/tests/unit/ad.mapper.spec.ts | 34 ++++++- .../unit/infrastructure/ad.repository.spec.ts | 14 ++- .../get-route/get-route.query-handler.ts | 19 ++++ .../queries/get-route/get-route.query.ts | 21 ++++ .../core/application/types/route.type.ts | 5 +- .../application/types/spacetime-point.type.ts | 6 ++ .../core/application/types/waypoint.type.ts | 5 + .../geography/core/domain/route.entity.ts | 97 +++++++++++++------ .../geography/core/domain/route.types.ts | 25 ++++- src/modules/geography/geography.di-tokens.ts | 1 + src/modules/geography/geography.mapper.ts | 39 ++++++++ src/modules/geography/geography.module.ts | 4 +- .../controllers/dtos/get-route.request.dto.ts | 9 ++ .../controllers/get-route.controller.ts | 26 +++++ .../interface/dtos/route.response.dto.ts | 12 +++ 20 files changed, 330 insertions(+), 46 deletions(-) create mode 100644 src/modules/ad/core/application/ports/route-provider.port.ts create mode 100644 src/modules/geography/core/application/queries/get-route/get-route.query-handler.ts create mode 100644 src/modules/geography/core/application/queries/get-route/get-route.query.ts create mode 100644 src/modules/geography/core/application/types/spacetime-point.type.ts create mode 100644 src/modules/geography/core/application/types/waypoint.type.ts create mode 100644 src/modules/geography/geography.mapper.ts create mode 100644 src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts create mode 100644 src/modules/geography/interface/controllers/get-route.controller.ts create mode 100644 src/modules/geography/interface/dtos/route.response.dto.ts diff --git a/src/modules/ad/ad.di-tokens.ts b/src/modules/ad/ad.di-tokens.ts index d4d5d64..3e2571d 100644 --- a/src/modules/ad/ad.di-tokens.ts +++ b/src/modules/ad/ad.di-tokens.ts @@ -1,4 +1,4 @@ export const AD_REPOSITORY = Symbol('AD_REPOSITORY'); -export const GEOROUTER = Symbol('GEOROUTER'); export const AD_DIRECTION_ENCODER = Symbol('AD_DIRECTION_ENCODER'); export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER'); +export const AD_ROUTE_PROVIDER = Symbol('AD_ROUTE_PROVIDER'); diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index ba6dafe..4412b1e 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -6,11 +6,13 @@ import { AdReadModel, ScheduleItemModel, } from './infrastructure/ad.repository'; -import { Frequency } from './core/domain/ad.types'; +import { Frequency, Role } from './core/domain/ad.types'; import { v4 } from 'uuid'; import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object'; import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; -import { AD_DIRECTION_ENCODER } from './ad.di-tokens'; +import { AD_DIRECTION_ENCODER, AD_ROUTE_PROVIDER } from './ad.di-tokens'; +import { RouteProviderPort } from './core/application/ports/route-provider.port'; +import { RouteResponseDto } from '@modules/geography/interface/dtos/route.response.dto'; /** * Mapper constructs objects that are used in different layers: @@ -26,11 +28,25 @@ export class AdMapper constructor( @Inject(AD_DIRECTION_ENCODER) private readonly directionEncoder: DirectionEncoderPort, + @Inject(AD_ROUTE_PROVIDER) + private readonly routeProvider: RouteProviderPort, ) {} toPersistence = (entity: AdEntity): AdWriteModel => { const copy = entity.getProps(); const now = new Date(); + const roles: Role[] = []; + if (copy.driver) roles.push(Role.DRIVER); + if (copy.passenger) roles.push(Role.PASSENGER); + const route: RouteResponseDto = this.routeProvider.get( + roles, + copy.waypoints, + { + withDistance: true, + withPoints: true, + withTime: false, + }, + ); const record: AdWriteModel = { uuid: copy.id, driver: copy.driver, @@ -57,14 +73,14 @@ export class AdMapper seatsProposed: copy.seatsProposed, seatsRequested: copy.seatsRequested, strict: copy.strict, - driverDuration: copy.driverDuration, - driverDistance: copy.driverDistance, - passengerDuration: copy.passengerDuration, - passengerDistance: copy.passengerDistance, + driverDuration: route.driverDuration, + driverDistance: route.driverDistance, + passengerDuration: route.passengerDuration, + passengerDistance: route.passengerDistance, waypoints: this.directionEncoder.encode(copy.waypoints), - direction: '', - fwdAzimuth: copy.fwdAzimuth, - backAzimuth: copy.backAzimuth, + direction: this.directionEncoder.encode(route.spacetimePoints), + fwdAzimuth: route.fwdAzimuth, + backAzimuth: route.backAzimuth, createdAt: copy.createdAt, updatedAt: copy.updatedAt, }; diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index 2106fba..a98751d 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -4,6 +4,7 @@ import { AD_MESSAGE_PUBLISHER, AD_REPOSITORY, AD_DIRECTION_ENCODER, + AD_ROUTE_PROVIDER, } from './ad.di-tokens'; import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; import { AdRepository } from './infrastructure/ad.repository'; @@ -11,6 +12,7 @@ import { PrismaService } from './infrastructure/prisma.service'; import { AdMapper } from './ad.mapper'; import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler'; import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder'; +import { GetRouteController } from '@modules/geography/interface/controllers/get-route.controller'; const messageHandlers = [AdCreatedMessageHandler]; @@ -37,6 +39,10 @@ const adapters: Provider[] = [ provide: AD_DIRECTION_ENCODER, useClass: PostgresDirectionEncoder, }, + { + provide: AD_ROUTE_PROVIDER, + useClass: GetRouteController, + }, ]; @Module({ diff --git a/src/modules/ad/core/application/ports/route-provider.port.ts b/src/modules/ad/core/application/ports/route-provider.port.ts new file mode 100644 index 0000000..a7a60a6 --- /dev/null +++ b/src/modules/ad/core/application/ports/route-provider.port.ts @@ -0,0 +1,12 @@ +import { GeorouterSettings } from '@modules/geography/core/application/types/georouter-settings.type'; +import { Waypoint } from '@modules/geography/core/application/types/waypoint.type'; +import { RouteResponseDto } from '@modules/geography/interface/dtos/route.response.dto'; +import { Role } from '../../domain/ad.types'; + +export interface RouteProviderPort { + get( + roles: Role[], + waypoints: Waypoint[], + georouterSettings: GeorouterSettings, + ): RouteResponseDto; +} diff --git a/src/modules/ad/core/domain/ad.types.ts b/src/modules/ad/core/domain/ad.types.ts index 8afef95..77fc02e 100644 --- a/src/modules/ad/core/domain/ad.types.ts +++ b/src/modules/ad/core/domain/ad.types.ts @@ -48,3 +48,8 @@ export enum PointContext { VENUE = 'VENUE', OTHER = 'OTHER', } + +export enum Role { + DRIVER = 'DRIVER', + PASSENGER = 'PASSENGER', +} diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index a740a4b..36f6beb 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -1,5 +1,9 @@ -import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens'; +import { + AD_DIRECTION_ENCODER, + AD_ROUTE_PROVIDER, +} from '@modules/ad/ad.di-tokens'; import { AdMapper } from '@modules/ad/ad.mapper'; +import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port'; import { AdEntity } from '@modules/ad/core/domain/ad.entity'; import { Frequency } from '@modules/ad/core/domain/ad.types'; import { @@ -81,11 +85,28 @@ const adReadModel: AdReadModel = { const mockDirectionEncoder: DirectionEncoderPort = { encode: jest .fn() - .mockImplementation( + .mockImplementationOnce( () => "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", + ) + .mockImplementationOnce( + () => + "'LINESTRING(6.1765102 48.689445,4.984578 48.725687,2.3522 48.8566)'", ), }; +const mockRouteProvider: RouteProviderPort = { + get: jest.fn().mockImplementation(() => ({ + driverDistance: 350101, + driverDuration: 14422, + passengerDistance: 350101, + passengerDuration: 14422, + fwdAzimuth: 273, + backAzimuth: 93, + distanceAzimuth: 336544, + spacetimePoints: [], + })), +}; + describe('Ad Mapper', () => { let adMapper: AdMapper; @@ -97,6 +118,10 @@ describe('Ad Mapper', () => { provide: AD_DIRECTION_ENCODER, useValue: mockDirectionEncoder, }, + { + provide: AD_ROUTE_PROVIDER, + useValue: mockRouteProvider, + }, ], }).compile(); adMapper = module.get(AdMapper); @@ -112,6 +137,11 @@ describe('Ad Mapper', () => { expect(mapped.waypoints).toBe( "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", ); + expect(mapped.direction).toBe( + "'LINESTRING(6.1765102 48.689445,4.984578 48.725687,2.3522 48.8566)'", + ); + expect(mapped.driverDuration).toBe(14422); + expect(mapped.fwdAzimuth).toBe(273); }); it('should map persisted data to domain entity', async () => { diff --git a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts index 3d12f92..1da3757 100644 --- a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts +++ b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts @@ -1,5 +1,9 @@ -import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens'; +import { + AD_DIRECTION_ENCODER, + AD_ROUTE_PROVIDER, +} from '@modules/ad/ad.di-tokens'; import { AdMapper } from '@modules/ad/ad.mapper'; +import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port'; import { AdRepository } from '@modules/ad/infrastructure/ad.repository'; import { PrismaService } from '@modules/ad/infrastructure/prisma.service'; import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; @@ -14,6 +18,10 @@ const mockDirectionEncoder: DirectionEncoderPort = { encode: jest.fn(), }; +const mockRouteProvider: RouteProviderPort = { + get: jest.fn(), +}; + describe('Ad repository', () => { let prismaService: PrismaService; let adMapper: AdMapper; @@ -29,6 +37,10 @@ describe('Ad repository', () => { provide: AD_DIRECTION_ENCODER, useValue: mockDirectionEncoder, }, + { + provide: AD_ROUTE_PROVIDER, + useValue: mockRouteProvider, + }, ], }).compile(); diff --git a/src/modules/geography/core/application/queries/get-route/get-route.query-handler.ts b/src/modules/geography/core/application/queries/get-route/get-route.query-handler.ts new file mode 100644 index 0000000..1a255aa --- /dev/null +++ b/src/modules/geography/core/application/queries/get-route/get-route.query-handler.ts @@ -0,0 +1,19 @@ +import { IQueryHandler, QueryHandler } from '@nestjs/cqrs'; +import { GetRouteQuery } from './get-route.query'; +import { RouteEntity } from '@modules/geography/core/domain/route.entity'; +import { Inject } from '@nestjs/common'; +import { GEOROUTER } from '@modules/geography/geography.di-tokens'; +import { GeorouterPort } from '../../ports/georouter.port'; + +@QueryHandler(GetRouteQuery) +export class GetRouteQueryHandler implements IQueryHandler { + constructor(@Inject(GEOROUTER) private readonly georouter: GeorouterPort) {} + + execute = async (query: GetRouteQuery): Promise => + await RouteEntity.create({ + roles: query.roles, + waypoints: query.waypoints, + georouter: this.georouter, + georouterSettings: query.georouterSettings, + }); +} diff --git a/src/modules/geography/core/application/queries/get-route/get-route.query.ts b/src/modules/geography/core/application/queries/get-route/get-route.query.ts new file mode 100644 index 0000000..4b8c6fd --- /dev/null +++ b/src/modules/geography/core/application/queries/get-route/get-route.query.ts @@ -0,0 +1,21 @@ +import { QueryBase } from '@mobicoop/ddd-library'; +import { Role } from '@modules/geography/core/domain/route.types'; +import { Waypoint } from '../../types/waypoint.type'; +import { GeorouterSettings } from '../../types/georouter-settings.type'; + +export class GetRouteQuery extends QueryBase { + readonly roles: Role[]; + readonly waypoints: Waypoint[]; + readonly georouterSettings: GeorouterSettings; + + constructor( + roles: Role[], + waypoints: Waypoint[], + georouterSettings: GeorouterSettings, + ) { + super(); + this.roles = roles; + this.waypoints = waypoints; + this.georouterSettings = georouterSettings; + } +} diff --git a/src/modules/geography/core/application/types/route.type.ts b/src/modules/geography/core/application/types/route.type.ts index f202e52..d49c2e4 100644 --- a/src/modules/geography/core/application/types/route.type.ts +++ b/src/modules/geography/core/application/types/route.type.ts @@ -1,11 +1,14 @@ +import { PathType } from '../../domain/route.types'; import { Point } from './point.type'; +import { SpacetimePoint } from './spacetime-point.type'; export type Route = { - name: string; + type: PathType; distance: number; duration: number; fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; points: Point[]; + spacetimePoints: SpacetimePoint[]; }; diff --git a/src/modules/geography/core/application/types/spacetime-point.type.ts b/src/modules/geography/core/application/types/spacetime-point.type.ts new file mode 100644 index 0000000..6822b1c --- /dev/null +++ b/src/modules/geography/core/application/types/spacetime-point.type.ts @@ -0,0 +1,6 @@ +import { Point } from './point.type'; + +export type SpacetimePoint = Point & { + duration: number; + distance: number; +}; diff --git a/src/modules/geography/core/application/types/waypoint.type.ts b/src/modules/geography/core/application/types/waypoint.type.ts new file mode 100644 index 0000000..af76297 --- /dev/null +++ b/src/modules/geography/core/application/types/waypoint.type.ts @@ -0,0 +1,5 @@ +import { Point } from './point.type'; + +export type Waypoint = Point & { + position: number; +}; diff --git a/src/modules/geography/core/domain/route.entity.ts b/src/modules/geography/core/domain/route.entity.ts index d5bf02f..a4a5822 100644 --- a/src/modules/geography/core/domain/route.entity.ts +++ b/src/modules/geography/core/domain/route.entity.ts @@ -5,19 +5,61 @@ import { Role, RouteProps, PathType, + Direction, } from './route.types'; import { WaypointProps } from './value-objects/waypoint.value-object'; +import { Route } from '../application/types/route.type'; +import { v4 } from 'uuid'; export class RouteEntity extends AggregateRoot { protected readonly _id: AggregateID; static create = async (create: CreateRouteProps): Promise => { - const props: RouteProps = await create.georouter.routes( + const directions: Direction[] = await create.georouter.routes( this.getPaths(create.roles, create.waypoints), create.georouterSettings, ); - const route = new RouteEntity({ props }); - return route; + let driverRoute: Route; + let passengerRoute: Route; + if (directions.some((route: Route) => route.type == PathType.GENERIC)) { + driverRoute = passengerRoute = directions.find( + (route: Route) => route.type == PathType.GENERIC, + ); + } else { + driverRoute = directions.some( + (route: Route) => route.type == PathType.DRIVER, + ) + ? directions.find((route: Route) => route.type == PathType.DRIVER) + : undefined; + passengerRoute = directions.some( + (route: Route) => route.type == PathType.PASSENGER, + ) + ? directions.find((route: Route) => route.type == PathType.PASSENGER) + : undefined; + } + const routeProps: RouteProps = { + driverDistance: driverRoute?.distance, + driverDuration: driverRoute?.duration, + passengerDistance: passengerRoute?.distance, + passengerDuration: passengerRoute?.duration, + fwdAzimuth: driverRoute + ? driverRoute.fwdAzimuth + : passengerRoute.fwdAzimuth, + backAzimuth: driverRoute + ? driverRoute.backAzimuth + : passengerRoute.backAzimuth, + distanceAzimuth: driverRoute + ? driverRoute.distanceAzimuth + : passengerRoute.distanceAzimuth, + waypoints: create.waypoints, + spacetimePoints: driverRoute + ? driverRoute.spacetimePoints + : passengerRoute.spacetimePoints, + }; + return new RouteEntity({ + id: v4(), + props: routeProps, + }); }; validate(): void { @@ -32,39 +74,40 @@ export class RouteEntity extends AggregateRoot { if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) { if (waypoints.length == 2) { // 2 points => same route for driver and passenger - const commonPath: Path = { - type: PathType.COMMON, - points: waypoints, - }; - paths.push(commonPath); + paths.push(this.createGenericPath(waypoints)); } else { - const driverPath: Path = RouteEntity.createDriverPath(waypoints); - const passengerPath: Path = RouteEntity.createPassengerPath(waypoints); - paths.push(driverPath, passengerPath); + paths.push( + this.createDriverPath(waypoints), + this.createPassengerPath(waypoints), + ); } } else if (roles.includes(Role.DRIVER)) { - const driverPath: Path = RouteEntity.createDriverPath(waypoints); - paths.push(driverPath); + paths.push(this.createDriverPath(waypoints)); } else if (roles.includes(Role.PASSENGER)) { - const passengerPath: Path = RouteEntity.createPassengerPath(waypoints); - paths.push(passengerPath); + paths.push(this.createPassengerPath(waypoints)); } return paths; }; - private static createDriverPath = (waypoints: WaypointProps[]): Path => { - return { - type: PathType.DRIVER, - points: waypoints, - }; - }; + private static createGenericPath = (waypoints: WaypointProps[]): Path => + this.createPath(waypoints, PathType.GENERIC); - private static createPassengerPath = (waypoints: WaypointProps[]): Path => { - return { - type: PathType.PASSENGER, - points: [waypoints[0], waypoints[waypoints.length - 1]], - }; - }; + private static createDriverPath = (waypoints: WaypointProps[]): Path => + this.createPath(waypoints, PathType.DRIVER); + + private static createPassengerPath = (waypoints: WaypointProps[]): Path => + this.createPath( + [waypoints[0], waypoints[waypoints.length - 1]], + PathType.PASSENGER, + ); + + private static createPath = ( + points: WaypointProps[], + type: PathType, + ): Path => ({ + type, + points, + }); } // import { IGeodesic } from '../interfaces/geodesic.interface'; diff --git a/src/modules/geography/core/domain/route.types.ts b/src/modules/geography/core/domain/route.types.ts index d9d3674..1df57c9 100644 --- a/src/modules/geography/core/domain/route.types.ts +++ b/src/modules/geography/core/domain/route.types.ts @@ -5,9 +5,10 @@ import { WaypointProps } from './value-objects/waypoint.value-object'; // All properties that a Route has export interface RouteProps { - name: string; - distance: number; - duration: number; + driverDistance?: number; + driverDuration?: number; + passengerDistance?: number; + passengerDuration?: number; fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; @@ -23,6 +24,17 @@ export interface CreateRouteProps { georouterSettings: GeorouterSettings; } +export type Direction = { + type: PathType; + distance: number; + duration: number; + fwdAzimuth: number; + backAzimuth: number; + distanceAzimuth: number; + points: Point[]; + spacetimePoints: SpacetimePoint[]; +}; + export type Path = { type: PathType; points: Point[]; @@ -34,6 +46,11 @@ export type Point = { context?: PointContext; }; +export type SpacetimePoint = Point & { + duration: number; + distance: number; +}; + export enum Role { DRIVER = 'DRIVER', PASSENGER = 'PASSENGER', @@ -48,7 +65,7 @@ export enum PointContext { } export enum PathType { - COMMON = 'common', + GENERIC = 'generic', DRIVER = 'driver', PASSENGER = 'passenger', } diff --git a/src/modules/geography/geography.di-tokens.ts b/src/modules/geography/geography.di-tokens.ts index 647e261..98e9456 100644 --- a/src/modules/geography/geography.di-tokens.ts +++ b/src/modules/geography/geography.di-tokens.ts @@ -1,2 +1,3 @@ export const PARAMS_PROVIDER = Symbol('PARAMS_PROVIDER'); export const DIRECTION_ENCODER = Symbol('DIRECTION_ENCODER'); +export const GEOROUTER = Symbol('GEOROUTER'); diff --git a/src/modules/geography/geography.mapper.ts b/src/modules/geography/geography.mapper.ts new file mode 100644 index 0000000..0c8aaca --- /dev/null +++ b/src/modules/geography/geography.mapper.ts @@ -0,0 +1,39 @@ +import { Mapper } from '@mobicoop/ddd-library'; +import { Injectable } from '@nestjs/common'; +import { RouteEntity } from './core/domain/route.entity'; +import { RouteResponseDto } from './interface/dtos/route.response.dto'; + +/** + * Mapper constructs objects that are used in different layers: + * Record is an object that is stored in a database, + * Entity is an object that is used in application domain layer, + * and a ResponseDTO is an object returned to a user (usually as json). + */ + +@Injectable() +export class RouteMapper + implements Mapper +{ + toPersistence = (): undefined => { + return undefined; + }; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + toDomain = (): undefined => { + return undefined; + }; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + toResponse = (entity: RouteEntity): RouteResponseDto => { + const response = new RouteResponseDto(); + response.driverDistance = entity.getProps().driverDistance; + response.driverDuration = entity.getProps().driverDuration; + response.passengerDistance = entity.getProps().passengerDistance; + response.passengerDuration = entity.getProps().passengerDuration; + response.fwdAzimuth = entity.getProps().fwdAzimuth; + response.backAzimuth = entity.getProps().backAzimuth; + response.distanceAzimuth = entity.getProps().distanceAzimuth; + response.spacetimePoints = entity.getProps().spacetimePoints; + return response; + }; +} diff --git a/src/modules/geography/geography.module.ts b/src/modules/geography/geography.module.ts index c1aff74..d974d9b 100644 --- a/src/modules/geography/geography.module.ts +++ b/src/modules/geography/geography.module.ts @@ -3,6 +3,7 @@ import { CqrsModule } from '@nestjs/cqrs'; import { DIRECTION_ENCODER, PARAMS_PROVIDER } from './geography.di-tokens'; import { DefaultParamsProvider } from './infrastructure/default-params-provider'; import { PostgresDirectionEncoder } from './infrastructure/postgres-direction-encoder'; +import { GetRouteController } from './interface/controllers/get-route.controller'; const adapters: Provider[] = [ { @@ -13,11 +14,12 @@ const adapters: Provider[] = [ provide: DIRECTION_ENCODER, useClass: PostgresDirectionEncoder, }, + GetRouteController, ]; @Module({ imports: [CqrsModule], providers: [...adapters], - exports: [DIRECTION_ENCODER], + exports: [DIRECTION_ENCODER, GetRouteController], }) export class GeographyModule {} diff --git a/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts b/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts new file mode 100644 index 0000000..b57502e --- /dev/null +++ b/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts @@ -0,0 +1,9 @@ +import { GeorouterSettings } from '@modules/geography/core/application/types/georouter-settings.type'; +import { Waypoint } from '@modules/geography/core/application/types/waypoint.type'; +import { Role } from '@modules/geography/core/domain/route.types'; + +export class GetRouteRequestDto { + roles: Role[]; + waypoints: Waypoint[]; + georouterSettings: GeorouterSettings; +} diff --git a/src/modules/geography/interface/controllers/get-route.controller.ts b/src/modules/geography/interface/controllers/get-route.controller.ts new file mode 100644 index 0000000..8fdd2f9 --- /dev/null +++ b/src/modules/geography/interface/controllers/get-route.controller.ts @@ -0,0 +1,26 @@ +import { QueryBus } from '@nestjs/cqrs'; +import { RouteResponseDto } from '../dtos/route.response.dto'; +import { GetRouteRequestDto } from './dtos/get-route.request.dto'; +import { RouteEntity } from '@modules/geography/core/domain/route.entity'; +import { GetRouteQuery } from '@modules/geography/core/application/queries/get-route/get-route.query'; +import { RouteMapper } from '@modules/geography/geography.mapper'; +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class GetRouteController { + constructor( + private readonly queryBus: QueryBus, + private readonly mapper: RouteMapper, + ) {} + + async get(data: GetRouteRequestDto): Promise { + try { + const route: RouteEntity = await this.queryBus.execute( + new GetRouteQuery(data.roles, data.waypoints, data.georouterSettings), + ); + return this.mapper.toResponse(route); + } catch (e) { + throw e; + } + } +} diff --git a/src/modules/geography/interface/dtos/route.response.dto.ts b/src/modules/geography/interface/dtos/route.response.dto.ts new file mode 100644 index 0000000..6829714 --- /dev/null +++ b/src/modules/geography/interface/dtos/route.response.dto.ts @@ -0,0 +1,12 @@ +import { SpacetimePoint } from '@modules/geography/core/application/types/spacetime-point.type'; + +export class RouteResponseDto { + driverDistance?: number; + driverDuration?: number; + passengerDistance?: number; + passengerDuration?: number; + fwdAzimuth: number; + backAzimuth: number; + distanceAzimuth: number; + spacetimePoints: SpacetimePoint[]; +} From 1dd44b14258a5b66ce2caef42f4462b879e04914 Mon Sep 17 00:00:00 2001 From: sbriat Date: Mon, 21 Aug 2023 15:24:34 +0200 Subject: [PATCH 05/24] simplify ad --- src/modules/ad/ad.mapper.ts | 18 +++++++----------- .../application/ports/route-provider.port.ts | 8 ++++---- .../core/application/types/coordinates.type.ts | 4 ++++ .../types/georouter-settings.type.ts | 5 +++++ .../ad/core/application/types/route.type.ts | 11 +++++++++++ .../ad/core/application/types/waypoint.type.ts | 7 ++----- src/modules/ad/core/domain/ad.types.ts | 8 -------- .../value-objects/waypoint.value-object.ts | 6 ------ .../ad/interface/message-handlers/ad.types.ts | 3 +-- src/modules/ad/tests/unit/ad.mapper.spec.ts | 15 ++++++++++++++- .../unit/core/waypoint.value-object.spec.ts | 16 +--------------- 11 files changed, 49 insertions(+), 52 deletions(-) create mode 100644 src/modules/ad/core/application/types/coordinates.type.ts create mode 100644 src/modules/ad/core/application/types/georouter-settings.type.ts create mode 100644 src/modules/ad/core/application/types/route.type.ts diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index 4412b1e..0f38427 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -12,7 +12,7 @@ import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.val import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; import { AD_DIRECTION_ENCODER, AD_ROUTE_PROVIDER } from './ad.di-tokens'; import { RouteProviderPort } from './core/application/ports/route-provider.port'; -import { RouteResponseDto } from '@modules/geography/interface/dtos/route.response.dto'; +import { Route } from './core/application/types/route.type'; /** * Mapper constructs objects that are used in different layers: @@ -38,15 +38,11 @@ export class AdMapper const roles: Role[] = []; if (copy.driver) roles.push(Role.DRIVER); if (copy.passenger) roles.push(Role.PASSENGER); - const route: RouteResponseDto = this.routeProvider.get( - roles, - copy.waypoints, - { - withDistance: true, - withPoints: true, - withTime: false, - }, - ); + const route: Route = this.routeProvider.get(roles, copy.waypoints, { + points: true, + detailedDistance: false, + detailedDuration: false, + }); const record: AdWriteModel = { uuid: copy.id, driver: copy.driver, @@ -78,7 +74,7 @@ export class AdMapper passengerDuration: route.passengerDuration, passengerDistance: route.passengerDistance, waypoints: this.directionEncoder.encode(copy.waypoints), - direction: this.directionEncoder.encode(route.spacetimePoints), + direction: this.directionEncoder.encode(route.points), fwdAzimuth: route.fwdAzimuth, backAzimuth: route.backAzimuth, createdAt: copy.createdAt, diff --git a/src/modules/ad/core/application/ports/route-provider.port.ts b/src/modules/ad/core/application/ports/route-provider.port.ts index a7a60a6..7ac93be 100644 --- a/src/modules/ad/core/application/ports/route-provider.port.ts +++ b/src/modules/ad/core/application/ports/route-provider.port.ts @@ -1,12 +1,12 @@ -import { GeorouterSettings } from '@modules/geography/core/application/types/georouter-settings.type'; -import { Waypoint } from '@modules/geography/core/application/types/waypoint.type'; -import { RouteResponseDto } from '@modules/geography/interface/dtos/route.response.dto'; +import { GeorouterSettings } from '../types/georouter-settings.type'; import { Role } from '../../domain/ad.types'; +import { Waypoint } from '../types/waypoint.type'; +import { Route } from '../types/route.type'; export interface RouteProviderPort { get( roles: Role[], waypoints: Waypoint[], georouterSettings: GeorouterSettings, - ): RouteResponseDto; + ): Route; } diff --git a/src/modules/ad/core/application/types/coordinates.type.ts b/src/modules/ad/core/application/types/coordinates.type.ts new file mode 100644 index 0000000..8e149ed --- /dev/null +++ b/src/modules/ad/core/application/types/coordinates.type.ts @@ -0,0 +1,4 @@ +export type Coordinates = { + lon: number; + lat: number; +}; diff --git a/src/modules/ad/core/application/types/georouter-settings.type.ts b/src/modules/ad/core/application/types/georouter-settings.type.ts new file mode 100644 index 0000000..ae5b391 --- /dev/null +++ b/src/modules/ad/core/application/types/georouter-settings.type.ts @@ -0,0 +1,5 @@ +export type GeorouterSettings = { + points: boolean; + detailedDuration: boolean; + detailedDistance: boolean; +}; diff --git a/src/modules/ad/core/application/types/route.type.ts b/src/modules/ad/core/application/types/route.type.ts new file mode 100644 index 0000000..971e2a9 --- /dev/null +++ b/src/modules/ad/core/application/types/route.type.ts @@ -0,0 +1,11 @@ +import { Coordinates } from './coordinates.type'; + +export type Route = { + driverDistance?: number; + driverDuration?: number; + passengerDistance?: number; + passengerDuration?: number; + fwdAzimuth: number; + backAzimuth: number; + points: Coordinates[]; +}; diff --git a/src/modules/ad/core/application/types/waypoint.type.ts b/src/modules/ad/core/application/types/waypoint.type.ts index f3e4a99..ba91158 100644 --- a/src/modules/ad/core/application/types/waypoint.type.ts +++ b/src/modules/ad/core/application/types/waypoint.type.ts @@ -1,8 +1,5 @@ -import { PointContext } from '../../domain/ad.types'; +import { Coordinates } from './coordinates.type'; export type Waypoint = { position: number; - context?: PointContext; - lon: number; - lat: number; -}; +} & Coordinates; diff --git a/src/modules/ad/core/domain/ad.types.ts b/src/modules/ad/core/domain/ad.types.ts index 77fc02e..ad2c7ef 100644 --- a/src/modules/ad/core/domain/ad.types.ts +++ b/src/modules/ad/core/domain/ad.types.ts @@ -41,14 +41,6 @@ export enum Frequency { RECURRENT = 'RECURRENT', } -export enum PointContext { - HOUSE_NUMBER = 'HOUSE_NUMBER', - STREET_ADDRESS = 'STREET_ADDRESS', - LOCALITY = 'LOCALITY', - VENUE = 'VENUE', - OTHER = 'OTHER', -} - export enum Role { DRIVER = 'DRIVER', PASSENGER = 'PASSENGER', diff --git a/src/modules/ad/core/domain/value-objects/waypoint.value-object.ts b/src/modules/ad/core/domain/value-objects/waypoint.value-object.ts index 7dcadc2..353f51d 100644 --- a/src/modules/ad/core/domain/value-objects/waypoint.value-object.ts +++ b/src/modules/ad/core/domain/value-objects/waypoint.value-object.ts @@ -3,7 +3,6 @@ import { ArgumentOutOfRangeException, ValueObject, } from '@mobicoop/ddd-library'; -import { PointContext } from '../ad.types'; /** Note: * Value Objects with multiple properties can contain @@ -14,7 +13,6 @@ export interface WaypointProps { position: number; lon: number; lat: number; - context?: PointContext; } export class Waypoint extends ValueObject { @@ -30,10 +28,6 @@ export class Waypoint extends ValueObject { return this.props.lat; } - get context(): PointContext { - return this.props.context; - } - protected validate(props: WaypointProps): void { if (props.position < 0) throw new ArgumentInvalidException( diff --git a/src/modules/ad/interface/message-handlers/ad.types.ts b/src/modules/ad/interface/message-handlers/ad.types.ts index f795309..1deb105 100644 --- a/src/modules/ad/interface/message-handlers/ad.types.ts +++ b/src/modules/ad/interface/message-handlers/ad.types.ts @@ -1,4 +1,4 @@ -import { Frequency, PointContext } from '@modules/ad/core/domain/ad.types'; +import { Frequency } from '@modules/ad/core/domain/ad.types'; export type Ad = { id: string; @@ -31,5 +31,4 @@ export type Waypoint = { country: string; lon: number; lat: number; - context?: PointContext; }; diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index 36f6beb..a854e3d 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -103,7 +103,20 @@ const mockRouteProvider: RouteProviderPort = { fwdAzimuth: 273, backAzimuth: 93, distanceAzimuth: 336544, - spacetimePoints: [], + points: [ + { + lon: 6.1765102, + lat: 48.689445, + }, + { + lon: 4.984578, + lat: 48.725687, + }, + { + lon: 2.3522, + lat: 48.8566, + }, + ], })), }; diff --git a/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts index 1d6e334..a2f363f 100644 --- a/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts +++ b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts @@ -2,11 +2,10 @@ import { ArgumentInvalidException, ArgumentOutOfRangeException, } from '@mobicoop/ddd-library'; -import { PointContext } from '@modules/ad/core/domain/ad.types'; import { Waypoint } from '@modules/ad/core/domain/value-objects/waypoint.value-object'; describe('Waypoint value object', () => { - it('should create a waypoint value object without context', () => { + it('should create a waypoint value object', () => { const waypointVO = new Waypoint({ position: 0, lon: 48.689445, @@ -15,19 +14,6 @@ describe('Waypoint value object', () => { expect(waypointVO.position).toBe(0); expect(waypointVO.lon).toBe(48.689445); expect(waypointVO.lat).toBe(6.17651); - expect(waypointVO.context).toBeUndefined(); - }); - it('should create a waypoint value object with context', () => { - const waypointVO = new Waypoint({ - position: 0, - lon: 48.689445, - lat: 6.17651, - context: PointContext.HOUSE_NUMBER, - }); - expect(waypointVO.position).toBe(0); - expect(waypointVO.lon).toBe(48.689445); - expect(waypointVO.lat).toBe(6.17651); - expect(waypointVO.context).toBe(PointContext.HOUSE_NUMBER); }); it('should throw an exception if position is invalid', () => { try { From e93d8b0c9d0033e855ab4c2664f84fdff95b0791 Mon Sep 17 00:00:00 2001 From: sbriat Date: Mon, 21 Aug 2023 16:00:37 +0200 Subject: [PATCH 06/24] add direction decoder --- src/modules/ad/ad.mapper.ts | 7 ++++++- src/modules/ad/tests/unit/ad.mapper.spec.ts | 11 +++++++++++ .../tests/unit/infrastructure/ad.repository.spec.ts | 1 + .../core/application/ports/direction-encoder.port.ts | 1 + .../infrastructure/postgres-direction-encoder.ts | 10 ++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index 0f38427..18690b9 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -112,7 +112,12 @@ export class AdMapper driverDistance: record.driverDistance, passengerDuration: record.passengerDuration, passengerDistance: record.passengerDistance, - waypoints: [], + waypoints: this.directionEncoder + .decode(record.waypoints) + .map((coordinates, index) => ({ + position: index, + ...coordinates, + })), fwdAzimuth: record.fwdAzimuth, backAzimuth: record.backAzimuth, }, diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index a854e3d..646e7aa 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -92,6 +92,16 @@ const mockDirectionEncoder: DirectionEncoderPort = { () => "'LINESTRING(6.1765102 48.689445,4.984578 48.725687,2.3522 48.8566)'", ), + decode: jest.fn().mockImplementation(() => [ + { + lon: 6.1765102, + lat: 48.689445, + }, + { + lon: 2.3522, + lat: 48.8566, + }, + ]), }; const mockRouteProvider: RouteProviderPort = { @@ -161,6 +171,7 @@ describe('Ad Mapper', () => { const mapped: AdEntity = adMapper.toDomain(adReadModel); expect(mapped.getProps().schedule.length).toBe(1); expect(mapped.getProps().schedule[0].time).toBe('07:05'); + expect(mapped.getProps().waypoints.length).toBe(2); }); it('should map domain entity to response', async () => { diff --git a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts index 1da3757..2dfe7e4 100644 --- a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts +++ b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts @@ -16,6 +16,7 @@ const mockMessagePublisher = { const mockDirectionEncoder: DirectionEncoderPort = { encode: jest.fn(), + decode: jest.fn(), }; const mockRouteProvider: RouteProviderPort = { diff --git a/src/modules/geography/core/application/ports/direction-encoder.port.ts b/src/modules/geography/core/application/ports/direction-encoder.port.ts index 333f8ba..3251915 100644 --- a/src/modules/geography/core/application/ports/direction-encoder.port.ts +++ b/src/modules/geography/core/application/ports/direction-encoder.port.ts @@ -2,4 +2,5 @@ import { Coordinates } from '../types/coordinates.type'; export interface DirectionEncoderPort { encode(coordinates: Coordinates[]): string; + decode(direction: string): Coordinates[]; } diff --git a/src/modules/geography/infrastructure/postgres-direction-encoder.ts b/src/modules/geography/infrastructure/postgres-direction-encoder.ts index 5d4aa3b..b4c8001 100644 --- a/src/modules/geography/infrastructure/postgres-direction-encoder.ts +++ b/src/modules/geography/infrastructure/postgres-direction-encoder.ts @@ -10,4 +10,14 @@ export class PostgresDirectionEncoder implements DirectionEncoderPort { coordinates.map((point) => [point.lon, point.lat].join(' ')).join(), ")'", ].join(''); + decode = (direction: string): Coordinates[] => + direction + .split('(')[1] + .split(')')[0] + .split(',') + .map((coordinates) => coordinates.split(' ')) + .map((point) => ({ + lon: parseFloat(point[0]), + lat: parseFloat(point[1]), + })); } From dad964b39cfcc8328aced84b0ef400df12a9e663 Mon Sep 17 00:00:00 2001 From: sbriat Date: Mon, 21 Aug 2023 17:06:28 +0200 Subject: [PATCH 07/24] route tests --- .../types/georouter-settings.type.ts | 6 +- .../core/application/types/path.type.ts | 4 +- .../core/application/types/point.type.ts | 6 - .../core/application/types/route.type.ts | 4 +- .../application/types/spacetime-point.type.ts | 4 +- .../core/application/types/waypoint.type.ts | 4 +- .../geography/core/domain/route.entity.ts | 16 +- .../geography/core/domain/route.errors.ts | 11 + .../tests/unit/core/route.entity.spec.ts | 256 ++++++++++++++++++ 9 files changed, 290 insertions(+), 21 deletions(-) delete mode 100644 src/modules/geography/core/application/types/point.type.ts create mode 100644 src/modules/geography/core/domain/route.errors.ts create mode 100644 src/modules/geography/tests/unit/core/route.entity.spec.ts diff --git a/src/modules/geography/core/application/types/georouter-settings.type.ts b/src/modules/geography/core/application/types/georouter-settings.type.ts index d8f73ae..ae5b391 100644 --- a/src/modules/geography/core/application/types/georouter-settings.type.ts +++ b/src/modules/geography/core/application/types/georouter-settings.type.ts @@ -1,5 +1,5 @@ export type GeorouterSettings = { - withPoints: boolean; - withTime: boolean; - withDistance: boolean; + points: boolean; + detailedDuration: boolean; + detailedDistance: boolean; }; diff --git a/src/modules/geography/core/application/types/path.type.ts b/src/modules/geography/core/application/types/path.type.ts index 1f4a6eb..2f8e46e 100644 --- a/src/modules/geography/core/application/types/path.type.ts +++ b/src/modules/geography/core/application/types/path.type.ts @@ -1,7 +1,7 @@ import { PathType } from '../../domain/route.types'; -import { Point } from './point.type'; +import { Coordinates } from './coordinates.type'; export type Path = { type: PathType; - points: Point[]; + points: Coordinates[]; }; diff --git a/src/modules/geography/core/application/types/point.type.ts b/src/modules/geography/core/application/types/point.type.ts deleted file mode 100644 index 6f71f0f..0000000 --- a/src/modules/geography/core/application/types/point.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { PointContext } from '../../domain/route.types'; -import { Coordinates } from './coordinates.type'; - -export type Point = Coordinates & { - context?: PointContext; -}; diff --git a/src/modules/geography/core/application/types/route.type.ts b/src/modules/geography/core/application/types/route.type.ts index d49c2e4..3913deb 100644 --- a/src/modules/geography/core/application/types/route.type.ts +++ b/src/modules/geography/core/application/types/route.type.ts @@ -1,5 +1,5 @@ import { PathType } from '../../domain/route.types'; -import { Point } from './point.type'; +import { Coordinates } from './coordinates.type'; import { SpacetimePoint } from './spacetime-point.type'; export type Route = { @@ -9,6 +9,6 @@ export type Route = { fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; - points: Point[]; + points: Coordinates[]; spacetimePoints: SpacetimePoint[]; }; diff --git a/src/modules/geography/core/application/types/spacetime-point.type.ts b/src/modules/geography/core/application/types/spacetime-point.type.ts index 6822b1c..9bed0c5 100644 --- a/src/modules/geography/core/application/types/spacetime-point.type.ts +++ b/src/modules/geography/core/application/types/spacetime-point.type.ts @@ -1,6 +1,6 @@ -import { Point } from './point.type'; +import { Coordinates } from './coordinates.type'; -export type SpacetimePoint = Point & { +export type SpacetimePoint = Coordinates & { duration: number; distance: number; }; diff --git a/src/modules/geography/core/application/types/waypoint.type.ts b/src/modules/geography/core/application/types/waypoint.type.ts index af76297..3c635d5 100644 --- a/src/modules/geography/core/application/types/waypoint.type.ts +++ b/src/modules/geography/core/application/types/waypoint.type.ts @@ -1,5 +1,5 @@ -import { Point } from './point.type'; +import { Coordinates } from './coordinates.type'; -export type Waypoint = Point & { +export type Waypoint = Coordinates & { position: number; }; diff --git a/src/modules/geography/core/domain/route.entity.ts b/src/modules/geography/core/domain/route.entity.ts index a4a5822..705a4c2 100644 --- a/src/modules/geography/core/domain/route.entity.ts +++ b/src/modules/geography/core/domain/route.entity.ts @@ -10,15 +10,23 @@ import { import { WaypointProps } from './value-objects/waypoint.value-object'; import { Route } from '../application/types/route.type'; import { v4 } from 'uuid'; +import { RouteNotFoundException } from './route.errors'; export class RouteEntity extends AggregateRoot { protected readonly _id: AggregateID; static create = async (create: CreateRouteProps): Promise => { - const directions: Direction[] = await create.georouter.routes( - this.getPaths(create.roles, create.waypoints), - create.georouterSettings, - ); + let directions: Direction[]; + try { + directions = await create.georouter.routes( + this.getPaths(create.roles, create.waypoints), + create.georouterSettings, + ); + if (!directions || directions.length == 0) + throw new RouteNotFoundException(); + } catch (e: any) { + throw e; + } let driverRoute: Route; let passengerRoute: Route; if (directions.some((route: Route) => route.type == PathType.GENERIC)) { diff --git a/src/modules/geography/core/domain/route.errors.ts b/src/modules/geography/core/domain/route.errors.ts new file mode 100644 index 0000000..a0f484b --- /dev/null +++ b/src/modules/geography/core/domain/route.errors.ts @@ -0,0 +1,11 @@ +import { ExceptionBase } from '@mobicoop/ddd-library'; + +export class RouteNotFoundException extends ExceptionBase { + static readonly message = 'Route not found'; + + public readonly code = 'ROUTE.NOT_FOUND'; + + constructor(cause?: Error, metadata?: unknown) { + super(RouteNotFoundException.message, cause, metadata); + } +} diff --git a/src/modules/geography/tests/unit/core/route.entity.spec.ts b/src/modules/geography/tests/unit/core/route.entity.spec.ts new file mode 100644 index 0000000..5c0eaf3 --- /dev/null +++ b/src/modules/geography/tests/unit/core/route.entity.spec.ts @@ -0,0 +1,256 @@ +import { GeorouterPort } from '@modules/geography/core/application/ports/georouter.port'; +import { Coordinates } from '@modules/geography/core/application/types/coordinates.type'; +import { RouteEntity } from '@modules/geography/core/domain/route.entity'; +import { RouteNotFoundException } from '@modules/geography/core/domain/route.errors'; +import { + CreateRouteProps, + PathType, + Role, +} from '@modules/geography/core/domain/route.types'; + +const originCoordinates: Coordinates = { + lon: 48.689445, + lat: 6.17651, +}; +const destinationCoordinates: Coordinates = { + lon: 48.8566, + lat: 2.3522, +}; +const additionalCoordinates: Coordinates = { + lon: 48.7566, + lat: 4.4498, +}; + +const mockGeorouter: GeorouterPort = { + routes: jest + .fn() + .mockImplementationOnce(() => [ + { + type: PathType.DRIVER, + distance: 350101, + duration: 14422, + fwdAzimuth: 273, + backAzimuth: 93, + distanceAzimuth: 336544, + points: [ + { + lon: 6.1765102, + lat: 48.689445, + }, + { + lon: 4.984578, + lat: 48.725687, + }, + { + lon: 2.3522, + lat: 48.8566, + }, + ], + spacetimePoints: [], + }, + ]) + .mockImplementationOnce(() => [ + { + type: PathType.PASSENGER, + distance: 350102, + duration: 14423, + fwdAzimuth: 273, + backAzimuth: 93, + distanceAzimuth: 336545, + points: [ + { + lon: 6.1765103, + lat: 48.689446, + }, + { + lon: 4.984579, + lat: 48.725688, + }, + { + lon: 2.3523, + lat: 48.8567, + }, + ], + spacetimePoints: [], + }, + ]) + .mockImplementationOnce(() => [ + { + type: PathType.GENERIC, + distance: 350100, + duration: 14421, + fwdAzimuth: 273, + backAzimuth: 93, + distanceAzimuth: 336543, + points: [ + { + lon: 6.1765101, + lat: 48.689444, + }, + { + lon: 4.984577, + lat: 48.725686, + }, + { + lon: 2.3521, + lat: 48.8565, + }, + ], + spacetimePoints: [], + }, + ]) + .mockImplementationOnce(() => [ + { + type: PathType.GENERIC, + distance: 350108, + duration: 14428, + fwdAzimuth: 273, + backAzimuth: 93, + distanceAzimuth: 336548, + points: [ + { + lon: 6.1765101, + lat: 48.689444, + }, + { + lon: 4.984577, + lat: 48.725686, + }, + { + lon: 2.3521, + lat: 48.8565, + }, + ], + spacetimePoints: [], + }, + ]) + .mockImplementationOnce(() => []), +}; + +const createDriverRouteProps: CreateRouteProps = { + roles: [Role.DRIVER], + waypoints: [ + { + position: 0, + ...originCoordinates, + }, + { + position: 1, + ...destinationCoordinates, + }, + ], + georouter: mockGeorouter, + georouterSettings: { + points: true, + detailedDistance: false, + detailedDuration: false, + }, +}; + +const createPassengerRouteProps: CreateRouteProps = { + roles: [Role.PASSENGER], + waypoints: [ + { + position: 0, + ...originCoordinates, + }, + { + position: 1, + ...destinationCoordinates, + }, + ], + georouter: mockGeorouter, + georouterSettings: { + points: true, + detailedDistance: false, + detailedDuration: false, + }, +}; + +const createSimpleDriverAndPassengerRouteProps: CreateRouteProps = { + roles: [Role.DRIVER, Role.PASSENGER], + waypoints: [ + { + position: 0, + ...originCoordinates, + }, + { + position: 1, + ...destinationCoordinates, + }, + ], + georouter: mockGeorouter, + georouterSettings: { + points: true, + detailedDistance: false, + detailedDuration: false, + }, +}; + +const createComplexDriverAndPassengerRouteProps: CreateRouteProps = { + roles: [Role.DRIVER, Role.PASSENGER], + waypoints: [ + { + position: 0, + ...originCoordinates, + }, + { + position: 1, + ...additionalCoordinates, + }, + { + position: 2, + ...destinationCoordinates, + }, + ], + georouter: mockGeorouter, + georouterSettings: { + points: true, + detailedDistance: false, + detailedDuration: false, + }, +}; + +describe('Route entity create', () => { + it('should create a new entity for a driver only', async () => { + const route: RouteEntity = await RouteEntity.create(createDriverRouteProps); + expect(route.id.length).toBe(36); + expect(route.getProps().driverDuration).toBe(14422); + expect(route.getProps().passengerDistance).toBeUndefined(); + }); + it('should create a new entity for a passenger only', async () => { + const route: RouteEntity = await RouteEntity.create( + createPassengerRouteProps, + ); + expect(route.id.length).toBe(36); + expect(route.getProps().passengerDuration).toBe(14423); + expect(route.getProps().driverDistance).toBeUndefined(); + }); + it('should create a new entity for a simple driver and passenger route', async () => { + const route: RouteEntity = await RouteEntity.create( + createSimpleDriverAndPassengerRouteProps, + ); + expect(route.id.length).toBe(36); + expect(route.getProps().driverDuration).toBe(14421); + expect(route.getProps().driverDistance).toBe(350100); + expect(route.getProps().passengerDuration).toBe(14421); + expect(route.getProps().passengerDistance).toBe(350100); + }); + it('should create a new entity for a complex driver and passenger route', async () => { + const route: RouteEntity = await RouteEntity.create( + createComplexDriverAndPassengerRouteProps, + ); + expect(route.id.length).toBe(36); + expect(route.getProps().driverDuration).toBe(14428); + expect(route.getProps().driverDistance).toBe(350108); + expect(route.getProps().passengerDuration).toBe(14428); + expect(route.getProps().passengerDistance).toBe(350108); + }); + it('should throw an exception if route is not found', async () => { + try { + await RouteEntity.create(createDriverRouteProps); + } catch (e: any) { + expect(e).toBeInstanceOf(RouteNotFoundException); + } + }); +}); From 65dd8d64b1e3349f58d10eb34fe533c6d2715d46 Mon Sep 17 00:00:00 2001 From: sbriat Date: Mon, 21 Aug 2023 17:14:22 +0200 Subject: [PATCH 08/24] route tests --- .../geography/core/domain/route.types.ts | 9 --- .../value-objects/waypoint.value-object.ts | 6 -- .../unit/core/waypoint.value-object.spec.ts | 69 +++++++++++++++++++ 3 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts diff --git a/src/modules/geography/core/domain/route.types.ts b/src/modules/geography/core/domain/route.types.ts index 1df57c9..74d1c6c 100644 --- a/src/modules/geography/core/domain/route.types.ts +++ b/src/modules/geography/core/domain/route.types.ts @@ -43,7 +43,6 @@ export type Path = { export type Point = { lon: number; lat: number; - context?: PointContext; }; export type SpacetimePoint = Point & { @@ -56,14 +55,6 @@ export enum Role { PASSENGER = 'PASSENGER', } -export enum PointContext { - HOUSE_NUMBER = 'HOUSE_NUMBER', - STREET_ADDRESS = 'STREET_ADDRESS', - LOCALITY = 'LOCALITY', - VENUE = 'VENUE', - OTHER = 'OTHER', -} - export enum PathType { GENERIC = 'generic', DRIVER = 'driver', diff --git a/src/modules/geography/core/domain/value-objects/waypoint.value-object.ts b/src/modules/geography/core/domain/value-objects/waypoint.value-object.ts index 9f6b493..353f51d 100644 --- a/src/modules/geography/core/domain/value-objects/waypoint.value-object.ts +++ b/src/modules/geography/core/domain/value-objects/waypoint.value-object.ts @@ -3,7 +3,6 @@ import { ArgumentOutOfRangeException, ValueObject, } from '@mobicoop/ddd-library'; -import { PointContext } from '../route.types'; /** Note: * Value Objects with multiple properties can contain @@ -14,7 +13,6 @@ export interface WaypointProps { position: number; lon: number; lat: number; - context?: PointContext; } export class Waypoint extends ValueObject { @@ -30,10 +28,6 @@ export class Waypoint extends ValueObject { return this.props.lat; } - get context(): PointContext { - return this.props.context; - } - protected validate(props: WaypointProps): void { if (props.position < 0) throw new ArgumentInvalidException( diff --git a/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts b/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts new file mode 100644 index 0000000..e69c1d2 --- /dev/null +++ b/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts @@ -0,0 +1,69 @@ +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, +} from '@mobicoop/ddd-library'; +import { Waypoint } from '@modules/geography/core/domain/value-objects/waypoint.value-object'; + +describe('Waypoint value object', () => { + it('should create a waypoint value object', () => { + const waypointVO = new Waypoint({ + position: 0, + lon: 48.689445, + lat: 6.17651, + }); + expect(waypointVO.position).toBe(0); + expect(waypointVO.lon).toBe(48.689445); + expect(waypointVO.lat).toBe(6.17651); + }); + it('should throw an exception if position is invalid', () => { + try { + new Waypoint({ + position: -1, + lon: 48.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentInvalidException); + } + }); + it('should throw an exception if longitude is invalid', () => { + try { + new Waypoint({ + position: 0, + lon: 348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Waypoint({ + position: 0, + lon: -348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); + it('should throw an exception if longitude is invalid', () => { + try { + new Waypoint({ + position: 0, + lon: 48.689445, + lat: 96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Waypoint({ + position: 0, + lon: 48.689445, + lat: -96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); +}); From 571699a66cee6874104b5646fbe588d7eeb8826c Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 08:54:35 +0200 Subject: [PATCH 09/24] spacetime VO tests --- .../geography/core/domain/route.types.ts | 2 +- ...ect.ts => spacetime-point.value-object.ts} | 10 ++- .../core/spacetime-point.value-object.spec.ts | 88 +++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) rename src/modules/geography/core/domain/value-objects/{timepoint.value-object.ts => spacetime-point.value-object.ts} (70%) create mode 100644 src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts diff --git a/src/modules/geography/core/domain/route.types.ts b/src/modules/geography/core/domain/route.types.ts index 74d1c6c..172d207 100644 --- a/src/modules/geography/core/domain/route.types.ts +++ b/src/modules/geography/core/domain/route.types.ts @@ -1,6 +1,6 @@ import { GeorouterPort } from '../application/ports/georouter.port'; import { GeorouterSettings } from '../application/types/georouter-settings.type'; -import { SpacetimePointProps } from './value-objects/timepoint.value-object'; +import { SpacetimePointProps } from './value-objects/spacetime-point.value-object'; import { WaypointProps } from './value-objects/waypoint.value-object'; // All properties that a Route has diff --git a/src/modules/geography/core/domain/value-objects/timepoint.value-object.ts b/src/modules/geography/core/domain/value-objects/spacetime-point.value-object.ts similarity index 70% rename from src/modules/geography/core/domain/value-objects/timepoint.value-object.ts rename to src/modules/geography/core/domain/value-objects/spacetime-point.value-object.ts index b6c7971..c7bfbce 100644 --- a/src/modules/geography/core/domain/value-objects/timepoint.value-object.ts +++ b/src/modules/geography/core/domain/value-objects/spacetime-point.value-object.ts @@ -1,4 +1,8 @@ -import { ArgumentInvalidException, ValueObject } from '@mobicoop/ddd-library'; +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, + ValueObject, +} from '@mobicoop/ddd-library'; /** Note: * Value Objects with multiple properties can contain @@ -38,5 +42,9 @@ export class SpacetimePoint extends ValueObject { throw new ArgumentInvalidException( 'distance must be greater than or equal to 0', ); + if (props.lon > 180 || props.lon < -180) + throw new ArgumentOutOfRangeException('lon must be between -180 and 180'); + if (props.lat > 90 || props.lat < -90) + throw new ArgumentOutOfRangeException('lat must be between -90 and 90'); } } diff --git a/src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts b/src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts new file mode 100644 index 0000000..bf18bd5 --- /dev/null +++ b/src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts @@ -0,0 +1,88 @@ +import { + ArgumentInvalidException, + ArgumentOutOfRangeException, +} from '@mobicoop/ddd-library'; +import { SpacetimePoint } from '@modules/geography/core/domain/value-objects/spacetime-point.value-object'; + +describe('Timepoint value object', () => { + it('should create a timepoint value object', () => { + const timepointVO = new SpacetimePoint({ + lon: 48.689445, + lat: 6.17651, + duration: 150, + distance: 12000, + }); + expect(timepointVO.duration).toBe(150); + expect(timepointVO.distance).toBe(12000); + expect(timepointVO.lon).toBe(48.689445); + expect(timepointVO.lat).toBe(6.17651); + }); + it('should throw an exception if longitude is invalid', () => { + try { + new SpacetimePoint({ + lon: 348.689445, + lat: 6.17651, + duration: 150, + distance: 12000, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new SpacetimePoint({ + lon: -348.689445, + lat: 6.17651, + duration: 150, + distance: 12000, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); + it('should throw an exception if latitude is invalid', () => { + try { + new SpacetimePoint({ + lon: 48.689445, + lat: 96.17651, + duration: 150, + distance: 12000, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new SpacetimePoint({ + lon: 48.689445, + lat: -96.17651, + duration: 150, + distance: 12000, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); + it('should throw an exception if distance is invalid', () => { + try { + new SpacetimePoint({ + lon: 48.689445, + lat: 6.17651, + duration: 150, + distance: -12000, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentInvalidException); + } + }); + it('should throw an exception if duration is invalid', () => { + try { + new SpacetimePoint({ + lon: 48.689445, + lat: 6.17651, + duration: -150, + distance: 12000, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentInvalidException); + } + }); +}); From 685b63e2cc98a7f5349a3c464f0751ddf0f01968 Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 10:55:27 +0200 Subject: [PATCH 10/24] get query tests --- .../unit/core/get-route.query-handler.spec.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts diff --git a/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts b/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts new file mode 100644 index 0000000..d9c142e --- /dev/null +++ b/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts @@ -0,0 +1,65 @@ +import { GeorouterPort } from '@modules/geography/core/application/ports/georouter.port'; +import { GetRouteQuery } from '@modules/geography/core/application/queries/get-route/get-route.query'; +import { GetRouteQueryHandler } from '@modules/geography/core/application/queries/get-route/get-route.query-handler'; +import { Waypoint } from '@modules/geography/core/application/types/waypoint.type'; +import { RouteEntity } from '@modules/geography/core/domain/route.entity'; +import { Role } from '@modules/geography/core/domain/route.types'; +import { GEOROUTER } from '@modules/geography/geography.di-tokens'; +import { Test, TestingModule } from '@nestjs/testing'; + +const originWaypoint: Waypoint = { + position: 0, + lon: 48.689445, + lat: 6.17651, +}; +const destinationWaypoint: Waypoint = { + position: 1, + lon: 48.8566, + lat: 2.3522, +}; + +const mockGeorouter: GeorouterPort = { + routes: jest.fn(), +}; + +describe('Get route query handler', () => { + let getRoutequeryHandler: GetRouteQueryHandler; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: GEOROUTER, + useValue: mockGeorouter, + }, + GetRouteQueryHandler, + ], + }).compile(); + + getRoutequeryHandler = + module.get(GetRouteQueryHandler); + }); + + it('should be defined', () => { + expect(getRoutequeryHandler).toBeDefined(); + }); + + describe('execution', () => { + it('should get a route for a driver only', async () => { + const getRoutequery = new GetRouteQuery( + [Role.DRIVER], + [originWaypoint, destinationWaypoint], + { + detailedDistance: false, + detailedDuration: false, + points: true, + }, + ); + RouteEntity.create = jest.fn().mockReturnValue({ + id: '047a6ecf-23d4-4d3e-877c-3225d560a8da', + }); + const result = await getRoutequeryHandler.execute(getRoutequery); + expect(result.id).toBe('047a6ecf-23d4-4d3e-877c-3225d560a8da'); + }); + }); +}); From b7bfdf6757aa7731e24d75a7d67cde5c65931a00 Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 11:17:21 +0200 Subject: [PATCH 11/24] routeMapper tests --- .../{geography.mapper.ts => route.mapper.ts} | 0 .../geography/tests/unit/route.mapper.spec.ts | 58 +++++++++++++++++++ 2 files changed, 58 insertions(+) rename src/modules/geography/{geography.mapper.ts => route.mapper.ts} (100%) create mode 100644 src/modules/geography/tests/unit/route.mapper.spec.ts diff --git a/src/modules/geography/geography.mapper.ts b/src/modules/geography/route.mapper.ts similarity index 100% rename from src/modules/geography/geography.mapper.ts rename to src/modules/geography/route.mapper.ts diff --git a/src/modules/geography/tests/unit/route.mapper.spec.ts b/src/modules/geography/tests/unit/route.mapper.spec.ts new file mode 100644 index 0000000..8c27c2d --- /dev/null +++ b/src/modules/geography/tests/unit/route.mapper.spec.ts @@ -0,0 +1,58 @@ +import { RouteEntity } from '@modules/geography/core/domain/route.entity'; +import { RouteMapper } from '@modules/geography/route.mapper'; +import { Test } from '@nestjs/testing'; + +describe('Route Mapper', () => { + let routeMapper: RouteMapper; + + beforeAll(async () => { + const module = await Test.createTestingModule({ + providers: [RouteMapper], + }).compile(); + routeMapper = module.get(RouteMapper); + }); + + it('should be defined', () => { + expect(routeMapper).toBeDefined(); + }); + + it('should map domain entity to persistence data', async () => { + expect(routeMapper.toPersistence()).toBeUndefined(); + }); + + it('should map persisted data to domain entity', async () => { + expect(routeMapper.toDomain()).toBeUndefined(); + }); + + it('should map domain entity to response', async () => { + const now = new Date(); + const routeEntity: RouteEntity = new RouteEntity({ + id: '047a6ecf-23d4-4d3e-877c-3225d560a8da', + createdAt: now, + updatedAt: now, + props: { + driverDistance: 23000, + driverDuration: 900, + passengerDistance: 23000, + passengerDuration: 900, + fwdAzimuth: 283, + backAzimuth: 93, + distanceAzimuth: 19840, + spacetimePoints: [], + waypoints: [ + { + position: 0, + lon: 6.1765103, + lat: 48.689446, + }, + { + position: 1, + lon: 2.3523, + lat: 48.8567, + }, + ], + }, + }); + expect(routeMapper.toResponse(routeEntity).driverDistance).toBe(23000); + }); +}); From c45e5c94e5026d05d8210be6ac43efbaca32ddae Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 11:30:40 +0200 Subject: [PATCH 12/24] default params provider tests --- .../default-param.provider.spec.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/modules/geography/tests/unit/infrastructure/default-param.provider.spec.ts diff --git a/src/modules/geography/tests/unit/infrastructure/default-param.provider.spec.ts b/src/modules/geography/tests/unit/infrastructure/default-param.provider.spec.ts new file mode 100644 index 0000000..72be537 --- /dev/null +++ b/src/modules/geography/tests/unit/infrastructure/default-param.provider.spec.ts @@ -0,0 +1,48 @@ +import { DefaultParams } from '@modules/geography/core/application/types/default-params.type'; +import { DefaultParamsProvider } from '@modules/geography/infrastructure/default-params-provider'; +import { ConfigService } from '@nestjs/config'; +import { Test, TestingModule } from '@nestjs/testing'; + +const mockConfigService = { + get: jest.fn().mockImplementation((value: string) => { + switch (value) { + case 'GEOROUTER_TYPE': + return 'graphhopper'; + case 'GEOROUTER_URL': + return 'http://localhost:8989'; + default: + return 'some_default_value'; + } + }), +}; + +describe('DefaultParamsProvider', () => { + let defaultParamsProvider: DefaultParamsProvider; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [], + providers: [ + DefaultParamsProvider, + { + provide: ConfigService, + useValue: mockConfigService, + }, + ], + }).compile(); + + defaultParamsProvider = module.get( + DefaultParamsProvider, + ); + }); + + it('should be defined', () => { + expect(defaultParamsProvider).toBeDefined(); + }); + + it('should provide default params', async () => { + const params: DefaultParams = defaultParamsProvider.getParams(); + expect(params.GEOROUTER_TYPE).toBe('graphhopper'); + expect(params.GEOROUTER_URL).toBe('http://localhost:8989'); + }); +}); From 14d2486c1b03d47c2680ca2d368ea649191cfdc8 Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 11:38:14 +0200 Subject: [PATCH 13/24] postgres direction encoder tests --- .../postgres-direction-encoder.spec.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts diff --git a/src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts b/src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts new file mode 100644 index 0000000..6f12ed5 --- /dev/null +++ b/src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts @@ -0,0 +1,41 @@ +import { Coordinates } from '@modules/geography/core/application/types/coordinates.type'; +import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder'; + +describe('Postgres direction encoder', () => { + it('should be defined', () => { + const postgresDirectionEncoder: PostgresDirectionEncoder = + new PostgresDirectionEncoder(); + expect(postgresDirectionEncoder).toBeDefined(); + }); + it('should encode coordinates to a postgres direction', () => { + const postgresDirectionEncoder: PostgresDirectionEncoder = + new PostgresDirectionEncoder(); + const coordinates: Coordinates[] = [ + { + lon: 6, + lat: 47, + }, + { + lon: 6.1, + lat: 47.1, + }, + { + lon: 6.2, + lat: 47.2, + }, + ]; + const direction = postgresDirectionEncoder.encode(coordinates); + expect(direction).toBe("'LINESTRING(6 47,6.1 47.1,6.2 47.2)'"); + }); + it('should decode a postgres direction to coordinates', () => { + const postgresDirectionEncoder: PostgresDirectionEncoder = + new PostgresDirectionEncoder(); + const direction = "'LINESTRING(6 47,6.1 47.1,6.2 47.2)'"; + const coordinates: Coordinates[] = + postgresDirectionEncoder.decode(direction); + expect(coordinates.length).toBe(3); + expect(coordinates[0].lat).toBe(47); + expect(coordinates[1].lon).toBe(6.1); + expect(coordinates[2].lat).toBe(47.2); + }); +}); From 52a1a815e6478e9c22c996cc79e8b032b2587dec Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 11:58:31 +0200 Subject: [PATCH 14/24] get route controller tests --- .../controllers/get-route.controller.ts | 14 ++-- .../interface/get-route.controller.spec.ts | 70 +++++++++++++++++++ 2 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 src/modules/geography/tests/unit/interface/get-route.controller.spec.ts diff --git a/src/modules/geography/interface/controllers/get-route.controller.ts b/src/modules/geography/interface/controllers/get-route.controller.ts index 8fdd2f9..0f16766 100644 --- a/src/modules/geography/interface/controllers/get-route.controller.ts +++ b/src/modules/geography/interface/controllers/get-route.controller.ts @@ -3,7 +3,7 @@ import { RouteResponseDto } from '../dtos/route.response.dto'; import { GetRouteRequestDto } from './dtos/get-route.request.dto'; import { RouteEntity } from '@modules/geography/core/domain/route.entity'; import { GetRouteQuery } from '@modules/geography/core/application/queries/get-route/get-route.query'; -import { RouteMapper } from '@modules/geography/geography.mapper'; +import { RouteMapper } from '@modules/geography/route.mapper'; import { Injectable } from '@nestjs/common'; @Injectable() @@ -14,13 +14,9 @@ export class GetRouteController { ) {} async get(data: GetRouteRequestDto): Promise { - try { - const route: RouteEntity = await this.queryBus.execute( - new GetRouteQuery(data.roles, data.waypoints, data.georouterSettings), - ); - return this.mapper.toResponse(route); - } catch (e) { - throw e; - } + const route: RouteEntity = await this.queryBus.execute( + new GetRouteQuery(data.roles, data.waypoints, data.georouterSettings), + ); + return this.mapper.toResponse(route); } } diff --git a/src/modules/geography/tests/unit/interface/get-route.controller.spec.ts b/src/modules/geography/tests/unit/interface/get-route.controller.spec.ts new file mode 100644 index 0000000..6b0ed30 --- /dev/null +++ b/src/modules/geography/tests/unit/interface/get-route.controller.spec.ts @@ -0,0 +1,70 @@ +import { Role } from '@modules/geography/core/domain/route.types'; +import { GetRouteController } from '@modules/geography/interface/controllers/get-route.controller'; +import { RouteMapper } from '@modules/geography/route.mapper'; +import { QueryBus } from '@nestjs/cqrs'; +import { Test, TestingModule } from '@nestjs/testing'; + +const mockQueryBus = { + execute: jest.fn(), +}; + +const mockRouteMapper = { + toPersistence: jest.fn(), + toDomain: jest.fn(), + toResponse: jest.fn(), +}; + +describe('Get Route Controller', () => { + let getRouteController: GetRouteController; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: QueryBus, + useValue: mockQueryBus, + }, + { + provide: RouteMapper, + useValue: mockRouteMapper, + }, + GetRouteController, + ], + }).compile(); + + getRouteController = module.get(GetRouteController); + }); + + afterEach(async () => { + jest.clearAllMocks(); + }); + + it('should be defined', () => { + expect(getRouteController).toBeDefined(); + }); + + it('should get a route', async () => { + jest.spyOn(mockQueryBus, 'execute'); + await getRouteController.get({ + roles: [Role.DRIVER], + waypoints: [ + { + position: 0, + lon: 48.689445, + lat: 6.17651, + }, + { + position: 1, + lon: 48.8566, + lat: 2.3522, + }, + ], + georouterSettings: { + points: true, + detailedDistance: false, + detailedDuration: false, + }, + }); + expect(mockQueryBus.execute).toHaveBeenCalledTimes(1); + }); +}); From 4762c844e1bb02d8814272cededa5e73ee0a28b8 Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 13:28:37 +0200 Subject: [PATCH 15/24] simplify ad georouter signature --- src/modules/ad/ad.mapper.ts | 6 +----- .../ad/core/application/ports/route-provider.port.ts | 10 ++++------ .../core/application/types/georouter-settings.type.ts | 5 ----- src/modules/ad/tests/unit/ad.mapper.spec.ts | 2 +- .../ad/tests/unit/infrastructure/ad.repository.spec.ts | 2 +- 5 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 src/modules/ad/core/application/types/georouter-settings.type.ts diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index 18690b9..c9df8b1 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -38,11 +38,7 @@ export class AdMapper const roles: Role[] = []; if (copy.driver) roles.push(Role.DRIVER); if (copy.passenger) roles.push(Role.PASSENGER); - const route: Route = this.routeProvider.get(roles, copy.waypoints, { - points: true, - detailedDistance: false, - detailedDuration: false, - }); + const route: Route = this.routeProvider.getBasic(roles, copy.waypoints); const record: AdWriteModel = { uuid: copy.id, driver: copy.driver, diff --git a/src/modules/ad/core/application/ports/route-provider.port.ts b/src/modules/ad/core/application/ports/route-provider.port.ts index 7ac93be..f8fd19e 100644 --- a/src/modules/ad/core/application/ports/route-provider.port.ts +++ b/src/modules/ad/core/application/ports/route-provider.port.ts @@ -1,12 +1,10 @@ -import { GeorouterSettings } from '../types/georouter-settings.type'; import { Role } from '../../domain/ad.types'; import { Waypoint } from '../types/waypoint.type'; import { Route } from '../types/route.type'; export interface RouteProviderPort { - get( - roles: Role[], - waypoints: Waypoint[], - georouterSettings: GeorouterSettings, - ): Route; + /** + * Get a basic route with points and overall duration / distance + */ + getBasic(roles: Role[], waypoints: Waypoint[]): Route; } diff --git a/src/modules/ad/core/application/types/georouter-settings.type.ts b/src/modules/ad/core/application/types/georouter-settings.type.ts deleted file mode 100644 index ae5b391..0000000 --- a/src/modules/ad/core/application/types/georouter-settings.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type GeorouterSettings = { - points: boolean; - detailedDuration: boolean; - detailedDistance: boolean; -}; diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index 646e7aa..14ae563 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -105,7 +105,7 @@ const mockDirectionEncoder: DirectionEncoderPort = { }; const mockRouteProvider: RouteProviderPort = { - get: jest.fn().mockImplementation(() => ({ + getBasic: jest.fn().mockImplementation(() => ({ driverDistance: 350101, driverDuration: 14422, passengerDistance: 350101, diff --git a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts index 2dfe7e4..789b547 100644 --- a/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts +++ b/src/modules/ad/tests/unit/infrastructure/ad.repository.spec.ts @@ -20,7 +20,7 @@ const mockDirectionEncoder: DirectionEncoderPort = { }; const mockRouteProvider: RouteProviderPort = { - get: jest.fn(), + getBasic: jest.fn(), }; describe('Ad repository', () => { From ac8e459e90b8aed4e65b357eb9ae2e9a7b89f594 Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 16:14:36 +0200 Subject: [PATCH 16/24] move route compute to create service as entity creation is not async --- src/modules/ad/ad.di-tokens.ts | 3 + src/modules/ad/ad.mapper.ts | 27 +++----- .../commands/create-ad/create-ad.service.ts | 21 +++++- .../application/ports/route-provider.port.ts | 2 +- src/modules/ad/core/domain/ad.types.ts | 13 +++- .../value-objects/point.value-object.ts | 31 +++++++++ .../ad/infrastructure/route-provider.ts | 21 ++++++ src/modules/ad/tests/unit/ad.mapper.spec.ts | 56 ++++++--------- .../ad/tests/unit/core/ad.entity.spec.ts | 9 ++- .../tests/unit/core/create-ad.service.spec.ts | 40 ++++++++++- .../unit/core/point.value-object.spec.ts | 49 +++++++++++++ .../unit/core/waypoint.value-object.spec.ts | 2 +- .../infrastructure/route-provider.spec.ts | 69 +++++++++++++++++++ .../ports/get-basic-route-controller.port.ts | 6 ++ .../core/application/types/route.type.ts | 3 +- .../geography/core/domain/route.entity.ts | 4 +- .../geography/core/domain/route.types.ts | 6 +- .../value-objects/coordinates.value-object.ts | 31 +++++++++ src/modules/geography/geography.module.ts | 6 +- .../controllers/dtos/get-route.request.dto.ts | 6 +- ...oller.ts => get-basic-route.controller.ts} | 13 ++-- .../interface/dtos/route.response.dto.ts | 3 +- src/modules/geography/route.mapper.ts | 2 +- .../core/coordinates.value-object.spec.ts | 49 +++++++++++++ .../unit/core/waypoint.value-object.spec.ts | 2 +- ....ts => get-basic-route.controller.spec.ts} | 21 +++--- .../geography/tests/unit/route.mapper.spec.ts | 2 +- 27 files changed, 403 insertions(+), 94 deletions(-) create mode 100644 src/modules/ad/core/domain/value-objects/point.value-object.ts create mode 100644 src/modules/ad/infrastructure/route-provider.ts create mode 100644 src/modules/ad/tests/unit/core/point.value-object.spec.ts create mode 100644 src/modules/ad/tests/unit/infrastructure/route-provider.spec.ts create mode 100644 src/modules/geography/core/application/ports/get-basic-route-controller.port.ts create mode 100644 src/modules/geography/core/domain/value-objects/coordinates.value-object.ts rename src/modules/geography/interface/controllers/{get-route.controller.ts => get-basic-route.controller.ts} (63%) create mode 100644 src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts rename src/modules/geography/tests/unit/interface/{get-route.controller.spec.ts => get-basic-route.controller.spec.ts} (70%) diff --git a/src/modules/ad/ad.di-tokens.ts b/src/modules/ad/ad.di-tokens.ts index 3e2571d..8690c8d 100644 --- a/src/modules/ad/ad.di-tokens.ts +++ b/src/modules/ad/ad.di-tokens.ts @@ -1,4 +1,7 @@ export const AD_REPOSITORY = Symbol('AD_REPOSITORY'); export const AD_DIRECTION_ENCODER = Symbol('AD_DIRECTION_ENCODER'); export const AD_MESSAGE_PUBLISHER = Symbol('AD_MESSAGE_PUBLISHER'); +export const AD_GET_BASIC_ROUTE_CONTROLLER = Symbol( + 'AD_GET_BASIC_ROUTE_CONTROLLER', +); export const AD_ROUTE_PROVIDER = Symbol('AD_ROUTE_PROVIDER'); diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index c9df8b1..bb5d25c 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -6,13 +6,11 @@ import { AdReadModel, ScheduleItemModel, } from './infrastructure/ad.repository'; -import { Frequency, Role } from './core/domain/ad.types'; +import { Frequency } from './core/domain/ad.types'; import { v4 } from 'uuid'; import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object'; import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; -import { AD_DIRECTION_ENCODER, AD_ROUTE_PROVIDER } from './ad.di-tokens'; -import { RouteProviderPort } from './core/application/ports/route-provider.port'; -import { Route } from './core/application/types/route.type'; +import { AD_DIRECTION_ENCODER } from './ad.di-tokens'; /** * Mapper constructs objects that are used in different layers: @@ -28,17 +26,11 @@ export class AdMapper constructor( @Inject(AD_DIRECTION_ENCODER) private readonly directionEncoder: DirectionEncoderPort, - @Inject(AD_ROUTE_PROVIDER) - private readonly routeProvider: RouteProviderPort, ) {} toPersistence = (entity: AdEntity): AdWriteModel => { const copy = entity.getProps(); const now = new Date(); - const roles: Role[] = []; - if (copy.driver) roles.push(Role.DRIVER); - if (copy.passenger) roles.push(Role.PASSENGER); - const route: Route = this.routeProvider.getBasic(roles, copy.waypoints); const record: AdWriteModel = { uuid: copy.id, driver: copy.driver, @@ -65,14 +57,14 @@ export class AdMapper seatsProposed: copy.seatsProposed, seatsRequested: copy.seatsRequested, strict: copy.strict, - driverDuration: route.driverDuration, - driverDistance: route.driverDistance, - passengerDuration: route.passengerDuration, - passengerDistance: route.passengerDistance, + driverDuration: copy.driverDuration, + driverDistance: copy.driverDistance, + passengerDuration: copy.passengerDuration, + passengerDistance: copy.passengerDistance, waypoints: this.directionEncoder.encode(copy.waypoints), - direction: this.directionEncoder.encode(route.points), - fwdAzimuth: route.fwdAzimuth, - backAzimuth: route.backAzimuth, + direction: this.directionEncoder.encode(copy.points), + fwdAzimuth: copy.fwdAzimuth, + backAzimuth: copy.backAzimuth, createdAt: copy.createdAt, updatedAt: copy.updatedAt, }; @@ -116,6 +108,7 @@ export class AdMapper })), fwdAzimuth: record.fwdAzimuth, backAzimuth: record.backAzimuth, + points: [], }, }); return entity; diff --git a/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts b/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts index 776e43d..47d367f 100644 --- a/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts +++ b/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts @@ -1,20 +1,32 @@ import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; import { CreateAdCommand } from './create-ad.command'; import { Inject } from '@nestjs/common'; -import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens'; +import { AD_REPOSITORY, AD_ROUTE_PROVIDER } from '@modules/ad/ad.di-tokens'; import { AdEntity } from '@modules/ad/core/domain/ad.entity'; import { AdRepositoryPort } from '../../ports/ad.repository.port'; import { AggregateID, ConflictException } from '@mobicoop/ddd-library'; import { AdAlreadyExistsException } from '@modules/ad/core/domain/ad.errors'; +import { RouteProviderPort } from '../../ports/route-provider.port'; +import { Role } from '@modules/ad/core/domain/ad.types'; +import { Route } from '../../types/route.type'; @CommandHandler(CreateAdCommand) export class CreateAdService implements ICommandHandler { constructor( @Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort, + @Inject(AD_ROUTE_PROVIDER) + private readonly routeProvider: RouteProviderPort, ) {} async execute(command: CreateAdCommand): Promise { + const roles: Role[] = []; + if (command.driver) roles.push(Role.DRIVER); + if (command.passenger) roles.push(Role.PASSENGER); + const route: Route = await this.routeProvider.getBasic( + roles, + command.waypoints, + ); const ad = AdEntity.create({ id: command.id, driver: command.driver, @@ -27,6 +39,13 @@ export class CreateAdService implements ICommandHandler { seatsRequested: command.seatsRequested, strict: command.strict, waypoints: command.waypoints, + points: route.points, + driverDistance: route.driverDistance, + driverDuration: route.driverDuration, + passengerDistance: route.passengerDistance, + passengerDuration: route.passengerDuration, + fwdAzimuth: route.fwdAzimuth, + backAzimuth: route.backAzimuth, }); try { diff --git a/src/modules/ad/core/application/ports/route-provider.port.ts b/src/modules/ad/core/application/ports/route-provider.port.ts index f8fd19e..4ce43b0 100644 --- a/src/modules/ad/core/application/ports/route-provider.port.ts +++ b/src/modules/ad/core/application/ports/route-provider.port.ts @@ -6,5 +6,5 @@ export interface RouteProviderPort { /** * Get a basic route with points and overall duration / distance */ - getBasic(roles: Role[], waypoints: Waypoint[]): Route; + getBasic(roles: Role[], waypoints: Waypoint[]): Promise; } diff --git a/src/modules/ad/core/domain/ad.types.ts b/src/modules/ad/core/domain/ad.types.ts index ad2c7ef..ba60073 100644 --- a/src/modules/ad/core/domain/ad.types.ts +++ b/src/modules/ad/core/domain/ad.types.ts @@ -1,3 +1,4 @@ +import { PointProps } from './value-objects/point.value-object'; import { ScheduleItemProps } from './value-objects/schedule-item.value-object'; import { WaypointProps } from './value-objects/waypoint.value-object'; @@ -17,8 +18,9 @@ export interface AdProps { passengerDuration?: number; passengerDistance?: number; waypoints: WaypointProps[]; - fwdAzimuth?: number; - backAzimuth?: number; + points: PointProps[]; + fwdAzimuth: number; + backAzimuth: number; } // Properties that are needed for an Ad creation @@ -34,6 +36,13 @@ export interface CreateAdProps { seatsRequested: number; strict: boolean; waypoints: WaypointProps[]; + driverDuration?: number; + driverDistance?: number; + passengerDuration?: number; + passengerDistance?: number; + fwdAzimuth: number; + backAzimuth: number; + points: PointProps[]; } export enum Frequency { diff --git a/src/modules/ad/core/domain/value-objects/point.value-object.ts b/src/modules/ad/core/domain/value-objects/point.value-object.ts new file mode 100644 index 0000000..2047ead --- /dev/null +++ b/src/modules/ad/core/domain/value-objects/point.value-object.ts @@ -0,0 +1,31 @@ +import { + ArgumentOutOfRangeException, + ValueObject, +} from '@mobicoop/ddd-library'; + +/** Note: + * Value Objects with multiple properties can contain + * other Value Objects inside if needed. + * */ + +export interface PointProps { + lon: number; + lat: number; +} + +export class Point extends ValueObject { + get lon(): number { + return this.props.lon; + } + + get lat(): number { + return this.props.lat; + } + + protected validate(props: PointProps): void { + if (props.lon > 180 || props.lon < -180) + throw new ArgumentOutOfRangeException('lon must be between -180 and 180'); + if (props.lat > 90 || props.lat < -90) + throw new ArgumentOutOfRangeException('lat must be between -90 and 90'); + } +} diff --git a/src/modules/ad/infrastructure/route-provider.ts b/src/modules/ad/infrastructure/route-provider.ts new file mode 100644 index 0000000..cd57ec2 --- /dev/null +++ b/src/modules/ad/infrastructure/route-provider.ts @@ -0,0 +1,21 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { RouteProviderPort } from '../core/application/ports/route-provider.port'; +import { Route } from '../core/application/types/route.type'; +import { Waypoint } from '../core/application/types/waypoint.type'; +import { Role } from '../core/domain/ad.types'; +import { GetBasicRouteControllerPort } from '@modules/geography/core/application/ports/get-basic-route-controller.port'; +import { AD_GET_BASIC_ROUTE_CONTROLLER } from '../ad.di-tokens'; + +@Injectable() +export class RouteProvider implements RouteProviderPort { + constructor( + @Inject(AD_GET_BASIC_ROUTE_CONTROLLER) + private readonly getBasicRouteController: GetBasicRouteControllerPort, + ) {} + + getBasic = async (roles: Role[], waypoints: Waypoint[]): Promise => + await this.getBasicRouteController.get({ + roles, + waypoints, + }); +} diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index 14ae563..0099653 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -1,9 +1,5 @@ -import { - AD_DIRECTION_ENCODER, - AD_ROUTE_PROVIDER, -} from '@modules/ad/ad.di-tokens'; +import { AD_DIRECTION_ENCODER } from '@modules/ad/ad.di-tokens'; import { AdMapper } from '@modules/ad/ad.mapper'; -import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port'; import { AdEntity } from '@modules/ad/core/domain/ad.entity'; import { Frequency } from '@modules/ad/core/domain/ad.types'; import { @@ -44,6 +40,26 @@ const adEntity: AdEntity = new AdEntity({ strict: false, seatsProposed: 3, seatsRequested: 1, + driverDistance: 350101, + driverDuration: 14422, + passengerDistance: 350101, + passengerDuration: 14422, + fwdAzimuth: 273, + backAzimuth: 93, + points: [ + { + lon: 6.1765102, + lat: 48.689445, + }, + { + lon: 4.984578, + lat: 48.725687, + }, + { + lon: 2.3522, + lat: 48.8566, + }, + ], }, createdAt: now, updatedAt: now, @@ -104,32 +120,6 @@ const mockDirectionEncoder: DirectionEncoderPort = { ]), }; -const mockRouteProvider: RouteProviderPort = { - getBasic: jest.fn().mockImplementation(() => ({ - driverDistance: 350101, - driverDuration: 14422, - passengerDistance: 350101, - passengerDuration: 14422, - fwdAzimuth: 273, - backAzimuth: 93, - distanceAzimuth: 336544, - points: [ - { - lon: 6.1765102, - lat: 48.689445, - }, - { - lon: 4.984578, - lat: 48.725687, - }, - { - lon: 2.3522, - lat: 48.8566, - }, - ], - })), -}; - describe('Ad Mapper', () => { let adMapper: AdMapper; @@ -141,10 +131,6 @@ describe('Ad Mapper', () => { provide: AD_DIRECTION_ENCODER, useValue: mockDirectionEncoder, }, - { - provide: AD_ROUTE_PROVIDER, - useValue: mockRouteProvider, - }, ], }).compile(); adMapper = module.get(AdMapper); diff --git a/src/modules/ad/tests/unit/core/ad.entity.spec.ts b/src/modules/ad/tests/unit/core/ad.entity.spec.ts index 899e3f0..90077ac 100644 --- a/src/modules/ad/tests/unit/core/ad.entity.spec.ts +++ b/src/modules/ad/tests/unit/core/ad.entity.spec.ts @@ -31,6 +31,13 @@ const createAdProps: CreateAdProps = { seatsRequested: 1, strict: false, waypoints: [originWaypointProps, destinationWaypointProps], + driverDistance: 23000, + driverDuration: 900, + passengerDistance: 23000, + passengerDuration: 900, + fwdAzimuth: 283, + backAzimuth: 93, + points: [], }; describe('Ad entity create', () => { @@ -42,6 +49,6 @@ describe('Ad entity create', () => { expect(ad.getProps().schedule[0].time).toBe('08:30'); expect(ad.getProps().driver).toBeTruthy(); expect(ad.getProps().passenger).toBeTruthy(); - expect(ad.getProps().driverDistance).toBeUndefined(); + expect(ad.getProps().driverDistance).toBe(23000); }); }); diff --git a/src/modules/ad/tests/unit/core/create-ad.service.spec.ts b/src/modules/ad/tests/unit/core/create-ad.service.spec.ts index 74f26e6..d78729c 100644 --- a/src/modules/ad/tests/unit/core/create-ad.service.spec.ts +++ b/src/modules/ad/tests/unit/core/create-ad.service.spec.ts @@ -1,5 +1,5 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { AD_REPOSITORY } from '@modules/ad/ad.di-tokens'; +import { AD_REPOSITORY, AD_ROUTE_PROVIDER } from '@modules/ad/ad.di-tokens'; import { AggregateID } from '@mobicoop/ddd-library'; import { AdEntity } from '@modules/ad/core/domain/ad.entity'; import { ConflictException } from '@mobicoop/ddd-library'; @@ -8,6 +8,7 @@ import { CreateAdService } from '@modules/ad/core/application/commands/create-ad import { CreateAdCommand } from '@modules/ad/core/application/commands/create-ad/create-ad.command'; import { AdAlreadyExistsException } from '@modules/ad/core/domain/ad.errors'; import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.value-object'; +import { RouteProviderPort } from '@modules/ad/core/application/ports/route-provider.port'; const originWaypoint: WaypointProps = { position: 0, @@ -37,6 +38,13 @@ const createAdProps: CreateAdProps = { strict: false, frequency: Frequency.PUNCTUAL, waypoints: [originWaypoint, destinationWaypoint], + driverDistance: 23000, + driverDuration: 900, + passengerDistance: 23000, + passengerDuration: 900, + fwdAzimuth: 283, + backAzimuth: 93, + points: [], }; const mockAdRepository = { @@ -51,6 +59,32 @@ const mockAdRepository = { }), }; +const mockRouteProvider: RouteProviderPort = { + getBasic: jest.fn().mockImplementation(() => ({ + driverDistance: 350101, + driverDuration: 14422, + passengerDistance: 350101, + passengerDuration: 14422, + fwdAzimuth: 273, + backAzimuth: 93, + distanceAzimuth: 336544, + points: [ + { + lon: 6.1765102, + lat: 48.689445, + }, + { + lon: 4.984578, + lat: 48.725687, + }, + { + lon: 2.3522, + lat: 48.8566, + }, + ], + })), +}; + describe('create-ad.service', () => { let createAdService: CreateAdService; @@ -61,6 +95,10 @@ describe('create-ad.service', () => { provide: AD_REPOSITORY, useValue: mockAdRepository, }, + { + provide: AD_ROUTE_PROVIDER, + useValue: mockRouteProvider, + }, CreateAdService, ], }).compile(); diff --git a/src/modules/ad/tests/unit/core/point.value-object.spec.ts b/src/modules/ad/tests/unit/core/point.value-object.spec.ts new file mode 100644 index 0000000..eb09cd8 --- /dev/null +++ b/src/modules/ad/tests/unit/core/point.value-object.spec.ts @@ -0,0 +1,49 @@ +import { ArgumentOutOfRangeException } from '@mobicoop/ddd-library'; +import { Point } from '@modules/ad/core/domain/value-objects/point.value-object'; + +describe('Point value object', () => { + it('should create a point value object', () => { + const pointVO = new Point({ + lon: 48.689445, + lat: 6.17651, + }); + expect(pointVO.lon).toBe(48.689445); + expect(pointVO.lat).toBe(6.17651); + }); + it('should throw an exception if longitude is invalid', () => { + try { + new Point({ + lon: 348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Point({ + lon: -348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); + it('should throw an exception if latitude is invalid', () => { + try { + new Point({ + lon: 48.689445, + lat: 96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Point({ + lon: 48.689445, + lat: -96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); +}); diff --git a/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts index a2f363f..4191313 100644 --- a/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts +++ b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts @@ -46,7 +46,7 @@ describe('Waypoint value object', () => { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); } }); - it('should throw an exception if longitude is invalid', () => { + it('should throw an exception if latitude is invalid', () => { try { new Waypoint({ position: 0, diff --git a/src/modules/ad/tests/unit/infrastructure/route-provider.spec.ts b/src/modules/ad/tests/unit/infrastructure/route-provider.spec.ts new file mode 100644 index 0000000..7a41ed8 --- /dev/null +++ b/src/modules/ad/tests/unit/infrastructure/route-provider.spec.ts @@ -0,0 +1,69 @@ +import { AD_GET_BASIC_ROUTE_CONTROLLER } from '@modules/ad/ad.di-tokens'; +import { Route } from '@modules/ad/core/application/types/route.type'; +import { Role } from '@modules/ad/core/domain/ad.types'; +import { RouteProvider } from '@modules/ad/infrastructure/route-provider'; +import { GetBasicRouteControllerPort } from '@modules/geography/core/application/ports/get-basic-route-controller.port'; +import { Test, TestingModule } from '@nestjs/testing'; + +const mockGetBasicRouteController: GetBasicRouteControllerPort = { + get: jest.fn().mockImplementation(() => ({ + driverDistance: 23000, + driverDuration: 900, + passengerDistance: 23000, + passengerDuration: 900, + fwdAzimuth: 283, + backAzimuth: 93, + distanceAzimuth: 19840, + points: [ + { + lon: 6.1765103, + lat: 48.689446, + }, + { + lon: 2.3523, + lat: 48.8567, + }, + ], + })), +}; + +describe('Route provider', () => { + let routeProvider: RouteProvider; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + RouteProvider, + { + provide: AD_GET_BASIC_ROUTE_CONTROLLER, + useValue: mockGetBasicRouteController, + }, + ], + }).compile(); + + routeProvider = module.get(RouteProvider); + }); + + it('should be defined', () => { + expect(routeProvider).toBeDefined(); + }); + + it('should provide a route', async () => { + const route: Route = await routeProvider.getBasic( + [Role.DRIVER], + [ + { + position: 0, + lat: 48.689445, + lon: 6.1765102, + }, + { + position: 1, + lat: 48.8566, + lon: 2.3522, + }, + ], + ); + expect(route.driverDistance).toBe(23000); + }); +}); diff --git a/src/modules/geography/core/application/ports/get-basic-route-controller.port.ts b/src/modules/geography/core/application/ports/get-basic-route-controller.port.ts new file mode 100644 index 0000000..a1f0bd4 --- /dev/null +++ b/src/modules/geography/core/application/ports/get-basic-route-controller.port.ts @@ -0,0 +1,6 @@ +import { GetRouteRequestDto } from '@modules/geography/interface/controllers/dtos/get-route.request.dto'; +import { RouteResponseDto } from '@modules/geography/interface/dtos/route.response.dto'; + +export interface GetBasicRouteControllerPort { + get(data: GetRouteRequestDto): Promise; +} diff --git a/src/modules/geography/core/application/types/route.type.ts b/src/modules/geography/core/application/types/route.type.ts index 3913deb..791a00e 100644 --- a/src/modules/geography/core/application/types/route.type.ts +++ b/src/modules/geography/core/application/types/route.type.ts @@ -9,6 +9,5 @@ export type Route = { fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; - points: Coordinates[]; - spacetimePoints: SpacetimePoint[]; + points: Coordinates[] | SpacetimePoint[]; }; diff --git a/src/modules/geography/core/domain/route.entity.ts b/src/modules/geography/core/domain/route.entity.ts index 705a4c2..dc81161 100644 --- a/src/modules/geography/core/domain/route.entity.ts +++ b/src/modules/geography/core/domain/route.entity.ts @@ -60,9 +60,7 @@ export class RouteEntity extends AggregateRoot { ? driverRoute.distanceAzimuth : passengerRoute.distanceAzimuth, waypoints: create.waypoints, - spacetimePoints: driverRoute - ? driverRoute.spacetimePoints - : passengerRoute.spacetimePoints, + points: driverRoute ? driverRoute.points : passengerRoute.points, }; return new RouteEntity({ id: v4(), diff --git a/src/modules/geography/core/domain/route.types.ts b/src/modules/geography/core/domain/route.types.ts index 172d207..7fe7776 100644 --- a/src/modules/geography/core/domain/route.types.ts +++ b/src/modules/geography/core/domain/route.types.ts @@ -1,5 +1,6 @@ import { GeorouterPort } from '../application/ports/georouter.port'; import { GeorouterSettings } from '../application/types/georouter-settings.type'; +import { CoordinatesProps } from './value-objects/coordinates.value-object'; import { SpacetimePointProps } from './value-objects/spacetime-point.value-object'; import { WaypointProps } from './value-objects/waypoint.value-object'; @@ -13,7 +14,7 @@ export interface RouteProps { backAzimuth: number; distanceAzimuth: number; waypoints: WaypointProps[]; - spacetimePoints: SpacetimePointProps[]; + points: SpacetimePointProps[] | CoordinatesProps[]; } // Properties that are needed for a Route creation @@ -31,8 +32,7 @@ export type Direction = { fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; - points: Point[]; - spacetimePoints: SpacetimePoint[]; + points: SpacetimePoint[] | Point[]; }; export type Path = { diff --git a/src/modules/geography/core/domain/value-objects/coordinates.value-object.ts b/src/modules/geography/core/domain/value-objects/coordinates.value-object.ts new file mode 100644 index 0000000..9bd81e7 --- /dev/null +++ b/src/modules/geography/core/domain/value-objects/coordinates.value-object.ts @@ -0,0 +1,31 @@ +import { + ArgumentOutOfRangeException, + ValueObject, +} from '@mobicoop/ddd-library'; + +/** Note: + * Value Objects with multiple properties can contain + * other Value Objects inside if needed. + * */ + +export interface CoordinatesProps { + lon: number; + lat: number; +} + +export class Coordinates extends ValueObject { + get lon(): number { + return this.props.lon; + } + + get lat(): number { + return this.props.lat; + } + + protected validate(props: CoordinatesProps): void { + if (props.lon > 180 || props.lon < -180) + throw new ArgumentOutOfRangeException('lon must be between -180 and 180'); + if (props.lat > 90 || props.lat < -90) + throw new ArgumentOutOfRangeException('lat must be between -90 and 90'); + } +} diff --git a/src/modules/geography/geography.module.ts b/src/modules/geography/geography.module.ts index d974d9b..192f6df 100644 --- a/src/modules/geography/geography.module.ts +++ b/src/modules/geography/geography.module.ts @@ -3,7 +3,7 @@ import { CqrsModule } from '@nestjs/cqrs'; import { DIRECTION_ENCODER, PARAMS_PROVIDER } from './geography.di-tokens'; import { DefaultParamsProvider } from './infrastructure/default-params-provider'; import { PostgresDirectionEncoder } from './infrastructure/postgres-direction-encoder'; -import { GetRouteController } from './interface/controllers/get-route.controller'; +import { GetBasicRouteController } from './interface/controllers/get-basic-route.controller'; const adapters: Provider[] = [ { @@ -14,12 +14,12 @@ const adapters: Provider[] = [ provide: DIRECTION_ENCODER, useClass: PostgresDirectionEncoder, }, - GetRouteController, + GetBasicRouteController, ]; @Module({ imports: [CqrsModule], providers: [...adapters], - exports: [DIRECTION_ENCODER, GetRouteController], + exports: [DIRECTION_ENCODER, GetBasicRouteController], }) export class GeographyModule {} diff --git a/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts b/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts index b57502e..c6948df 100644 --- a/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts +++ b/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts @@ -1,9 +1,7 @@ -import { GeorouterSettings } from '@modules/geography/core/application/types/georouter-settings.type'; import { Waypoint } from '@modules/geography/core/application/types/waypoint.type'; import { Role } from '@modules/geography/core/domain/route.types'; -export class GetRouteRequestDto { +export type GetRouteRequestDto = { roles: Role[]; waypoints: Waypoint[]; - georouterSettings: GeorouterSettings; -} +}; diff --git a/src/modules/geography/interface/controllers/get-route.controller.ts b/src/modules/geography/interface/controllers/get-basic-route.controller.ts similarity index 63% rename from src/modules/geography/interface/controllers/get-route.controller.ts rename to src/modules/geography/interface/controllers/get-basic-route.controller.ts index 0f16766..3bdc42e 100644 --- a/src/modules/geography/interface/controllers/get-route.controller.ts +++ b/src/modules/geography/interface/controllers/get-basic-route.controller.ts @@ -4,10 +4,11 @@ import { GetRouteRequestDto } from './dtos/get-route.request.dto'; import { RouteEntity } from '@modules/geography/core/domain/route.entity'; import { GetRouteQuery } from '@modules/geography/core/application/queries/get-route/get-route.query'; import { RouteMapper } from '@modules/geography/route.mapper'; -import { Injectable } from '@nestjs/common'; +import { Controller } from '@nestjs/common'; +import { GetBasicRouteControllerPort } from '@modules/geography/core/application/ports/get-basic-route-controller.port'; -@Injectable() -export class GetRouteController { +@Controller() +export class GetBasicRouteController implements GetBasicRouteControllerPort { constructor( private readonly queryBus: QueryBus, private readonly mapper: RouteMapper, @@ -15,7 +16,11 @@ export class GetRouteController { async get(data: GetRouteRequestDto): Promise { const route: RouteEntity = await this.queryBus.execute( - new GetRouteQuery(data.roles, data.waypoints, data.georouterSettings), + new GetRouteQuery(data.roles, data.waypoints, { + detailedDistance: false, + detailedDuration: false, + points: true, + }), ); return this.mapper.toResponse(route); } diff --git a/src/modules/geography/interface/dtos/route.response.dto.ts b/src/modules/geography/interface/dtos/route.response.dto.ts index 6829714..58d3c52 100644 --- a/src/modules/geography/interface/dtos/route.response.dto.ts +++ b/src/modules/geography/interface/dtos/route.response.dto.ts @@ -1,3 +1,4 @@ +import { Coordinates } from '@modules/geography/core/application/types/coordinates.type'; import { SpacetimePoint } from '@modules/geography/core/application/types/spacetime-point.type'; export class RouteResponseDto { @@ -8,5 +9,5 @@ export class RouteResponseDto { fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; - spacetimePoints: SpacetimePoint[]; + points: SpacetimePoint[] | Coordinates[]; } diff --git a/src/modules/geography/route.mapper.ts b/src/modules/geography/route.mapper.ts index 0c8aaca..98fc10c 100644 --- a/src/modules/geography/route.mapper.ts +++ b/src/modules/geography/route.mapper.ts @@ -33,7 +33,7 @@ export class RouteMapper response.fwdAzimuth = entity.getProps().fwdAzimuth; response.backAzimuth = entity.getProps().backAzimuth; response.distanceAzimuth = entity.getProps().distanceAzimuth; - response.spacetimePoints = entity.getProps().spacetimePoints; + response.points = entity.getProps().points; return response; }; } diff --git a/src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts b/src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts new file mode 100644 index 0000000..da2cf7e --- /dev/null +++ b/src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts @@ -0,0 +1,49 @@ +import { ArgumentOutOfRangeException } from '@mobicoop/ddd-library'; +import { Coordinates } from '@modules/geography/core/domain/value-objects/coordinates.value-object'; + +describe('Waypoint value object', () => { + it('should create a waypoint value object', () => { + const coordinatesVO = new Coordinates({ + lon: 48.689445, + lat: 6.17651, + }); + expect(coordinatesVO.lon).toBe(48.689445); + expect(coordinatesVO.lat).toBe(6.17651); + }); + it('should throw an exception if longitude is invalid', () => { + try { + new Coordinates({ + lon: 348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Coordinates({ + lon: -348.689445, + lat: 6.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); + it('should throw an exception if latitude is invalid', () => { + try { + new Coordinates({ + lon: 48.689445, + lat: 96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + try { + new Coordinates({ + lon: 48.689445, + lat: -96.17651, + }); + } catch (e: any) { + expect(e).toBeInstanceOf(ArgumentOutOfRangeException); + } + }); +}); diff --git a/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts b/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts index e69c1d2..8c44dd5 100644 --- a/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts +++ b/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts @@ -46,7 +46,7 @@ describe('Waypoint value object', () => { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); } }); - it('should throw an exception if longitude is invalid', () => { + it('should throw an exception if latitude is invalid', () => { try { new Waypoint({ position: 0, diff --git a/src/modules/geography/tests/unit/interface/get-route.controller.spec.ts b/src/modules/geography/tests/unit/interface/get-basic-route.controller.spec.ts similarity index 70% rename from src/modules/geography/tests/unit/interface/get-route.controller.spec.ts rename to src/modules/geography/tests/unit/interface/get-basic-route.controller.spec.ts index 6b0ed30..2aeaf75 100644 --- a/src/modules/geography/tests/unit/interface/get-route.controller.spec.ts +++ b/src/modules/geography/tests/unit/interface/get-basic-route.controller.spec.ts @@ -1,5 +1,5 @@ import { Role } from '@modules/geography/core/domain/route.types'; -import { GetRouteController } from '@modules/geography/interface/controllers/get-route.controller'; +import { GetBasicRouteController } from '@modules/geography/interface/controllers/get-basic-route.controller'; import { RouteMapper } from '@modules/geography/route.mapper'; import { QueryBus } from '@nestjs/cqrs'; import { Test, TestingModule } from '@nestjs/testing'; @@ -14,8 +14,8 @@ const mockRouteMapper = { toResponse: jest.fn(), }; -describe('Get Route Controller', () => { - let getRouteController: GetRouteController; +describe('Get Basic Route Controller', () => { + let getBasicRouteController: GetBasicRouteController; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -28,11 +28,13 @@ describe('Get Route Controller', () => { provide: RouteMapper, useValue: mockRouteMapper, }, - GetRouteController, + GetBasicRouteController, ], }).compile(); - getRouteController = module.get(GetRouteController); + getBasicRouteController = module.get( + GetBasicRouteController, + ); }); afterEach(async () => { @@ -40,12 +42,12 @@ describe('Get Route Controller', () => { }); it('should be defined', () => { - expect(getRouteController).toBeDefined(); + expect(getBasicRouteController).toBeDefined(); }); it('should get a route', async () => { jest.spyOn(mockQueryBus, 'execute'); - await getRouteController.get({ + await getBasicRouteController.get({ roles: [Role.DRIVER], waypoints: [ { @@ -59,11 +61,6 @@ describe('Get Route Controller', () => { lat: 2.3522, }, ], - georouterSettings: { - points: true, - detailedDistance: false, - detailedDuration: false, - }, }); expect(mockQueryBus.execute).toHaveBeenCalledTimes(1); }); diff --git a/src/modules/geography/tests/unit/route.mapper.spec.ts b/src/modules/geography/tests/unit/route.mapper.spec.ts index 8c27c2d..0846a7b 100644 --- a/src/modules/geography/tests/unit/route.mapper.spec.ts +++ b/src/modules/geography/tests/unit/route.mapper.spec.ts @@ -38,7 +38,7 @@ describe('Route Mapper', () => { fwdAzimuth: 283, backAzimuth: 93, distanceAzimuth: 19840, - spacetimePoints: [], + points: [], waypoints: [ { position: 0, From a6836b168cb605054221b3e71d975ebc6bb14220 Mon Sep 17 00:00:00 2001 From: sbriat Date: Tue, 22 Aug 2023 16:49:25 +0200 Subject: [PATCH 17/24] fix modules interactions --- old/app.constants.ts | 2 - old/app.module.ts | 66 -- old/interfaces/message-publisher.ts | 3 - old/modules/ad/ad.constants.ts | 4 - old/modules/ad/ad.module.ts | 61 -- .../adapters/primaries/ad-messager.service.ts | 82 --- .../ad/adapters/secondaries/ad.repository.ts | 129 ---- .../secondaries/default-params.provider.ts | 17 - .../adapters/secondaries/message-publisher.ts | 16 - .../adapters/secondaries/timezone-finder.ts | 11 - old/modules/ad/commands/create-ad.command.ts | 9 - .../ad/domain/dtos/create-ad.request.ts | 140 ----- .../domain/dtos/has-truthy-with.validator.ts | 32 - old/modules/ad/domain/entities/ad.ts | 109 ---- old/modules/ad/domain/entities/geography.ts | 92 --- .../ad/domain/entities/time-converter.ts | 19 - .../interfaces/params-provider.interface.ts | 5 - .../ad/domain/types/default-params.type.ts | 5 - old/modules/ad/domain/types/frequency.enum.ts | 4 - old/modules/ad/domain/types/role.enum.ts | 4 - .../ad/domain/usecases/create-ad.usecase.ts | 150 ----- old/modules/ad/mappers/ad.profile.ts | 18 - .../tests/integration/ad.repository.spec.ts | 402 ------------ .../default-params.provider.spec.ts | 38 -- .../secondaries/message-publisher.spec.ts | 36 -- .../secondaries/timezone-finder.spec.ts | 35 -- .../unit/domain/create-ad.usecase.spec.ts | 182 ------ .../ad/tests/unit/domain/geography.spec.ts | 138 ----- .../tests/unit/domain/time-converter.spec.ts | 53 -- .../secondaries/prisma.repository.abstract.ts | 259 -------- .../adapters/secondaries/prisma.service.ts | 15 - old/modules/database/database.module.ts | 8 - .../database/domain/database.repository.ts | 3 - .../database/exceptions/database.exception.ts | 24 - .../interfaces/collection.interface.ts | 4 - .../interfaces/repository.interface.ts | 18 - .../tests/unit/prisma-repository.spec.ts | 571 ------------------ .../secondaries/geo-timezone-finder.ts | 8 - .../adapters/secondaries/geodesic.ts | 27 - .../adapters/secondaries/georouter-creator.ts | 28 - .../secondaries/graphhopper-georouter.ts | 330 ---------- .../secondaries/postgres-direction-encoder.ts | 11 - .../geography/domain/entities/coordinate.ts | 19 - .../geography/domain/entities/route.ts | 48 -- .../domain/entities/spacetime-point.ts | 13 - .../interfaces/direction-encoder.interface.ts | 5 - .../domain/interfaces/geodesic.interface.ts | 11 - .../interfaces/georouter-creator.interface.ts | 5 - .../domain/interfaces/georouter.interface.ts | 7 - .../interfaces/timezone-finder.interface.ts | 3 - .../domain/types/georouter-settings.type.ts | 5 - .../geography/domain/types/named-route.ts | 6 - .../geography/domain/types/path.type.ts | 6 - .../geography/domain/types/point-type.enum.ts | 7 - .../geography/domain/types/point.type.ts | 6 - .../geography/domain/types/timezoner.ts | 6 - .../exceptions/geography.exception.ts | 11 - old/modules/geography/geography.module.ts | 9 - .../geography/tests/unit/coordinate.spec.ts | 8 - .../tests/unit/geo-timezone-finder.spec.ts | 14 - .../geography/tests/unit/geodesic.spec.ts | 14 - .../tests/unit/georouter-creator.spec.ts | 47 -- .../tests/unit/graphhopper-georouter.spec.ts | 456 -------------- .../unit/postgres-direction-encoder.spec.ts | 30 - .../geography/tests/unit/route.spec.ts | 48 -- .../primaries/health-server.controller.ts | 42 -- .../adapters/primaries/health.controller.ts | 37 -- .../health/adapters/primaries/health.proto | 21 - .../adapters/secondaries/message-publisher.ts | 16 - .../interfaces/check-repository.interface.ts | 3 - .../repositories.health-indicator.usecase.ts | 33 - old/modules/health/health.module.ts | 28 - .../tests/unit/message-publisher.spec.ts | 36 -- ...ositories.health-indicator.usecase.spec.ts | 55 -- .../adapters/primaries/matcher.controller.ts | 59 -- .../matcher/adapters/primaries/matcher.proto | 70 --- .../secondaries/default-params.provider.ts | 35 -- .../matcher/adapters/secondaries/geodesic.ts | 16 - .../adapters/secondaries/georouter-creator.ts | 30 - .../secondaries/graphhopper-georouter.ts | 326 ---------- .../adapters/secondaries/match.presenter.ts | 6 - .../adapters/secondaries/message-publisher.ts | 16 - .../adapters/secondaries/time-converter.ts | 21 - .../adapters/secondaries/timezone-finder.ts | 11 - .../matcher/domain/dtos/match.request.ts | 155 ----- .../domain/entities/ecosystem/actor.ts | 15 - .../matcher/domain/entities/ecosystem/ad.ts | 40 -- .../entities/ecosystem/algorithm-settings.ts | 62 -- .../domain/entities/ecosystem/geography.ts | 196 ------ .../domain/entities/ecosystem/match.ts | 6 - .../entities/ecosystem/matcher-route.ts | 16 - .../domain/entities/ecosystem/named-route.ts | 6 - .../domain/entities/ecosystem/requirement.ts | 13 - .../entities/ecosystem/spacetime-point.ts | 13 - .../matcher/domain/entities/ecosystem/time.ts | 206 ------- .../domain/entities/ecosystem/timezoner.ts | 6 - .../domain/entities/ecosystem/waypoint.ts | 14 - .../domain/entities/engine/candidate.ts | 5 - .../factory/algorithm-factory-creator.ts | 18 - .../factory/algorithm-factory.abstract.ts | 17 - .../domain/entities/engine/factory/classic.ts | 21 - .../matcher/domain/entities/engine/matcher.ts | 27 - .../classic-waypoint.completer.processor.ts | 8 - .../processor/completer/completer.abstract.ts | 8 - .../completer/journey.completer.processor.ts | 8 - .../completer/route.completer.processor.ts | 25 - .../processor/filter/filter.abstract.ts | 8 - .../geofilter/classic.filter.processor.ts | 8 - .../timefilter/classic.filter.processor.ts | 8 - .../engine/processor/processor.abstract.ts | 12 - .../engine/selector/classic.selector.ts | 8 - .../engine/selector/selector.abstract.ts | 12 - .../domain/interfaces/ad-request.interface.ts | 3 - .../algorithm-settings-request.interface.ts | 13 - .../interfaces/geography-request.interface.ts | 5 - .../interfaces/georouter-creator.interface.ts | 5 - .../domain/interfaces/georouter.interface.ts | 7 - .../requirement-request.interface.ts | 4 - .../interfaces/time-converter.interface.ts | 3 - .../interfaces/time-request.interface.ts | 12 - .../matcher/domain/types/actor.type..ts | 9 - .../matcher/domain/types/algorithm.enum.ts | 3 - old/modules/matcher/domain/types/day.type.ts | 9 - .../matcher/domain/types/days.const.ts | 1 - .../types/default-algorithm-settings.type.ts | 15 - .../domain/types/default-params.type.ts | 10 - .../domain/types/georouter-settings.type.ts | 5 - .../domain/types/margin-durations.type.ts | 9 - old/modules/matcher/domain/types/mode.enum.ts | 5 - old/modules/matcher/domain/types/path.type.ts | 6 - old/modules/matcher/domain/types/role.enum.ts | 4 - .../matcher/domain/types/schedule.type.ts | 9 - old/modules/matcher/domain/types/step.enum.ts | 6 - .../domain/types/time-schedule.type.ts | 9 - old/modules/matcher/domain/types/waypoint.ts | 7 - .../matcher/domain/usecases/match.usecase.ts | 80 --- .../matcher/exceptions/matcher.exception.ts | 33 - old/modules/matcher/mappers/match.profile.ts | 18 - old/modules/matcher/matcher.module.ts | 67 -- old/modules/matcher/queries/match.query.ts | 123 ---- .../default-params.provider.spec.ts | 38 -- .../adapters/secondaries/geodesic.spec.ts | 38 -- .../secondaries/georouter-creator.spec.ts | 47 -- .../secondaries/graphhopper-georouter.spec.ts | 456 -------------- .../secondaries/message-publisher.spec.ts | 36 -- .../secondaries/timezone-finder.spec.ts | 35 -- .../unit/domain/ecosystem/geography.spec.ts | 315 ---------- .../domain/ecosystem/matcher-route.spec.ts | 65 -- .../unit/domain/ecosystem/person.spec.ts | 40 -- .../tests/unit/domain/ecosystem/time.spec.ts | 208 ------- .../engine/algorithm-factory-creator.spec.ts | 71 --- .../engine/algorithm-factory.abstract.spec.ts | 88 --- .../engine/classic-algorithm-factory.spec.ts | 79 --- .../classic-geo.filter.processor.spec.ts | 73 --- .../classic-time.filter.processor.spec.ts | 73 --- ...assic-waypoint.completer.processor.spec.ts | 72 --- .../domain/engine/classic.selector.spec.ts | 71 --- .../domain/engine/completer.abstract.spec.ts | 78 --- .../domain/engine/filter.abstract.spec.ts | 78 --- .../journey.completer.processor.spec.ts | 71 --- .../tests/unit/domain/engine/matcher.spec.ts | 83 --- .../domain/engine/processor.abstract.spec.ts | 71 --- .../engine/route.completer.processor.spec.ts | 71 --- .../domain/engine/selector.abstract.spec.ts | 71 --- .../tests/unit/domain/match.usecase.spec.ts | 133 ---- .../tests/unit/queries/match.query.spec.ts | 262 -------- old/modules/utils/exception-code.enum.ts | 19 - .../utils/pipes/rpc.validation-pipe.ts | 14 - .../unit/rpc-validation-pipe.usecase.spec.ts | 20 - src/main.ts | 7 +- src/modules/ad/ad.module.ts | 13 +- src/modules/geography/geography.module.ts | 7 +- 172 files changed, 17 insertions(+), 9020 deletions(-) delete mode 100644 old/app.constants.ts delete mode 100644 old/app.module.ts delete mode 100644 old/interfaces/message-publisher.ts delete mode 100644 old/modules/ad/ad.constants.ts delete mode 100644 old/modules/ad/ad.module.ts delete mode 100644 old/modules/ad/adapters/primaries/ad-messager.service.ts delete mode 100644 old/modules/ad/adapters/secondaries/ad.repository.ts delete mode 100644 old/modules/ad/adapters/secondaries/default-params.provider.ts delete mode 100644 old/modules/ad/adapters/secondaries/message-publisher.ts delete mode 100644 old/modules/ad/adapters/secondaries/timezone-finder.ts delete mode 100644 old/modules/ad/commands/create-ad.command.ts delete mode 100644 old/modules/ad/domain/dtos/create-ad.request.ts delete mode 100644 old/modules/ad/domain/dtos/has-truthy-with.validator.ts delete mode 100644 old/modules/ad/domain/entities/ad.ts delete mode 100644 old/modules/ad/domain/entities/geography.ts delete mode 100644 old/modules/ad/domain/entities/time-converter.ts delete mode 100644 old/modules/ad/domain/interfaces/params-provider.interface.ts delete mode 100644 old/modules/ad/domain/types/default-params.type.ts delete mode 100644 old/modules/ad/domain/types/frequency.enum.ts delete mode 100644 old/modules/ad/domain/types/role.enum.ts delete mode 100644 old/modules/ad/domain/usecases/create-ad.usecase.ts delete mode 100644 old/modules/ad/mappers/ad.profile.ts delete mode 100644 old/modules/ad/tests/integration/ad.repository.spec.ts delete mode 100644 old/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts delete mode 100644 old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts delete mode 100644 old/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts delete mode 100644 old/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts delete mode 100644 old/modules/ad/tests/unit/domain/geography.spec.ts delete mode 100644 old/modules/ad/tests/unit/domain/time-converter.spec.ts delete mode 100644 old/modules/database/adapters/secondaries/prisma.repository.abstract.ts delete mode 100644 old/modules/database/adapters/secondaries/prisma.service.ts delete mode 100644 old/modules/database/database.module.ts delete mode 100644 old/modules/database/domain/database.repository.ts delete mode 100644 old/modules/database/exceptions/database.exception.ts delete mode 100644 old/modules/database/interfaces/collection.interface.ts delete mode 100644 old/modules/database/interfaces/repository.interface.ts delete mode 100644 old/modules/database/tests/unit/prisma-repository.spec.ts delete mode 100644 old/modules/geography/adapters/secondaries/geo-timezone-finder.ts delete mode 100644 old/modules/geography/adapters/secondaries/geodesic.ts delete mode 100644 old/modules/geography/adapters/secondaries/georouter-creator.ts delete mode 100644 old/modules/geography/adapters/secondaries/graphhopper-georouter.ts delete mode 100644 old/modules/geography/adapters/secondaries/postgres-direction-encoder.ts delete mode 100644 old/modules/geography/domain/entities/coordinate.ts delete mode 100644 old/modules/geography/domain/entities/route.ts delete mode 100644 old/modules/geography/domain/entities/spacetime-point.ts delete mode 100644 old/modules/geography/domain/interfaces/direction-encoder.interface.ts delete mode 100644 old/modules/geography/domain/interfaces/geodesic.interface.ts delete mode 100644 old/modules/geography/domain/interfaces/georouter-creator.interface.ts delete mode 100644 old/modules/geography/domain/interfaces/georouter.interface.ts delete mode 100644 old/modules/geography/domain/interfaces/timezone-finder.interface.ts delete mode 100644 old/modules/geography/domain/types/georouter-settings.type.ts delete mode 100644 old/modules/geography/domain/types/named-route.ts delete mode 100644 old/modules/geography/domain/types/path.type.ts delete mode 100644 old/modules/geography/domain/types/point-type.enum.ts delete mode 100644 old/modules/geography/domain/types/point.type.ts delete mode 100644 old/modules/geography/domain/types/timezoner.ts delete mode 100644 old/modules/geography/exceptions/geography.exception.ts delete mode 100644 old/modules/geography/geography.module.ts delete mode 100644 old/modules/geography/tests/unit/coordinate.spec.ts delete mode 100644 old/modules/geography/tests/unit/geo-timezone-finder.spec.ts delete mode 100644 old/modules/geography/tests/unit/geodesic.spec.ts delete mode 100644 old/modules/geography/tests/unit/georouter-creator.spec.ts delete mode 100644 old/modules/geography/tests/unit/graphhopper-georouter.spec.ts delete mode 100644 old/modules/geography/tests/unit/postgres-direction-encoder.spec.ts delete mode 100644 old/modules/geography/tests/unit/route.spec.ts delete mode 100644 old/modules/health/adapters/primaries/health-server.controller.ts delete mode 100644 old/modules/health/adapters/primaries/health.controller.ts delete mode 100644 old/modules/health/adapters/primaries/health.proto delete mode 100644 old/modules/health/adapters/secondaries/message-publisher.ts delete mode 100644 old/modules/health/domain/interfaces/check-repository.interface.ts delete mode 100644 old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts delete mode 100644 old/modules/health/health.module.ts delete mode 100644 old/modules/health/tests/unit/message-publisher.spec.ts delete mode 100644 old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts delete mode 100644 old/modules/matcher/adapters/primaries/matcher.controller.ts delete mode 100644 old/modules/matcher/adapters/primaries/matcher.proto delete mode 100644 old/modules/matcher/adapters/secondaries/default-params.provider.ts delete mode 100644 old/modules/matcher/adapters/secondaries/geodesic.ts delete mode 100644 old/modules/matcher/adapters/secondaries/georouter-creator.ts delete mode 100644 old/modules/matcher/adapters/secondaries/graphhopper-georouter.ts delete mode 100644 old/modules/matcher/adapters/secondaries/match.presenter.ts delete mode 100644 old/modules/matcher/adapters/secondaries/message-publisher.ts delete mode 100644 old/modules/matcher/adapters/secondaries/time-converter.ts delete mode 100644 old/modules/matcher/adapters/secondaries/timezone-finder.ts delete mode 100644 old/modules/matcher/domain/dtos/match.request.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/actor.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/ad.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/geography.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/match.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/matcher-route.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/named-route.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/requirement.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/spacetime-point.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/time.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/timezoner.ts delete mode 100644 old/modules/matcher/domain/entities/ecosystem/waypoint.ts delete mode 100644 old/modules/matcher/domain/entities/engine/candidate.ts delete mode 100644 old/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts delete mode 100644 old/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts delete mode 100644 old/modules/matcher/domain/entities/engine/factory/classic.ts delete mode 100644 old/modules/matcher/domain/entities/engine/matcher.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts delete mode 100644 old/modules/matcher/domain/entities/engine/processor/processor.abstract.ts delete mode 100644 old/modules/matcher/domain/entities/engine/selector/classic.selector.ts delete mode 100644 old/modules/matcher/domain/entities/engine/selector/selector.abstract.ts delete mode 100644 old/modules/matcher/domain/interfaces/ad-request.interface.ts delete mode 100644 old/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts delete mode 100644 old/modules/matcher/domain/interfaces/geography-request.interface.ts delete mode 100644 old/modules/matcher/domain/interfaces/georouter-creator.interface.ts delete mode 100644 old/modules/matcher/domain/interfaces/georouter.interface.ts delete mode 100644 old/modules/matcher/domain/interfaces/requirement-request.interface.ts delete mode 100644 old/modules/matcher/domain/interfaces/time-converter.interface.ts delete mode 100644 old/modules/matcher/domain/interfaces/time-request.interface.ts delete mode 100644 old/modules/matcher/domain/types/actor.type..ts delete mode 100644 old/modules/matcher/domain/types/algorithm.enum.ts delete mode 100644 old/modules/matcher/domain/types/day.type.ts delete mode 100644 old/modules/matcher/domain/types/days.const.ts delete mode 100644 old/modules/matcher/domain/types/default-algorithm-settings.type.ts delete mode 100644 old/modules/matcher/domain/types/default-params.type.ts delete mode 100644 old/modules/matcher/domain/types/georouter-settings.type.ts delete mode 100644 old/modules/matcher/domain/types/margin-durations.type.ts delete mode 100644 old/modules/matcher/domain/types/mode.enum.ts delete mode 100644 old/modules/matcher/domain/types/path.type.ts delete mode 100644 old/modules/matcher/domain/types/role.enum.ts delete mode 100644 old/modules/matcher/domain/types/schedule.type.ts delete mode 100644 old/modules/matcher/domain/types/step.enum.ts delete mode 100644 old/modules/matcher/domain/types/time-schedule.type.ts delete mode 100644 old/modules/matcher/domain/types/waypoint.ts delete mode 100644 old/modules/matcher/domain/usecases/match.usecase.ts delete mode 100644 old/modules/matcher/exceptions/matcher.exception.ts delete mode 100644 old/modules/matcher/mappers/match.profile.ts delete mode 100644 old/modules/matcher/matcher.module.ts delete mode 100644 old/modules/matcher/queries/match.query.ts delete mode 100644 old/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts delete mode 100644 old/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts delete mode 100644 old/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts delete mode 100644 old/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts delete mode 100644 old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts delete mode 100644 old/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/matcher.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts delete mode 100644 old/modules/matcher/tests/unit/domain/match.usecase.spec.ts delete mode 100644 old/modules/matcher/tests/unit/queries/match.query.spec.ts delete mode 100644 old/modules/utils/exception-code.enum.ts delete mode 100644 old/modules/utils/pipes/rpc.validation-pipe.ts delete mode 100644 old/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts diff --git a/old/app.constants.ts b/old/app.constants.ts deleted file mode 100644 index 28001cd..0000000 --- a/old/app.constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const MESSAGE_BROKER_PUBLISHER = Symbol('MESSAGE_BROKER_PUBLISHER'); -export const MESSAGE_PUBLISHER = Symbol('MESSAGE_PUBLISHER'); diff --git a/old/app.module.ts b/old/app.module.ts deleted file mode 100644 index 25543ee..0000000 --- a/old/app.module.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { classes } from '@automapper/classes'; -import { AutomapperModule } from '@automapper/nestjs'; -import { Module } from '@nestjs/common'; -import { ConfigModule, ConfigService } from '@nestjs/config'; -import { HealthModule } from './modules/health/health.module'; -import { MatcherModule } from './modules/matcher/matcher.module'; -import { AdModule } from './modules/ad/ad.module'; -import { - ConfigurationModule, - ConfigurationModuleOptions, -} from '@mobicoop/configuration-module'; -import { - MessageBrokerModule, - MessageBrokerModuleOptions, -} from '@mobicoop/message-broker-module'; - -@Module({ - imports: [ - ConfigModule.forRoot({ isGlobal: true }), - ConfigurationModule.forRootAsync({ - imports: [ConfigModule], - inject: [ConfigService], - useFactory: async ( - configService: ConfigService, - ): Promise => ({ - domain: configService.get('SERVICE_CONFIGURATION_DOMAIN'), - messageBroker: { - uri: configService.get('MESSAGE_BROKER_URI'), - exchange: configService.get('MESSAGE_BROKER_EXCHANGE'), - }, - redis: { - host: configService.get('REDIS_HOST'), - password: configService.get('REDIS_PASSWORD'), - port: configService.get('REDIS_PORT'), - }, - setConfigurationBrokerQueue: 'matcher-configuration-create-update', - deleteConfigurationQueue: 'matcher-configuration-delete', - propagateConfigurationQueue: 'matcher-configuration-propagate', - }), - }), - MessageBrokerModule.forRootAsync({ - imports: [ConfigModule], - inject: [ConfigService], - useFactory: async ( - configService: ConfigService, - ): Promise => ({ - uri: configService.get('MESSAGE_BROKER_URI'), - exchange: configService.get('MESSAGE_BROKER_EXCHANGE'), - handlers: { - adCreated: { - routingKey: 'ad.created', - queue: 'matcher-ad-created', - }, - }, - name: 'matcher', - }), - }), - AutomapperModule.forRoot({ strategyInitializer: classes() }), - HealthModule, - MatcherModule, - AdModule, - ], - controllers: [], - providers: [], -}) -export class AppModule {} diff --git a/old/interfaces/message-publisher.ts b/old/interfaces/message-publisher.ts deleted file mode 100644 index 29ad456..0000000 --- a/old/interfaces/message-publisher.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IPublishMessage { - publish(routingKey: string, message: string): void; -} diff --git a/old/modules/ad/ad.constants.ts b/old/modules/ad/ad.constants.ts deleted file mode 100644 index 2f044c9..0000000 --- a/old/modules/ad/ad.constants.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const PARAMS_PROVIDER = Symbol(); -export const GEOROUTER_CREATOR = Symbol(); -export const TIMEZONE_FINDER = Symbol(); -export const DIRECTION_ENCODER = Symbol(); diff --git a/old/modules/ad/ad.module.ts b/old/modules/ad/ad.module.ts deleted file mode 100644 index 4a36f22..0000000 --- a/old/modules/ad/ad.module.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Module } from '@nestjs/common'; -import { AdMessagerService } from './adapters/primaries/ad-messager.service'; -import { AdProfile } from './mappers/ad.profile'; -import { CreateAdUseCase } from './domain/usecases/create-ad.usecase'; -import { AdRepository } from './adapters/secondaries/ad.repository'; -import { DatabaseModule } from '../database/database.module'; -import { CqrsModule } from '@nestjs/cqrs'; -import { GeoTimezoneFinder } from '../geography/adapters/secondaries/geo-timezone-finder'; -import { DefaultParamsProvider } from './adapters/secondaries/default-params.provider'; -import { GeorouterCreator } from '../geography/adapters/secondaries/georouter-creator'; -import { GeographyModule } from '../geography/geography.module'; -import { HttpModule } from '@nestjs/axios'; -import { PostgresDirectionEncoder } from '../geography/adapters/secondaries/postgres-direction-encoder'; -import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; -import { - MESSAGE_BROKER_PUBLISHER, - MESSAGE_PUBLISHER, -} from '../../app.constants'; -import { MessagePublisher } from './adapters/secondaries/message-publisher'; -import { - DIRECTION_ENCODER, - GEOROUTER_CREATOR, - PARAMS_PROVIDER, - TIMEZONE_FINDER, -} from './ad.constants'; - -@Module({ - imports: [GeographyModule, DatabaseModule, CqrsModule, HttpModule], - providers: [ - { - provide: PARAMS_PROVIDER, - useClass: DefaultParamsProvider, - }, - { - provide: GEOROUTER_CREATOR, - useClass: GeorouterCreator, - }, - { - provide: TIMEZONE_FINDER, - useClass: GeoTimezoneFinder, - }, - { - provide: DIRECTION_ENCODER, - useClass: PostgresDirectionEncoder, - }, - { - provide: MESSAGE_BROKER_PUBLISHER, - useClass: MessageBrokerPublisher, - }, - { - provide: MESSAGE_PUBLISHER, - useClass: MessagePublisher, - }, - AdProfile, - AdRepository, - CreateAdUseCase, - AdMessagerService, - ], - exports: [], -}) -export class AdModule {} diff --git a/old/modules/ad/adapters/primaries/ad-messager.service.ts b/old/modules/ad/adapters/primaries/ad-messager.service.ts deleted file mode 100644 index d5f2b5a..0000000 --- a/old/modules/ad/adapters/primaries/ad-messager.service.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Controller, Inject } from '@nestjs/common'; -import { CommandBus } from '@nestjs/cqrs'; -import { CreateAdCommand } from '../../commands/create-ad.command'; -import { CreateAdRequest } from '../../domain/dtos/create-ad.request'; -import { validateOrReject } from 'class-validator'; -import { plainToInstance } from 'class-transformer'; -import { DatabaseException } from 'src/modules/database/exceptions/database.exception'; -import { ExceptionCode } from 'src/modules/utils/exception-code.enum'; -import { IPublishMessage } from 'src/interfaces/message-publisher'; -import { MESSAGE_PUBLISHER } from 'src/app.constants'; -import { RabbitSubscribe } from '@mobicoop/message-broker-module'; - -@Controller() -export class AdMessagerService { - constructor( - @Inject(MESSAGE_PUBLISHER) - private readonly messagePublisher: IPublishMessage, - private readonly commandBus: CommandBus, - ) {} - - @RabbitSubscribe({ - name: 'adCreated', - }) - async adCreatedHandler(message: string): Promise { - let createAdRequest: CreateAdRequest; - // parse message to request instance - try { - createAdRequest = plainToInstance(CreateAdRequest, JSON.parse(message)); - // validate instance - await validateOrReject(createAdRequest); - // validate nested objects (fixes direct nested validation bug) - for (const waypoint of createAdRequest.addresses) { - try { - await validateOrReject(waypoint); - } catch (e) { - throw e; - } - } - } catch (e) { - this.messagePublisher.publish( - 'matcher.ad.crit', - JSON.stringify({ - message: `Can't validate message : ${message}`, - error: e, - }), - ); - } - try { - await this.commandBus.execute(new CreateAdCommand(createAdRequest)); - } catch (e) { - if (e instanceof DatabaseException) { - if (e.message.includes('already exists')) { - this.messagePublisher.publish( - 'matcher.ad.crit', - JSON.stringify({ - code: ExceptionCode.ALREADY_EXISTS, - message: 'Already exists', - uuid: createAdRequest.uuid, - }), - ); - } - if (e.message.includes("Can't reach database server")) { - this.messagePublisher.publish( - 'matcher.ad.crit', - JSON.stringify({ - code: ExceptionCode.UNAVAILABLE, - message: 'Database server unavailable', - uuid: createAdRequest.uuid, - }), - ); - } - } - this.messagePublisher.publish( - 'logging.matcher.ad.crit', - JSON.stringify({ - message, - error: e, - }), - ); - } - } -} diff --git a/old/modules/ad/adapters/secondaries/ad.repository.ts b/old/modules/ad/adapters/secondaries/ad.repository.ts deleted file mode 100644 index 51ff9e7..0000000 --- a/old/modules/ad/adapters/secondaries/ad.repository.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { DatabaseRepository } from '../../../database/domain/database.repository'; -import { Ad } from '../../domain/entities/ad'; -import { DatabaseException } from '../../../database/exceptions/database.exception'; - -@Injectable() -export class AdRepository extends DatabaseRepository { - protected model = 'ad'; - - createAd = async (ad: Partial): Promise => { - try { - const affectedRowNumber = await this.createWithFields( - this.createFields(ad), - ); - if (affectedRowNumber == 1) { - return this.findOneByUuid(ad.uuid); - } - throw new DatabaseException(); - } catch (e) { - throw e; - } - }; - - private createFields = (ad: Partial): Partial => ({ - uuid: `'${ad.uuid}'`, - userUuid: `'${ad.userUuid}'`, - driver: ad.driver ? 'true' : 'false', - passenger: ad.passenger ? 'true' : 'false', - frequency: `'${ad.frequency}'`, - fromDate: `'${ad.fromDate.getFullYear()}-${ - ad.fromDate.getMonth() + 1 - }-${ad.fromDate.getDate()}'`, - toDate: `'${ad.toDate.getFullYear()}-${ - ad.toDate.getMonth() + 1 - }-${ad.toDate.getDate()}'`, - monTime: ad.monTime - ? `'${ad.monTime.getFullYear()}-${ - ad.monTime.getMonth() + 1 - }-${ad.monTime.getDate()}T${ad.monTime.getHours()}:${ad.monTime.getMinutes()}Z'` - : 'NULL', - tueTime: ad.tueTime - ? `'${ad.tueTime.getFullYear()}-${ - ad.tueTime.getMonth() + 1 - }-${ad.tueTime.getDate()}T${ad.tueTime.getHours()}:${ad.tueTime.getMinutes()}Z'` - : 'NULL', - wedTime: ad.wedTime - ? `'${ad.wedTime.getFullYear()}-${ - ad.wedTime.getMonth() + 1 - }-${ad.wedTime.getDate()}T${ad.wedTime.getHours()}:${ad.wedTime.getMinutes()}Z'` - : 'NULL', - thuTime: ad.thuTime - ? `'${ad.thuTime.getFullYear()}-${ - ad.thuTime.getMonth() + 1 - }-${ad.thuTime.getDate()}T${ad.thuTime.getHours()}:${ad.thuTime.getMinutes()}Z'` - : 'NULL', - friTime: ad.friTime - ? `'${ad.friTime.getFullYear()}-${ - ad.friTime.getMonth() + 1 - }-${ad.friTime.getDate()}T${ad.friTime.getHours()}:${ad.friTime.getMinutes()}Z'` - : 'NULL', - satTime: ad.satTime - ? `'${ad.satTime.getFullYear()}-${ - ad.satTime.getMonth() + 1 - }-${ad.satTime.getDate()}T${ad.satTime.getHours()}:${ad.satTime.getMinutes()}Z'` - : 'NULL', - sunTime: ad.sunTime - ? `'${ad.sunTime.getFullYear()}-${ - ad.sunTime.getMonth() + 1 - }-${ad.sunTime.getDate()}T${ad.sunTime.getHours()}:${ad.sunTime.getMinutes()}Z'` - : 'NULL', - monMargin: ad.monMargin, - tueMargin: ad.tueMargin, - wedMargin: ad.wedMargin, - thuMargin: ad.thuMargin, - friMargin: ad.friMargin, - satMargin: ad.satMargin, - sunMargin: ad.sunMargin, - fwdAzimuth: ad.fwdAzimuth, - backAzimuth: ad.backAzimuth, - driverDuration: ad.driverDuration ?? 'NULL', - driverDistance: ad.driverDistance ?? 'NULL', - passengerDuration: ad.passengerDuration ?? 'NULL', - passengerDistance: ad.passengerDistance ?? 'NULL', - waypoints: ad.waypoints, - direction: ad.direction, - seatsDriver: ad.seatsDriver, - seatsPassenger: ad.seatsPassenger, - seatsUsed: ad.seatsUsed ?? 0, - strict: ad.strict, - }); -} - -type AdFields = { - uuid: string; - userUuid: string; - driver: string; - passenger: string; - frequency: string; - fromDate: string; - toDate: string; - monTime: string; - tueTime: string; - wedTime: string; - thuTime: string; - friTime: string; - satTime: string; - sunTime: string; - monMargin: number; - tueMargin: number; - wedMargin: number; - thuMargin: number; - friMargin: number; - satMargin: number; - sunMargin: number; - driverDuration?: number | 'NULL'; - driverDistance?: number | 'NULL'; - passengerDuration?: number | 'NULL'; - passengerDistance?: number | 'NULL'; - waypoints: string; - direction: string; - fwdAzimuth: number; - backAzimuth: number; - seatsDriver?: number; - seatsPassenger?: number; - seatsUsed?: number; - strict: boolean; - createdAt: string; - updatedAt: string; -}; diff --git a/old/modules/ad/adapters/secondaries/default-params.provider.ts b/old/modules/ad/adapters/secondaries/default-params.provider.ts deleted file mode 100644 index f0a41fb..0000000 --- a/old/modules/ad/adapters/secondaries/default-params.provider.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { DefaultParams } from '../../domain/types/default-params.type'; -import { IProvideParams } from '../../domain/interfaces/params-provider.interface'; - -@Injectable() -export class DefaultParamsProvider implements IProvideParams { - constructor(private readonly configService: ConfigService) {} - - getParams = (): DefaultParams => { - return { - DEFAULT_TIMEZONE: this.configService.get('DEFAULT_TIMEZONE'), - GEOROUTER_TYPE: this.configService.get('GEOROUTER_TYPE'), - GEOROUTER_URL: this.configService.get('GEOROUTER_URL'), - }; - }; -} diff --git a/old/modules/ad/adapters/secondaries/message-publisher.ts b/old/modules/ad/adapters/secondaries/message-publisher.ts deleted file mode 100644 index 315bb6b..0000000 --- a/old/modules/ad/adapters/secondaries/message-publisher.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; -import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; -import { IPublishMessage } from '../../../../interfaces/message-publisher'; - -@Injectable() -export class MessagePublisher implements IPublishMessage { - constructor( - @Inject(MESSAGE_BROKER_PUBLISHER) - private readonly messageBrokerPublisher: MessageBrokerPublisher, - ) {} - - publish = (routingKey: string, message: string): void => { - this.messageBrokerPublisher.publish(routingKey, message); - }; -} diff --git a/old/modules/ad/adapters/secondaries/timezone-finder.ts b/old/modules/ad/adapters/secondaries/timezone-finder.ts deleted file mode 100644 index 8459661..0000000 --- a/old/modules/ad/adapters/secondaries/timezone-finder.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { GeoTimezoneFinder } from '../../../geography/adapters/secondaries/geo-timezone-finder'; -import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-finder.interface'; - -@Injectable() -export class TimezoneFinder implements IFindTimezone { - constructor(private readonly geoTimezoneFinder: GeoTimezoneFinder) {} - - timezones = (lon: number, lat: number): string[] => - this.geoTimezoneFinder.timezones(lon, lat); -} diff --git a/old/modules/ad/commands/create-ad.command.ts b/old/modules/ad/commands/create-ad.command.ts deleted file mode 100644 index b4f1e8d..0000000 --- a/old/modules/ad/commands/create-ad.command.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { CreateAdRequest } from '../domain/dtos/create-ad.request'; - -export class CreateAdCommand { - readonly createAdRequest: CreateAdRequest; - - constructor(request: CreateAdRequest) { - this.createAdRequest = request; - } -} diff --git a/old/modules/ad/domain/dtos/create-ad.request.ts b/old/modules/ad/domain/dtos/create-ad.request.ts deleted file mode 100644 index 06bb0d6..0000000 --- a/old/modules/ad/domain/dtos/create-ad.request.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { AutoMap } from '@automapper/classes'; -import { - ArrayMinSize, - IsArray, - IsBoolean, - IsDate, - IsEnum, - IsMilitaryTime, - IsNotEmpty, - IsNumber, - IsOptional, - IsString, -} from 'class-validator'; -import { Frequency } from '../types/frequency.enum'; -import { Coordinate } from '../../../geography/domain/entities/coordinate'; -import { Type } from 'class-transformer'; -import { HasTruthyWith } from './has-truthy-with.validator'; - -export class CreateAdRequest { - @IsString() - @IsNotEmpty() - @AutoMap() - uuid: string; - - @IsString() - @IsNotEmpty() - @AutoMap() - userUuid: string; - - @HasTruthyWith('passenger', { - message: 'A role (driver or passenger) must be set to true', - }) - @IsBoolean() - @AutoMap() - driver: boolean; - - @IsBoolean() - @AutoMap() - passenger: boolean; - - @IsEnum(Frequency) - @AutoMap() - frequency: Frequency; - - @Type(() => Date) - @IsDate() - @AutoMap() - fromDate: Date; - - @Type(() => Date) - @IsDate() - @AutoMap() - toDate: Date; - - @IsOptional() - @IsMilitaryTime() - @AutoMap() - monTime?: string; - - @IsOptional() - @IsMilitaryTime() - @AutoMap() - tueTime?: string; - - @IsOptional() - @IsMilitaryTime() - @AutoMap() - wedTime?: string; - - @IsOptional() - @IsMilitaryTime() - @AutoMap() - thuTime?: string; - - @IsOptional() - @IsMilitaryTime() - @AutoMap() - friTime?: string; - - @IsOptional() - @IsMilitaryTime() - @AutoMap() - satTime?: string; - - @IsOptional() - @IsMilitaryTime() - @AutoMap() - sunTime?: string; - - @IsNumber() - @AutoMap() - monMargin: number; - - @IsNumber() - @AutoMap() - tueMargin: number; - - @IsNumber() - @AutoMap() - wedMargin: number; - - @IsNumber() - @AutoMap() - thuMargin: number; - - @IsNumber() - @AutoMap() - friMargin: number; - - @IsNumber() - @AutoMap() - satMargin: number; - - @IsNumber() - @AutoMap() - sunMargin: number; - - @Type(() => Coordinate) - @IsArray() - @ArrayMinSize(2) - @AutoMap(() => [Coordinate]) - addresses: Coordinate[]; - - @IsNumber() - @AutoMap() - seatsDriver: number; - - @IsNumber() - @AutoMap() - seatsPassenger: number; - - @IsOptional() - @IsNumber() - @AutoMap() - seatsUsed?: number; - - @IsBoolean() - @AutoMap() - strict: boolean; -} diff --git a/old/modules/ad/domain/dtos/has-truthy-with.validator.ts b/old/modules/ad/domain/dtos/has-truthy-with.validator.ts deleted file mode 100644 index 06460c6..0000000 --- a/old/modules/ad/domain/dtos/has-truthy-with.validator.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { - registerDecorator, - ValidationOptions, - ValidationArguments, -} from 'class-validator'; - -export function HasTruthyWith( - property: string, - validationOptions?: ValidationOptions, -) { - // eslint-disable-next-line @typescript-eslint/ban-types - return function (object: Object, propertyName: string) { - registerDecorator({ - name: 'hasTruthyWith', - target: object.constructor, - propertyName: propertyName, - constraints: [property], - options: validationOptions, - validator: { - validate(value: any, args: ValidationArguments) { - const [relatedPropertyName] = args.constraints; - const relatedValue = (args.object as any)[relatedPropertyName]; - return ( - typeof value === 'boolean' && - typeof relatedValue === 'boolean' && - (value || relatedValue) - ); // you can return a Promise here as well, if you want to make async validation - }, - }, - }); - }; -} diff --git a/old/modules/ad/domain/entities/ad.ts b/old/modules/ad/domain/entities/ad.ts deleted file mode 100644 index a3a7ffb..0000000 --- a/old/modules/ad/domain/entities/ad.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { AutoMap } from '@automapper/classes'; -import { Frequency } from '../types/frequency.enum'; - -export class Ad { - @AutoMap() - uuid: string; - - @AutoMap() - userUuid: string; - - @AutoMap() - driver: boolean; - - @AutoMap() - passenger: boolean; - - @AutoMap() - frequency: Frequency; - - @AutoMap() - fromDate: Date; - - @AutoMap() - toDate: Date; - - @AutoMap() - monTime: Date; - - @AutoMap() - tueTime: Date; - - @AutoMap() - wedTime: Date; - - @AutoMap() - thuTime: Date; - - @AutoMap() - friTime: Date; - - @AutoMap() - satTime: Date; - - @AutoMap() - sunTime: Date; - - @AutoMap() - monMargin: number; - - @AutoMap() - tueMargin: number; - - @AutoMap() - wedMargin: number; - - @AutoMap() - thuMargin: number; - - @AutoMap() - friMargin: number; - - @AutoMap() - satMargin: number; - - @AutoMap() - sunMargin: number; - - @AutoMap() - driverDuration?: number; - - @AutoMap() - driverDistance?: number; - - @AutoMap() - passengerDuration?: number; - - @AutoMap() - passengerDistance?: number; - - @AutoMap() - waypoints: string; - - @AutoMap() - direction: string; - - @AutoMap() - fwdAzimuth: number; - - @AutoMap() - backAzimuth: number; - - @AutoMap() - seatsDriver: number; - - @AutoMap() - seatsPassenger: number; - - @AutoMap() - seatsUsed: number; - - @AutoMap() - strict: boolean; - - @AutoMap() - createdAt: Date; - - @AutoMap() - updatedAt: Date; -} diff --git a/old/modules/ad/domain/entities/geography.ts b/old/modules/ad/domain/entities/geography.ts deleted file mode 100644 index e1ba54c..0000000 --- a/old/modules/ad/domain/entities/geography.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Coordinate } from '../../../geography/domain/entities/coordinate'; -import { Route } from '../../../geography/domain/entities/route'; -import { Role } from '../types/role.enum'; -import { IGeorouter } from '../../../geography/domain/interfaces/georouter.interface'; -import { Path } from '../../../geography/domain/types/path.type'; -import { GeorouterSettings } from '../../../geography/domain/types/georouter-settings.type'; - -export class Geography { - private coordinates: Coordinate[]; - driverRoute: Route; - passengerRoute: Route; - - constructor(coordinates: Coordinate[]) { - this.coordinates = coordinates; - } - - createRoutes = async ( - roles: Role[], - georouter: IGeorouter, - settings: GeorouterSettings, - ): Promise => { - const paths: Path[] = this.getPaths(roles); - const routes = await georouter.route(paths, settings); - if (routes.some((route) => route.key == RouteType.COMMON)) { - this.driverRoute = routes.find( - (route) => route.key == RouteType.COMMON, - ).route; - this.passengerRoute = routes.find( - (route) => route.key == RouteType.COMMON, - ).route; - } else { - if (routes.some((route) => route.key == RouteType.DRIVER)) { - this.driverRoute = routes.find( - (route) => route.key == RouteType.DRIVER, - ).route; - } - if (routes.some((route) => route.key == RouteType.PASSENGER)) { - this.passengerRoute = routes.find( - (route) => route.key == RouteType.PASSENGER, - ).route; - } - } - }; - - private getPaths = (roles: Role[]): Path[] => { - const paths: Path[] = []; - if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) { - if (this.coordinates.length == 2) { - // 2 points => same route for driver and passenger - const commonPath: Path = { - key: RouteType.COMMON, - points: this.coordinates, - }; - paths.push(commonPath); - } else { - const driverPath: Path = this.createDriverPath(); - const passengerPath: Path = this.createPassengerPath(); - paths.push(driverPath, passengerPath); - } - } else if (roles.includes(Role.DRIVER)) { - const driverPath: Path = this.createDriverPath(); - paths.push(driverPath); - } else if (roles.includes(Role.PASSENGER)) { - const passengerPath: Path = this.createPassengerPath(); - paths.push(passengerPath); - } - return paths; - }; - - private createDriverPath = (): Path => { - return { - key: RouteType.DRIVER, - points: this.coordinates, - }; - }; - - private createPassengerPath = (): Path => { - return { - key: RouteType.PASSENGER, - points: [ - this.coordinates[0], - this.coordinates[this.coordinates.length - 1], - ], - }; - }; -} - -export enum RouteType { - COMMON = 'common', - DRIVER = 'driver', - PASSENGER = 'passenger', -} diff --git a/old/modules/ad/domain/entities/time-converter.ts b/old/modules/ad/domain/entities/time-converter.ts deleted file mode 100644 index e60bf76..0000000 --- a/old/modules/ad/domain/entities/time-converter.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { DateTime, TimeZone } from 'timezonecomplete'; - -export class TimeConverter { - static toUtcDatetime = (date: Date, time: string, timezone: string): Date => { - try { - if (!date || !time || !timezone) throw new Error(); - return new Date( - new DateTime( - `${date.toISOString().split('T')[0]}T${time}:00`, - TimeZone.zone(timezone, false), - ) - .convert(TimeZone.zone('UTC')) - .toIsoString(), - ); - } catch (e) { - return undefined; - } - }; -} diff --git a/old/modules/ad/domain/interfaces/params-provider.interface.ts b/old/modules/ad/domain/interfaces/params-provider.interface.ts deleted file mode 100644 index bde5a06..0000000 --- a/old/modules/ad/domain/interfaces/params-provider.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { DefaultParams } from '../types/default-params.type'; - -export interface IProvideParams { - getParams(): DefaultParams; -} diff --git a/old/modules/ad/domain/types/default-params.type.ts b/old/modules/ad/domain/types/default-params.type.ts deleted file mode 100644 index bea841b..0000000 --- a/old/modules/ad/domain/types/default-params.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type DefaultParams = { - DEFAULT_TIMEZONE: string; - GEOROUTER_TYPE: string; - GEOROUTER_URL: string; -}; diff --git a/old/modules/ad/domain/types/frequency.enum.ts b/old/modules/ad/domain/types/frequency.enum.ts deleted file mode 100644 index 0126874..0000000 --- a/old/modules/ad/domain/types/frequency.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Frequency { - PUNCTUAL = 'PUNCTUAL', - RECURRENT = 'RECURRENT', -} diff --git a/old/modules/ad/domain/types/role.enum.ts b/old/modules/ad/domain/types/role.enum.ts deleted file mode 100644 index 7522f80..0000000 --- a/old/modules/ad/domain/types/role.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Role { - DRIVER = 'DRIVER', - PASSENGER = 'PASSENGER', -} diff --git a/old/modules/ad/domain/usecases/create-ad.usecase.ts b/old/modules/ad/domain/usecases/create-ad.usecase.ts deleted file mode 100644 index 506a82a..0000000 --- a/old/modules/ad/domain/usecases/create-ad.usecase.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { CommandHandler } from '@nestjs/cqrs'; -import { CreateAdCommand } from '../../commands/create-ad.command'; -import { Ad } from '../entities/ad'; -import { AdRepository } from '../../adapters/secondaries/ad.repository'; -import { InjectMapper } from '@automapper/nestjs'; -import { Mapper } from '@automapper/core'; -import { CreateAdRequest } from '../dtos/create-ad.request'; -import { Inject } from '@nestjs/common'; -import { IProvideParams } from '../interfaces/params-provider.interface'; -import { ICreateGeorouter } from '../../../geography/domain/interfaces/georouter-creator.interface'; -import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-finder.interface'; -import { IGeorouter } from '../../../geography/domain/interfaces/georouter.interface'; -import { DefaultParams } from '../types/default-params.type'; -import { Role } from '../types/role.enum'; -import { Geography } from '../entities/geography'; -import { IEncodeDirection } from '../../../geography/domain/interfaces/direction-encoder.interface'; -import { TimeConverter } from '../entities/time-converter'; -import { Coordinate } from '../../../geography/domain/entities/coordinate'; -import { - DIRECTION_ENCODER, - GEOROUTER_CREATOR, - PARAMS_PROVIDER, - TIMEZONE_FINDER, -} from '../../ad.constants'; - -@CommandHandler(CreateAdCommand) -export class CreateAdUseCase { - private readonly georouter: IGeorouter; - private readonly defaultParams: DefaultParams; - private timezone: string; - private roles: Role[]; - private geography: Geography; - private ad: Ad; - - constructor( - @InjectMapper() private readonly mapper: Mapper, - private readonly adRepository: AdRepository, - @Inject(PARAMS_PROVIDER) - private readonly defaultParamsProvider: IProvideParams, - @Inject(GEOROUTER_CREATOR) - private readonly georouterCreator: ICreateGeorouter, - @Inject(TIMEZONE_FINDER) - private readonly timezoneFinder: IFindTimezone, - @Inject(DIRECTION_ENCODER) - private readonly directionEncoder: IEncodeDirection, - ) { - this.defaultParams = defaultParamsProvider.getParams(); - this.georouter = georouterCreator.create( - this.defaultParams.GEOROUTER_TYPE, - this.defaultParams.GEOROUTER_URL, - ); - } - - async execute(command: CreateAdCommand): Promise { - try { - this.ad = this.mapper.map(command.createAdRequest, CreateAdRequest, Ad); - this.setTimezone(command.createAdRequest.addresses); - this.setGeography(command.createAdRequest.addresses); - this.setRoles(command.createAdRequest); - await this.geography.createRoutes(this.roles, this.georouter, { - withDistance: false, - withPoints: true, - withTime: false, - }); - this.setAdGeography(command); - this.setAdSchedule(command); - return await this.adRepository.createAd(this.ad); - } catch (error) { - throw error; - } - } - - private setTimezone = (coordinates: Coordinate[]): void => { - this.timezone = this.defaultParams.DEFAULT_TIMEZONE; - try { - const timezones = this.timezoneFinder.timezones( - coordinates[0].lon, - coordinates[0].lat, - ); - if (timezones.length > 0) this.timezone = timezones[0]; - } catch (e) {} - }; - - private setRoles = (createAdRequest: CreateAdRequest): void => { - this.roles = []; - if (createAdRequest.driver) this.roles.push(Role.DRIVER); - if (createAdRequest.passenger) this.roles.push(Role.PASSENGER); - }; - - private setGeography = (coordinates: Coordinate[]): void => { - this.geography = new Geography(coordinates); - }; - - private setAdGeography = (command: CreateAdCommand): void => { - this.ad.driverDistance = this.geography.driverRoute?.distance; - this.ad.driverDuration = this.geography.driverRoute?.duration; - this.ad.passengerDistance = this.geography.passengerRoute?.distance; - this.ad.passengerDuration = this.geography.passengerRoute?.duration; - this.ad.fwdAzimuth = this.geography.driverRoute - ? this.geography.driverRoute.fwdAzimuth - : this.geography.passengerRoute.fwdAzimuth; - this.ad.backAzimuth = this.geography.driverRoute - ? this.geography.driverRoute.backAzimuth - : this.geography.passengerRoute.backAzimuth; - this.ad.waypoints = this.directionEncoder.encode( - command.createAdRequest.addresses, - ); - this.ad.direction = this.geography.driverRoute - ? this.directionEncoder.encode(this.geography.driverRoute.points) - : undefined; - }; - - private setAdSchedule = (command: CreateAdCommand): void => { - this.ad.monTime = TimeConverter.toUtcDatetime( - this.ad.fromDate, - command.createAdRequest.monTime, - this.timezone, - ); - this.ad.tueTime = TimeConverter.toUtcDatetime( - this.ad.fromDate, - command.createAdRequest.tueTime, - this.timezone, - ); - this.ad.wedTime = TimeConverter.toUtcDatetime( - this.ad.fromDate, - command.createAdRequest.wedTime, - this.timezone, - ); - this.ad.thuTime = TimeConverter.toUtcDatetime( - this.ad.fromDate, - command.createAdRequest.thuTime, - this.timezone, - ); - this.ad.friTime = TimeConverter.toUtcDatetime( - this.ad.fromDate, - command.createAdRequest.friTime, - this.timezone, - ); - this.ad.satTime = TimeConverter.toUtcDatetime( - this.ad.fromDate, - command.createAdRequest.satTime, - this.timezone, - ); - this.ad.sunTime = TimeConverter.toUtcDatetime( - this.ad.fromDate, - command.createAdRequest.sunTime, - this.timezone, - ); - }; -} diff --git a/old/modules/ad/mappers/ad.profile.ts b/old/modules/ad/mappers/ad.profile.ts deleted file mode 100644 index bbc38d5..0000000 --- a/old/modules/ad/mappers/ad.profile.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createMap, Mapper } from '@automapper/core'; -import { AutomapperProfile, InjectMapper } from '@automapper/nestjs'; -import { Injectable } from '@nestjs/common'; -import { Ad } from '../domain/entities/ad'; -import { CreateAdRequest } from '../domain/dtos/create-ad.request'; - -@Injectable() -export class AdProfile extends AutomapperProfile { - constructor(@InjectMapper() mapper: Mapper) { - super(mapper); - } - - override get profile() { - return (mapper: any) => { - createMap(mapper, CreateAdRequest, Ad); - }; - } -} diff --git a/old/modules/ad/tests/integration/ad.repository.spec.ts b/old/modules/ad/tests/integration/ad.repository.spec.ts deleted file mode 100644 index 7df5c09..0000000 --- a/old/modules/ad/tests/integration/ad.repository.spec.ts +++ /dev/null @@ -1,402 +0,0 @@ -import { TestingModule, Test } from '@nestjs/testing'; -import { DatabaseModule } from '../../../database/database.module'; -import { PrismaService } from '../../../database/adapters/secondaries/prisma.service'; -import { AdRepository } from '../../adapters/secondaries/ad.repository'; -import { Ad } from '../../domain/entities/ad'; -import { Frequency } from '../../domain/types/frequency.enum'; - -describe('AdRepository', () => { - let prismaService: PrismaService; - let adRepository: AdRepository; - - const baseUuid = { - uuid: 'be459a29-7a41-4c0b-b371-abe90bfb6f00', - }; - const baseUserUuid = { - userUuid: '4e52b54d-a729-4dbd-9283-f84a11bb2200', - }; - const driverAd = { - driver: 'true', - passenger: 'false', - fwdAzimuth: 0, - backAzimuth: 180, - waypoints: "'LINESTRING(6 47,6.1 47.1,6.2 47.2)'", - direction: "'LINESTRING(6 47,6.05 47.05,6.1 47.1,6.15 47.15,6.2 47.2)'", - seatsDriver: 3, - seatsPassenger: 1, - seatsUsed: 0, - strict: 'false', - }; - const passengerAd = { - driver: 'false', - passenger: 'true', - fwdAzimuth: 0, - backAzimuth: 180, - waypoints: "'LINESTRING(6 47,6.2 47.2)'", - direction: "'LINESTRING(6 47,6.05 47.05,6.15 47.15,6.2 47.2)'", - seatsDriver: 3, - seatsPassenger: 1, - seatsUsed: 0, - strict: 'false', - }; - const driverAndPassengerAd = { - driver: 'true', - passenger: 'true', - fwdAzimuth: 0, - backAzimuth: 180, - waypoints: "'LINESTRING(6 47,6.1 47.1,6.2 47.2)'", - direction: "'LINESTRING(6 47,6.05 47.05,6.1 47.1,6.15 47.15,6.2 47.2)'", - seatsDriver: 3, - seatsPassenger: 1, - seatsUsed: 0, - strict: 'false', - }; - const punctualAd = { - frequency: `'PUNCTUAL'`, - fromDate: `'2023-01-01'`, - toDate: `'2023-01-01'`, - monTime: 'NULL', - tueTime: 'NULL', - wedTime: 'NULL', - thuTime: 'NULL', - friTime: 'NULL', - satTime: 'NULL', - sunTime: `'2023-01-01T07:00Z'`, - monMargin: 900, - tueMargin: 900, - wedMargin: 900, - thuMargin: 900, - friMargin: 900, - satMargin: 900, - sunMargin: 900, - }; - const recurrentAd = { - frequency: `'RECURRENT'`, - fromDate: `'2023-01-01'`, - toDate: `'2023-12-31'`, - monTime: `'2023-01-01T07:00Z'`, - tueTime: `'2023-01-01T07:00Z'`, - wedTime: `'2023-01-01T07:00Z'`, - thuTime: `'2023-01-01T07:00Z'`, - friTime: `'2023-01-01T07:00Z'`, - satTime: 'NULL', - sunTime: 'NULL', - monMargin: 900, - tueMargin: 900, - wedMargin: 900, - thuMargin: 900, - friMargin: 900, - satMargin: 900, - sunMargin: 900, - }; - - const createPunctualDriverAds = async (nbToCreate = 10) => { - const adToCreate = { - ...baseUuid, - ...baseUserUuid, - ...driverAd, - ...punctualAd, - }; - for (let i = 0; i < nbToCreate; i++) { - adToCreate.uuid = `'${baseUuid.uuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - adToCreate.userUuid = `'${baseUserUuid.userUuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - await executeInsertCommand(adToCreate); - } - }; - - const createRecurrentDriverAds = async (nbToCreate = 10) => { - const adToCreate = { - ...baseUuid, - ...baseUserUuid, - ...driverAd, - ...recurrentAd, - }; - for (let i = 0; i < nbToCreate; i++) { - adToCreate.uuid = `'${baseUuid.uuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - adToCreate.userUuid = `'${baseUserUuid.userUuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - await executeInsertCommand(adToCreate); - } - }; - - const createPunctualPassengerAds = async (nbToCreate = 10) => { - const adToCreate = { - ...baseUuid, - ...baseUserUuid, - ...passengerAd, - ...punctualAd, - }; - for (let i = 0; i < nbToCreate; i++) { - adToCreate.uuid = `'${baseUuid.uuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - adToCreate.userUuid = `'${baseUserUuid.userUuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - await executeInsertCommand(adToCreate); - } - }; - - const createRecurrentPassengerAds = async (nbToCreate = 10) => { - const adToCreate = { - ...baseUuid, - ...baseUserUuid, - ...passengerAd, - ...recurrentAd, - }; - for (let i = 0; i < nbToCreate; i++) { - adToCreate.uuid = `'${baseUuid.uuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - adToCreate.userUuid = `'${baseUserUuid.userUuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - await executeInsertCommand(adToCreate); - } - }; - - const createPunctualDriverPassengerAds = async (nbToCreate = 10) => { - const adToCreate = { - ...baseUuid, - ...baseUserUuid, - ...driverAndPassengerAd, - ...punctualAd, - }; - for (let i = 0; i < nbToCreate; i++) { - adToCreate.uuid = `'${baseUuid.uuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - adToCreate.userUuid = `'${baseUserUuid.userUuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - await executeInsertCommand(adToCreate); - } - }; - - const createRecurrentDriverPassengerAds = async (nbToCreate = 10) => { - const adToCreate = { - ...baseUuid, - ...baseUserUuid, - ...driverAndPassengerAd, - ...recurrentAd, - }; - for (let i = 0; i < nbToCreate; i++) { - adToCreate.uuid = `'${baseUuid.uuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - adToCreate.userUuid = `'${baseUserUuid.userUuid.slice(0, -2)}${i - .toString(16) - .padStart(2, '0')}'`; - await executeInsertCommand(adToCreate); - } - }; - - const executeInsertCommand = async (object: any) => { - const command = `INSERT INTO ad ("${Object.keys(object).join( - '","', - )}") VALUES (${Object.values(object).join(',')})`; - await prismaService.$executeRawUnsafe(command); - }; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [DatabaseModule], - providers: [AdRepository, PrismaService], - }).compile(); - - prismaService = module.get(PrismaService); - adRepository = module.get(AdRepository); - }); - - afterAll(async () => { - await prismaService.$disconnect(); - }); - - beforeEach(async () => { - await prismaService.ad.deleteMany(); - }); - - describe('findAll', () => { - it('should return an empty data array', async () => { - const res = await adRepository.findAll(); - expect(res).toEqual({ - data: [], - total: 0, - }); - }); - - describe('drivers', () => { - it('should return a data array with 8 punctual driver ads', async () => { - await createPunctualDriverAds(8); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(8); - expect(ads.total).toBe(8); - expect(ads.data[0].driver).toBeTruthy(); - expect(ads.data[0].passenger).toBeFalsy(); - }); - - it('should return a data array limited to 10 punctual driver ads', async () => { - await createPunctualDriverAds(20); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(10); - expect(ads.total).toBe(20); - expect(ads.data[1].driver).toBeTruthy(); - expect(ads.data[1].passenger).toBeFalsy(); - }); - - it('should return a data array with 8 recurrent driver ads', async () => { - await createRecurrentDriverAds(8); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(8); - expect(ads.total).toBe(8); - expect(ads.data[2].driver).toBeTruthy(); - expect(ads.data[2].passenger).toBeFalsy(); - }); - - it('should return a data array limited to 10 recurrent driver ads', async () => { - await createRecurrentDriverAds(20); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(10); - expect(ads.total).toBe(20); - expect(ads.data[3].driver).toBeTruthy(); - expect(ads.data[3].passenger).toBeFalsy(); - }); - }); - - describe('passengers', () => { - it('should return a data array with 7 punctual passenger ads', async () => { - await createPunctualPassengerAds(7); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(7); - expect(ads.total).toBe(7); - expect(ads.data[0].passenger).toBeTruthy(); - expect(ads.data[0].driver).toBeFalsy(); - }); - - it('should return a data array limited to 10 punctual passenger ads', async () => { - await createPunctualPassengerAds(15); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(10); - expect(ads.total).toBe(15); - expect(ads.data[1].passenger).toBeTruthy(); - expect(ads.data[1].driver).toBeFalsy(); - }); - - it('should return a data array with 7 recurrent passenger ads', async () => { - await createRecurrentPassengerAds(7); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(7); - expect(ads.total).toBe(7); - expect(ads.data[2].passenger).toBeTruthy(); - expect(ads.data[2].driver).toBeFalsy(); - }); - - it('should return a data array limited to 10 recurrent passenger ads', async () => { - await createRecurrentPassengerAds(15); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(10); - expect(ads.total).toBe(15); - expect(ads.data[3].passenger).toBeTruthy(); - expect(ads.data[3].driver).toBeFalsy(); - }); - }); - - describe('drivers and passengers', () => { - it('should return a data array with 6 punctual driver and passenger ads', async () => { - await createPunctualDriverPassengerAds(6); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(6); - expect(ads.total).toBe(6); - expect(ads.data[0].passenger).toBeTruthy(); - expect(ads.data[0].driver).toBeTruthy(); - }); - - it('should return a data array limited to 10 punctual driver and passenger ads', async () => { - await createPunctualDriverPassengerAds(16); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(10); - expect(ads.total).toBe(16); - expect(ads.data[1].passenger).toBeTruthy(); - expect(ads.data[1].driver).toBeTruthy(); - }); - - it('should return a data array with 6 recurrent driver and passenger ads', async () => { - await createRecurrentDriverPassengerAds(6); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(6); - expect(ads.total).toBe(6); - expect(ads.data[2].passenger).toBeTruthy(); - expect(ads.data[2].driver).toBeTruthy(); - }); - - it('should return a data array limited to 10 recurrent driver and passenger ads', async () => { - await createRecurrentDriverPassengerAds(16); - const ads = await adRepository.findAll(); - expect(ads.data.length).toBe(10); - expect(ads.total).toBe(16); - expect(ads.data[3].passenger).toBeTruthy(); - expect(ads.data[3].driver).toBeTruthy(); - }); - }); - }); - - describe('findOneByUuid', () => { - it('should return an ad', async () => { - await createPunctualDriverAds(1); - const ad = await adRepository.findOneByUuid(baseUuid.uuid); - expect(ad.uuid).toBe(baseUuid.uuid); - }); - - it('should return null', async () => { - const ad = await adRepository.findOneByUuid( - '544572be-11fb-4244-8235-587221fc9104', - ); - expect(ad).toBeNull(); - }); - }); - - describe('create', () => { - it('should create an ad', async () => { - const beforeCount = await prismaService.ad.count(); - - const adToCreate: Ad = new Ad(); - adToCreate.uuid = 'be459a29-7a41-4c0b-b371-abe90bfb6f00'; - adToCreate.userUuid = '4e52b54d-a729-4dbd-9283-f84a11bb2200'; - adToCreate.driver = true; - adToCreate.passenger = false; - adToCreate.fwdAzimuth = 0; - adToCreate.backAzimuth = 180; - adToCreate.waypoints = "'LINESTRING(6 47,6.1 47.1,6.2 47.2)'"; - adToCreate.direction = - "'LINESTRING(6 47,6.05 47.05,6.1 47.1,6.15 47.15,6.2 47.2)'"; - adToCreate.seatsDriver = 3; - adToCreate.seatsPassenger = 1; - adToCreate.seatsUsed = 0; - adToCreate.strict = false; - adToCreate.frequency = Frequency.PUNCTUAL; - adToCreate.fromDate = new Date(2023, 0, 1); - adToCreate.toDate = new Date(2023, 0, 1); - adToCreate.sunTime = new Date(2023, 0, 1, 6, 0, 0); - adToCreate.monMargin = 900; - adToCreate.tueMargin = 900; - adToCreate.wedMargin = 900; - adToCreate.thuMargin = 900; - adToCreate.friMargin = 900; - adToCreate.satMargin = 900; - adToCreate.sunMargin = 900; - const ad = await adRepository.createAd(adToCreate); - - const afterCount = await prismaService.ad.count(); - - expect(afterCount - beforeCount).toBe(1); - expect(ad.uuid).toBe('be459a29-7a41-4c0b-b371-abe90bfb6f00'); - }); - }); -}); diff --git a/old/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts b/old/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts deleted file mode 100644 index 5b69430..0000000 --- a/old/modules/ad/tests/unit/adapters/secondaries/default-params.provider.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ConfigService } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { DefaultParamsProvider } from '../../../../adapters/secondaries/default-params.provider'; -import { DefaultParams } from '../../../../domain/types/default-params.type'; - -const mockConfigService = { - get: jest.fn().mockImplementation(() => 'some_default_value'), -}; - -describe('DefaultParamsProvider', () => { - let defaultParamsProvider: DefaultParamsProvider; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - DefaultParamsProvider, - { - provide: ConfigService, - useValue: mockConfigService, - }, - ], - }).compile(); - - defaultParamsProvider = module.get( - DefaultParamsProvider, - ); - }); - - it('should be defined', () => { - expect(defaultParamsProvider).toBeDefined(); - }); - - it('should provide default params', async () => { - const params: DefaultParams = defaultParamsProvider.getParams(); - expect(params.GEOROUTER_URL).toBe('some_default_value'); - }); -}); diff --git a/old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts b/old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts deleted file mode 100644 index a60708f..0000000 --- a/old/modules/ad/tests/unit/adapters/secondaries/message-publisher.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { MessagePublisher } from '../../../../adapters/secondaries/message-publisher'; -import { MESSAGE_BROKER_PUBLISHER } from '../../../../../../app.constants'; - -const mockMessageBrokerPublisher = { - publish: jest.fn().mockImplementation(), -}; - -describe('Messager', () => { - let messagePublisher: MessagePublisher; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - MessagePublisher, - { - provide: MESSAGE_BROKER_PUBLISHER, - useValue: mockMessageBrokerPublisher, - }, - ], - }).compile(); - - messagePublisher = module.get(MessagePublisher); - }); - - it('should be defined', () => { - expect(messagePublisher).toBeDefined(); - }); - - it('should publish a message', async () => { - jest.spyOn(mockMessageBrokerPublisher, 'publish'); - messagePublisher.publish('ad.info', 'my-test'); - expect(mockMessageBrokerPublisher.publish).toHaveBeenCalledTimes(1); - }); -}); diff --git a/old/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts b/old/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts deleted file mode 100644 index 63d8462..0000000 --- a/old/modules/ad/tests/unit/adapters/secondaries/timezone-finder.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { TimezoneFinder } from '../../../../adapters/secondaries/timezone-finder'; -import { GeoTimezoneFinder } from '../../../../../geography/adapters/secondaries/geo-timezone-finder'; - -const mockGeoTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -describe('Timezone Finder', () => { - let timezoneFinder: TimezoneFinder; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - TimezoneFinder, - { - provide: GeoTimezoneFinder, - useValue: mockGeoTimezoneFinder, - }, - ], - }).compile(); - - timezoneFinder = module.get(TimezoneFinder); - }); - - it('should be defined', () => { - expect(timezoneFinder).toBeDefined(); - }); - it('should get timezone for Nancy(France) as Europe/Paris', () => { - const timezones = timezoneFinder.timezones(6.179373, 48.687913); - expect(timezones.length).toBe(1); - expect(timezones[0]).toBe('Europe/Paris'); - }); -}); diff --git a/old/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts b/old/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts deleted file mode 100644 index d6819c1..0000000 --- a/old/modules/ad/tests/unit/domain/create-ad.usecase.spec.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { CreateAdRequest } from '../../../domain/dtos/create-ad.request'; -import { CreateAdUseCase } from '../../../domain/usecases/create-ad.usecase'; -import { Test, TestingModule } from '@nestjs/testing'; -import { AutomapperModule } from '@automapper/nestjs'; -import { classes } from '@automapper/classes'; -import { AdRepository } from '../../../adapters/secondaries/ad.repository'; -import { CreateAdCommand } from '../../../commands/create-ad.command'; -import { Ad } from '../../../domain/entities/ad'; -import { AdProfile } from '../../../mappers/ad.profile'; -import { Frequency } from '../../../domain/types/frequency.enum'; -import { RouteType } from '../../../domain/entities/geography'; -import { DatabaseException } from '../../../../database/exceptions/database.exception'; -import { Route } from '../../../../geography/domain/entities/route'; -import { - DIRECTION_ENCODER, - GEOROUTER_CREATOR, - PARAMS_PROVIDER, - TIMEZONE_FINDER, -} from '../../../ad.constants'; - -const mockAdRepository = { - createAd: jest.fn().mockImplementation((ad) => { - if (ad.uuid == '00000000-0000-0000-0000-000000000000') - throw new DatabaseException(); - return new Ad(); - }), -}; -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(() => ({ - route: jest.fn().mockImplementation(() => [ - { - key: RouteType.DRIVER, - route: { - points: [], - fwdAzimuth: 0, - backAzimuth: 180, - distance: 20000, - duration: 1800, - }, - }, - { - key: RouteType.PASSENGER, - route: { - points: [], - fwdAzimuth: 0, - backAzimuth: 180, - distance: 20000, - duration: 1800, - }, - }, - { - key: RouteType.COMMON, - route: { - points: [], - fwdAzimuth: 0, - backAzimuth: 180, - distance: 20000, - duration: 1800, - }, - }, - ]), - })), -}; -const mockParamsProvider = { - getParams: jest.fn().mockImplementation(() => ({ - DEFAULT_TIMEZONE: 'Europe/Paris', - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'localhost', - })), -}; -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; -const mockDirectionEncoder = { - encode: jest.fn(), -}; - -const createAdRequest: CreateAdRequest = { - uuid: '77c55dfc-c28b-4026-942e-f94e95401fb1', - userUuid: 'dfd993f6-7889-4876-9570-5e1d7b6e3f42', - driver: true, - passenger: false, - frequency: Frequency.RECURRENT, - fromDate: new Date('2023-04-26'), - toDate: new Date('2024-04-25'), - monTime: '07:00', - tueTime: '07:00', - wedTime: '07:00', - thuTime: '07:00', - friTime: '07:00', - satTime: null, - sunTime: null, - monMargin: 900, - tueMargin: 900, - wedMargin: 900, - thuMargin: 900, - friMargin: 900, - satMargin: 900, - sunMargin: 900, - seatsDriver: 3, - seatsPassenger: 1, - strict: false, - addresses: [ - { lon: 6, lat: 45 }, - { lon: 6.5, lat: 45.5 }, - ], -}; - -const setUuid = async (uuid: string): Promise => { - createAdRequest.uuid = uuid; -}; - -const setIsDriver = async (isDriver: boolean): Promise => { - createAdRequest.driver = isDriver; -}; - -const setIsPassenger = async (isPassenger: boolean): Promise => { - createAdRequest.passenger = isPassenger; -}; - -describe('CreateAdUseCase', () => { - let createAdUseCase: CreateAdUseCase; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })], - providers: [ - { - provide: AdRepository, - useValue: mockAdRepository, - }, - { - provide: GEOROUTER_CREATOR, - useValue: mockGeorouterCreator, - }, - { - provide: PARAMS_PROVIDER, - useValue: mockParamsProvider, - }, - { - provide: TIMEZONE_FINDER, - useValue: mockTimezoneFinder, - }, - { - provide: DIRECTION_ENCODER, - useValue: mockDirectionEncoder, - }, - AdProfile, - CreateAdUseCase, - ], - }).compile(); - - createAdUseCase = module.get(CreateAdUseCase); - }); - - it('should be defined', () => { - expect(createAdUseCase).toBeDefined(); - }); - - describe('execute', () => { - it('should create an ad as driver', async () => { - const ad = await createAdUseCase.execute( - new CreateAdCommand(createAdRequest), - ); - expect(ad).toBeInstanceOf(Ad); - }); - it('should create an ad as passenger', async () => { - await setIsDriver(false); - await setIsPassenger(true); - const ad = await createAdUseCase.execute( - new CreateAdCommand(createAdRequest), - ); - expect(ad).toBeInstanceOf(Ad); - }); - it('should throw an exception if repository fails', async () => { - await setUuid('00000000-0000-0000-0000-000000000000'); - await expect( - createAdUseCase.execute(new CreateAdCommand(createAdRequest)), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); -}); diff --git a/old/modules/ad/tests/unit/domain/geography.spec.ts b/old/modules/ad/tests/unit/domain/geography.spec.ts deleted file mode 100644 index bf3de17..0000000 --- a/old/modules/ad/tests/unit/domain/geography.spec.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { Role } from '../../../domain/types/role.enum'; -import { Geography } from '../../../domain/entities/geography'; -import { Coordinate } from '../../../../geography/domain/entities/coordinate'; -import { IGeorouter } from '../../../../geography/domain/interfaces/georouter.interface'; -import { GeorouterSettings } from '../../../../geography/domain/types/georouter-settings.type'; -import { Route } from '../../../../geography/domain/entities/route'; -import { IGeodesic } from '../../../../geography/domain/interfaces/geodesic.interface'; - -const simpleCoordinates: Coordinate[] = [ - { - lon: 6, - lat: 47, - }, - { - lon: 6.1, - lat: 47.1, - }, -]; - -const complexCoordinates: Coordinate[] = [ - { - lon: 6, - lat: 47, - }, - { - lon: 6.1, - lat: 47.1, - }, - { - lon: 6.2, - lat: 47.2, - }, -]; - -const mockGeodesic: IGeodesic = { - inverse: jest.fn(), -}; - -const driverRoute: Route = new Route(mockGeodesic); -driverRoute.distance = 25000; - -const commonRoute: Route = new Route(mockGeodesic); -commonRoute.distance = 20000; - -const mockGeorouter: IGeorouter = { - route: jest - .fn() - .mockResolvedValueOnce([ - { - key: 'driver', - route: driverRoute, - }, - ]) - .mockResolvedValueOnce([ - { - key: 'passenger', - route: commonRoute, - }, - ]) - .mockResolvedValueOnce([ - { - key: 'common', - route: commonRoute, - }, - ]) - .mockResolvedValueOnce([ - { - key: 'driver', - route: driverRoute, - }, - { - key: 'passenger', - route: commonRoute, - }, - ]), -}; - -const georouterSettings: GeorouterSettings = { - withDistance: false, - withPoints: true, - withTime: false, -}; - -describe('Geography entity', () => { - it('should be defined', () => { - expect(new Geography(simpleCoordinates)).toBeDefined(); - }); - - it('should create a route as driver', async () => { - const geography = new Geography(complexCoordinates); - await geography.createRoutes( - [Role.DRIVER], - mockGeorouter, - georouterSettings, - ); - expect(geography.driverRoute).toBeDefined(); - expect(geography.passengerRoute).toBeUndefined(); - expect(geography.driverRoute.distance).toBe(25000); - }); - - it('should create a route as passenger', async () => { - const geography = new Geography(simpleCoordinates); - await geography.createRoutes( - [Role.PASSENGER], - mockGeorouter, - georouterSettings, - ); - expect(geography.driverRoute).toBeUndefined(); - expect(geography.passengerRoute).toBeDefined(); - expect(geography.passengerRoute.distance).toBe(20000); - }); - - it('should create routes as driver and passenger with simple coordinates', async () => { - const geography = new Geography(simpleCoordinates); - await geography.createRoutes( - [Role.DRIVER, Role.PASSENGER], - mockGeorouter, - georouterSettings, - ); - expect(geography.driverRoute).toBeDefined(); - expect(geography.passengerRoute).toBeDefined(); - expect(geography.driverRoute.distance).toBe(20000); - expect(geography.passengerRoute.distance).toBe(20000); - }); - - it('should create routes as driver and passenger with complex coordinates', async () => { - const geography = new Geography(complexCoordinates); - await geography.createRoutes( - [Role.DRIVER, Role.PASSENGER], - mockGeorouter, - georouterSettings, - ); - expect(geography.driverRoute).toBeDefined(); - expect(geography.passengerRoute).toBeDefined(); - expect(geography.driverRoute.distance).toBe(25000); - expect(geography.passengerRoute.distance).toBe(20000); - }); -}); diff --git a/old/modules/ad/tests/unit/domain/time-converter.spec.ts b/old/modules/ad/tests/unit/domain/time-converter.spec.ts deleted file mode 100644 index 9c4113d..0000000 --- a/old/modules/ad/tests/unit/domain/time-converter.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { TimeConverter } from '../../../domain/entities/time-converter'; - -describe('TimeConverter', () => { - it('should be defined', () => { - expect(new TimeConverter()).toBeDefined(); - }); - - it('should convert a Europe/Paris datetime to utc datetime', () => { - expect( - TimeConverter.toUtcDatetime( - new Date('2023-05-01'), - '07:00', - 'Europe/Paris', - ).getUTCHours(), - ).toBe(6); - }); - - it('should return undefined when trying to convert a Europe/Paris datetime to utc datetime without a valid date', () => { - expect( - TimeConverter.toUtcDatetime(undefined, '07:00', 'Europe/Paris'), - ).toBeUndefined(); - expect( - TimeConverter.toUtcDatetime( - new Date('2023-13-01'), - '07:00', - 'Europe/Paris', - ), - ).toBeUndefined(); - }); - - it('should return undefined when trying to convert a Europe/Paris datetime to utc datetime without a valid time', () => { - expect( - TimeConverter.toUtcDatetime( - new Date('2023-05-01'), - undefined, - 'Europe/Paris', - ), - ).toBeUndefined(); - expect( - TimeConverter.toUtcDatetime(new Date('2023-05-01'), 'a', 'Europe/Paris'), - ).toBeUndefined(); - }); - - it('should return undefined when trying to convert a datetime to utc datetime without a valid timezone', () => { - expect( - TimeConverter.toUtcDatetime( - new Date('2023-12-01'), - '07:00', - 'OlympusMons/Mars', - ), - ).toBeUndefined(); - }); -}); diff --git a/old/modules/database/adapters/secondaries/prisma.repository.abstract.ts b/old/modules/database/adapters/secondaries/prisma.repository.abstract.ts deleted file mode 100644 index 1ab4b67..0000000 --- a/old/modules/database/adapters/secondaries/prisma.repository.abstract.ts +++ /dev/null @@ -1,259 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { Prisma } from '@prisma/client'; -import { DatabaseException } from '../../exceptions/database.exception'; -import { ICollection } from '../../interfaces/collection.interface'; -import { IRepository } from '../../interfaces/repository.interface'; -import { PrismaService } from './prisma.service'; - -/** - * Child classes MUST redefined model property with appropriate model name - */ -@Injectable() -export abstract class PrismaRepository implements IRepository { - protected model: string; - - constructor(protected readonly prisma: PrismaService) {} - - findAll = async ( - page = 1, - perPage = 10, - where?: any, - include?: any, - ): Promise> => { - const [data, total] = await this.prisma.$transaction([ - this.prisma[this.model].findMany({ - where, - include, - skip: (page - 1) * perPage, - take: perPage, - }), - this.prisma[this.model].count({ - where, - }), - ]); - return Promise.resolve({ - data, - total, - }); - }; - - findOneByUuid = async (uuid: string): Promise => { - try { - const entity = await this.prisma[this.model].findUnique({ - where: { uuid }, - }); - - return entity; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; - - findOne = async (where: any, include?: any): Promise => { - try { - const entity = await this.prisma[this.model].findFirst({ - where: where, - include: include, - }); - - return entity; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - ); - } else { - throw new DatabaseException(); - } - } - }; - - // TODO : using any is not good, but needed for nested entities - // TODO : Refactor for good clean architecture ? - async create(entity: Partial | any, include?: any): Promise { - try { - const res = await this.prisma[this.model].create({ - data: entity, - include: include, - }); - - return res; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - } - - update = async (uuid: string, entity: Partial): Promise => { - try { - const updatedEntity = await this.prisma[this.model].update({ - where: { uuid }, - data: entity, - }); - return updatedEntity; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; - - updateWhere = async ( - where: any, - entity: Partial | any, - include?: any, - ): Promise => { - try { - const updatedEntity = await this.prisma[this.model].update({ - where: where, - data: entity, - include: include, - }); - - return updatedEntity; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; - - delete = async (uuid: string): Promise => { - try { - const entity = await this.prisma[this.model].delete({ - where: { uuid }, - }); - - return entity; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; - - deleteMany = async (where: any): Promise => { - try { - const entity = await this.prisma[this.model].deleteMany({ - where: where, - }); - - return entity; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; - - findAllByQuery = async ( - include: string[], - where: string[], - ): Promise> => { - const query = `SELECT ${include.join(',')} FROM ${ - this.model - } WHERE ${where.join(' AND ')}`; - const data: T[] = await this.prisma.$queryRawUnsafe(query); - return Promise.resolve({ - data, - total: data.length, - }); - }; - - createWithFields = async (fields: object): Promise => { - try { - const command = `INSERT INTO ${this.model} ("${Object.keys(fields).join( - '","', - )}") VALUES (${Object.values(fields).join(',')})`; - return await this.prisma.$executeRawUnsafe(command); - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; - - updateWithFields = async (uuid: string, entity: object): Promise => { - entity['"updatedAt"'] = `to_timestamp(${Date.now()} / 1000.0)`; - const values = Object.keys(entity).map((key) => `${key} = ${entity[key]}`); - try { - const command = `UPDATE ${this.model} SET ${values.join( - ', ', - )} WHERE uuid = '${uuid}'`; - return await this.prisma.$executeRawUnsafe(command); - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; - - healthCheck = async (): Promise => { - try { - await this.prisma.$queryRaw`SELECT 1`; - return true; - } catch (e) { - if (e instanceof Prisma.PrismaClientKnownRequestError) { - throw new DatabaseException( - Prisma.PrismaClientKnownRequestError.name, - e.code, - e.message, - ); - } else { - throw new DatabaseException(); - } - } - }; -} diff --git a/old/modules/database/adapters/secondaries/prisma.service.ts b/old/modules/database/adapters/secondaries/prisma.service.ts deleted file mode 100644 index edf6532..0000000 --- a/old/modules/database/adapters/secondaries/prisma.service.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common'; -import { PrismaClient } from '@prisma/client'; - -@Injectable() -export class PrismaService extends PrismaClient implements OnModuleInit { - async onModuleInit() { - await this.$connect(); - } - - async enableShutdownHooks(app: INestApplication) { - this.$on('beforeExit', async () => { - await app.close(); - }); - } -} diff --git a/old/modules/database/database.module.ts b/old/modules/database/database.module.ts deleted file mode 100644 index f98fa94..0000000 --- a/old/modules/database/database.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { PrismaService } from './adapters/secondaries/prisma.service'; - -@Module({ - providers: [PrismaService], - exports: [PrismaService], -}) -export class DatabaseModule {} diff --git a/old/modules/database/domain/database.repository.ts b/old/modules/database/domain/database.repository.ts deleted file mode 100644 index 83f17e7..0000000 --- a/old/modules/database/domain/database.repository.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { PrismaRepository } from '../adapters/secondaries/prisma.repository.abstract'; - -export class DatabaseRepository extends PrismaRepository {} diff --git a/old/modules/database/exceptions/database.exception.ts b/old/modules/database/exceptions/database.exception.ts deleted file mode 100644 index b0782a6..0000000 --- a/old/modules/database/exceptions/database.exception.ts +++ /dev/null @@ -1,24 +0,0 @@ -export class DatabaseException implements Error { - name: string; - message: string; - - constructor( - private _type: string = 'unknown', - private _code: string = '', - message?: string, - ) { - this.name = 'DatabaseException'; - this.message = message ?? 'An error occured with the database.'; - if (this.message.includes('Unique constraint failed')) { - this.message = 'Already exists.'; - } - } - - get type(): string { - return this._type; - } - - get code(): string { - return this._code; - } -} diff --git a/old/modules/database/interfaces/collection.interface.ts b/old/modules/database/interfaces/collection.interface.ts deleted file mode 100644 index 6e9a96d..0000000 --- a/old/modules/database/interfaces/collection.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface ICollection { - data: T[]; - total: number; -} diff --git a/old/modules/database/interfaces/repository.interface.ts b/old/modules/database/interfaces/repository.interface.ts deleted file mode 100644 index 1e23984..0000000 --- a/old/modules/database/interfaces/repository.interface.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ICollection } from './collection.interface'; - -export interface IRepository { - findAll( - page: number, - perPage: number, - params?: any, - include?: any, - ): Promise>; - findOne(where: any, include?: any): Promise; - findOneByUuid(uuid: string, include?: any): Promise; - create(entity: Partial | any, include?: any): Promise; - update(uuid: string, entity: Partial, include?: any): Promise; - updateWhere(where: any, entity: Partial | any, include?: any): Promise; - delete(uuid: string): Promise; - deleteMany(where: any): Promise; - healthCheck(): Promise; -} diff --git a/old/modules/database/tests/unit/prisma-repository.spec.ts b/old/modules/database/tests/unit/prisma-repository.spec.ts deleted file mode 100644 index d27b1fe..0000000 --- a/old/modules/database/tests/unit/prisma-repository.spec.ts +++ /dev/null @@ -1,571 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { Test, TestingModule } from '@nestjs/testing'; -import { PrismaService } from '../../adapters/secondaries/prisma.service'; -import { PrismaRepository } from '../../adapters/secondaries/prisma.repository.abstract'; -import { DatabaseException } from '../../exceptions/database.exception'; -import { Prisma } from '@prisma/client'; - -class FakeEntity { - uuid?: string; - name: string; -} - -let entityId = 2; -const entityUuid = 'uuid-'; -const entityName = 'name-'; - -const createRandomEntity = (): FakeEntity => { - const entity: FakeEntity = { - uuid: `${entityUuid}${entityId}`, - name: `${entityName}${entityId}`, - }; - - entityId++; - - return entity; -}; - -const fakeEntityToCreate: FakeEntity = { - name: 'test', -}; - -const fakeEntityCreated: FakeEntity = { - ...fakeEntityToCreate, - uuid: 'some-uuid', -}; - -const fakeEntities: FakeEntity[] = []; -Array.from({ length: 10 }).forEach(() => { - fakeEntities.push(createRandomEntity()); -}); - -@Injectable() -class FakePrismaRepository extends PrismaRepository { - protected model = 'fake'; -} - -class FakePrismaService extends PrismaService { - fake: any; -} - -const mockPrismaService = { - $transaction: jest.fn().mockImplementation(async (data: any) => { - const entities = await data[0]; - if (entities.length == 1) { - return Promise.resolve([[fakeEntityCreated], 1]); - } - - return Promise.resolve([fakeEntities, fakeEntities.length]); - }), - // eslint-disable-next-line @typescript-eslint/no-unused-vars - $queryRawUnsafe: jest.fn().mockImplementation((query?: string) => { - return Promise.resolve(fakeEntities); - }), - $executeRawUnsafe: jest - .fn() - .mockResolvedValueOnce(fakeEntityCreated) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((fields: object) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((fields: object) => { - throw new Error('an unknown error'); - }) - .mockResolvedValueOnce(fakeEntityCreated) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((fields: object) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((fields: object) => { - throw new Error('an unknown error'); - }), - $queryRaw: jest - .fn() - .mockImplementationOnce(() => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - .mockImplementationOnce(() => { - return true; - }) - .mockImplementation(() => { - throw new Prisma.PrismaClientKnownRequestError('Database unavailable', { - code: 'code', - clientVersion: 'version', - }); - }), - fake: { - create: jest - .fn() - .mockResolvedValueOnce(fakeEntityCreated) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Error('an unknown error'); - }), - - findMany: jest.fn().mockImplementation((params?: any) => { - if (params?.where?.limit == 1) { - return Promise.resolve([fakeEntityCreated]); - } - - return Promise.resolve(fakeEntities); - }), - count: jest.fn().mockResolvedValue(fakeEntities.length), - - findUnique: jest.fn().mockImplementation(async (params?: any) => { - let entity; - - if (params?.where?.uuid) { - entity = fakeEntities.find( - (entity) => entity.uuid === params?.where?.uuid, - ); - } - - if (!entity && params?.where?.uuid == 'unknown') { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - } else if (!entity) { - throw new Error('no entity'); - } - - return entity; - }), - - findFirst: jest - .fn() - .mockImplementationOnce((params?: any) => { - if (params?.where?.name) { - return Promise.resolve( - fakeEntities.find((entity) => entity.name === params?.where?.name), - ); - } - }) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Error('an unknown error'); - }), - - update: jest - .fn() - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - .mockImplementationOnce((params: any) => { - const entity = fakeEntities.find( - (entity) => entity.name === params.where.name, - ); - Object.entries(params.data).map(([key, value]) => { - entity[key] = value; - }); - - return Promise.resolve(entity); - }) - .mockImplementation((params: any) => { - const entity = fakeEntities.find( - (entity) => entity.uuid === params.where.uuid, - ); - Object.entries(params.data).map(([key, value]) => { - entity[key] = value; - }); - - return Promise.resolve(entity); - }), - - delete: jest - .fn() - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - .mockImplementation((params: any) => { - let found = false; - - fakeEntities.forEach((entity, index) => { - if (entity.uuid === params?.where?.uuid) { - found = true; - fakeEntities.splice(index, 1); - } - }); - - if (!found) { - throw new Error(); - } - }), - - deleteMany: jest - .fn() - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .mockImplementationOnce((params?: any) => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) - .mockImplementation((params: any) => { - let found = false; - - fakeEntities.forEach((entity, index) => { - if (entity.uuid === params?.where?.uuid) { - found = true; - fakeEntities.splice(index, 1); - } - }); - - if (!found) { - throw new Error(); - } - }), - }, -}; - -describe('PrismaRepository', () => { - let fakeRepository: FakePrismaRepository; - let prisma: FakePrismaService; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - FakePrismaRepository, - { - provide: PrismaService, - useValue: mockPrismaService, - }, - ], - }).compile(); - - fakeRepository = module.get(FakePrismaRepository); - prisma = module.get(PrismaService) as FakePrismaService; - }); - - it('should be defined', () => { - expect(fakeRepository).toBeDefined(); - expect(prisma).toBeDefined(); - }); - - describe('findAll', () => { - it('should return an array of entities', async () => { - jest.spyOn(prisma.fake, 'findMany'); - jest.spyOn(prisma.fake, 'count'); - jest.spyOn(prisma, '$transaction'); - - const entities = await fakeRepository.findAll(); - expect(entities).toStrictEqual({ - data: fakeEntities, - total: fakeEntities.length, - }); - }); - - it('should return an array containing only one entity', async () => { - const entities = await fakeRepository.findAll(1, 10, { limit: 1 }); - - expect(prisma.fake.findMany).toHaveBeenCalledWith({ - skip: 0, - take: 10, - where: { limit: 1 }, - }); - expect(entities).toEqual({ - data: [fakeEntityCreated], - total: 1, - }); - }); - }); - - describe('create', () => { - it('should create an entity', async () => { - jest.spyOn(prisma.fake, 'create'); - - const newEntity = await fakeRepository.create(fakeEntityToCreate); - expect(newEntity).toBe(fakeEntityCreated); - expect(prisma.fake.create).toHaveBeenCalledTimes(1); - }); - - it('should throw a DatabaseException for client error', async () => { - await expect( - fakeRepository.create(fakeEntityToCreate), - ).rejects.toBeInstanceOf(DatabaseException); - }); - - it('should throw a DatabaseException if uuid is not found', async () => { - await expect( - fakeRepository.create(fakeEntityToCreate), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); - - describe('findOneByUuid', () => { - it('should find an entity by uuid', async () => { - const entity = await fakeRepository.findOneByUuid(fakeEntities[0].uuid); - expect(entity).toBe(fakeEntities[0]); - }); - - it('should throw a DatabaseException for client error', async () => { - await expect( - fakeRepository.findOneByUuid('unknown'), - ).rejects.toBeInstanceOf(DatabaseException); - }); - - it('should throw a DatabaseException if uuid is not found', async () => { - await expect( - fakeRepository.findOneByUuid('wrong-uuid'), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); - - describe('findOne', () => { - it('should find one entity', async () => { - const entity = await fakeRepository.findOne({ - name: fakeEntities[0].name, - }); - - expect(entity.name).toBe(fakeEntities[0].name); - }); - - it('should throw a DatabaseException for client error', async () => { - await expect( - fakeRepository.findOne({ - name: fakeEntities[0].name, - }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - - it('should throw a DatabaseException for unknown error', async () => { - await expect( - fakeRepository.findOne({ - name: fakeEntities[0].name, - }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); - - describe('update', () => { - it('should throw a DatabaseException for client error', async () => { - await expect( - fakeRepository.update('fake-uuid', { name: 'error' }), - ).rejects.toBeInstanceOf(DatabaseException); - await expect( - fakeRepository.updateWhere({ name: 'error' }, { name: 'new error' }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - - it('should update an entity with name', async () => { - const newName = 'new-random-name'; - - await fakeRepository.updateWhere( - { name: fakeEntities[0].name }, - { - name: newName, - }, - ); - expect(fakeEntities[0].name).toBe(newName); - }); - - it('should update an entity with uuid', async () => { - const newName = 'random-name'; - - await fakeRepository.update(fakeEntities[0].uuid, { - name: newName, - }); - expect(fakeEntities[0].name).toBe(newName); - }); - - it("should throw an exception if an entity doesn't exist", async () => { - await expect( - fakeRepository.update('fake-uuid', { name: 'error' }), - ).rejects.toBeInstanceOf(DatabaseException); - await expect( - fakeRepository.updateWhere({ name: 'error' }, { name: 'new error' }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); - - describe('delete', () => { - it('should throw a DatabaseException for client error', async () => { - await expect(fakeRepository.delete('fake-uuid')).rejects.toBeInstanceOf( - DatabaseException, - ); - }); - - it('should delete an entity', async () => { - const savedUuid = fakeEntities[0].uuid; - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const res = await fakeRepository.delete(savedUuid); - - const deletedEntity = fakeEntities.find( - (entity) => entity.uuid === savedUuid, - ); - expect(deletedEntity).toBeUndefined(); - }); - - it("should throw an exception if an entity doesn't exist", async () => { - await expect(fakeRepository.delete('fake-uuid')).rejects.toBeInstanceOf( - DatabaseException, - ); - }); - }); - - describe('deleteMany', () => { - it('should throw a DatabaseException for client error', async () => { - await expect( - fakeRepository.deleteMany({ uuid: 'fake-uuid' }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - - it('should delete entities based on their uuid', async () => { - const savedUuid = fakeEntities[0].uuid; - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const res = await fakeRepository.deleteMany({ uuid: savedUuid }); - - const deletedEntity = fakeEntities.find( - (entity) => entity.uuid === savedUuid, - ); - expect(deletedEntity).toBeUndefined(); - }); - - it("should throw an exception if an entity doesn't exist", async () => { - await expect( - fakeRepository.deleteMany({ uuid: 'fake-uuid' }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); - - describe('findAllByquery', () => { - it('should return an array of entities', async () => { - const entities = await fakeRepository.findAllByQuery( - ['uuid', 'name'], - ['name is not null'], - ); - expect(entities).toStrictEqual({ - data: fakeEntities, - total: fakeEntities.length, - }); - }); - }); - - describe('createWithFields', () => { - it('should create an entity', async () => { - jest.spyOn(prisma, '$queryRawUnsafe'); - - const newEntity = await fakeRepository.createWithFields({ - uuid: '804319b3-a09b-4491-9f82-7976bfce0aff', - name: 'my-name', - }); - expect(newEntity).toBe(fakeEntityCreated); - expect(prisma.$queryRawUnsafe).toHaveBeenCalledTimes(1); - }); - - it('should throw a DatabaseException for client error', async () => { - await expect( - fakeRepository.createWithFields({ - uuid: '804319b3-a09b-4491-9f82-7976bfce0aff', - name: 'my-name', - }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - - it('should throw a DatabaseException if uuid is not found', async () => { - await expect( - fakeRepository.createWithFields({ - name: 'my-name', - }), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); - - describe('updateWithFields', () => { - it('should update an entity', async () => { - jest.spyOn(prisma, '$queryRawUnsafe'); - - const updatedEntity = await fakeRepository.updateWithFields( - '804319b3-a09b-4491-9f82-7976bfce0aff', - { - name: 'my-name', - }, - ); - expect(updatedEntity).toBe(fakeEntityCreated); - expect(prisma.$queryRawUnsafe).toHaveBeenCalledTimes(1); - }); - - it('should throw a DatabaseException for client error', async () => { - await expect( - fakeRepository.updateWithFields( - '804319b3-a09b-4491-9f82-7976bfce0aff', - { - name: 'my-name', - }, - ), - ).rejects.toBeInstanceOf(DatabaseException); - }); - - it('should throw a DatabaseException if uuid is not found', async () => { - await expect( - fakeRepository.updateWithFields( - '804319b3-a09b-4491-9f82-7976bfce0aff', - { - name: 'my-name', - }, - ), - ).rejects.toBeInstanceOf(DatabaseException); - }); - }); - - describe('healthCheck', () => { - it('should throw a DatabaseException for client error', async () => { - await expect(fakeRepository.healthCheck()).rejects.toBeInstanceOf( - DatabaseException, - ); - }); - - it('should return a healthy result', async () => { - const res = await fakeRepository.healthCheck(); - expect(res).toBeTruthy(); - }); - - it('should throw an exception if database is not available', async () => { - await expect(fakeRepository.healthCheck()).rejects.toBeInstanceOf( - DatabaseException, - ); - }); - }); -}); diff --git a/old/modules/geography/adapters/secondaries/geo-timezone-finder.ts b/old/modules/geography/adapters/secondaries/geo-timezone-finder.ts deleted file mode 100644 index bce0097..0000000 --- a/old/modules/geography/adapters/secondaries/geo-timezone-finder.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { IFindTimezone } from '../../domain/interfaces/timezone-finder.interface'; -import { find } from 'geo-tz'; - -@Injectable() -export class GeoTimezoneFinder implements IFindTimezone { - timezones = (lon: number, lat: number): string[] => find(lat, lon); -} diff --git a/old/modules/geography/adapters/secondaries/geodesic.ts b/old/modules/geography/adapters/secondaries/geodesic.ts deleted file mode 100644 index 835df8e..0000000 --- a/old/modules/geography/adapters/secondaries/geodesic.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { Geodesic as Geolib, GeodesicClass } from 'geographiclib-geodesic'; -import { IGeodesic } from '../../domain/interfaces/geodesic.interface'; - -@Injectable() -export class Geodesic implements IGeodesic { - private geod: GeodesicClass; - - constructor() { - this.geod = Geolib.WGS84; - } - - inverse = ( - lon1: number, - lat1: number, - lon2: number, - lat2: number, - ): { azimuth: number; distance: number } => { - const { azi2: azimuth, s12: distance } = this.geod.Inverse( - lat1, - lon1, - lat2, - lon2, - ); - return { azimuth, distance }; - }; -} diff --git a/old/modules/geography/adapters/secondaries/georouter-creator.ts b/old/modules/geography/adapters/secondaries/georouter-creator.ts deleted file mode 100644 index 69b5a35..0000000 --- a/old/modules/geography/adapters/secondaries/georouter-creator.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { ICreateGeorouter } from '../../domain/interfaces/georouter-creator.interface'; -import { IGeorouter } from '../../domain/interfaces/georouter.interface'; -import { GraphhopperGeorouter } from './graphhopper-georouter'; -import { HttpService } from '@nestjs/axios'; -import { Geodesic } from './geodesic'; -import { GeographyException } from '../../exceptions/geography.exception'; -import { ExceptionCode } from '../../../utils/exception-code.enum'; - -@Injectable() -export class GeorouterCreator implements ICreateGeorouter { - constructor( - private readonly httpService: HttpService, - private readonly geodesic: Geodesic, - ) {} - - create = (type: string, url: string): IGeorouter => { - switch (type) { - case 'graphhopper': - return new GraphhopperGeorouter(url, this.httpService, this.geodesic); - default: - throw new GeographyException( - ExceptionCode.INVALID_ARGUMENT, - 'Unknown geocoder', - ); - } - }; -} diff --git a/old/modules/geography/adapters/secondaries/graphhopper-georouter.ts b/old/modules/geography/adapters/secondaries/graphhopper-georouter.ts deleted file mode 100644 index 42087c4..0000000 --- a/old/modules/geography/adapters/secondaries/graphhopper-georouter.ts +++ /dev/null @@ -1,330 +0,0 @@ -import { HttpService } from '@nestjs/axios'; -import { IGeorouter } from '../../domain/interfaces/georouter.interface'; -import { Injectable } from '@nestjs/common'; -import { catchError, lastValueFrom, map } from 'rxjs'; -import { AxiosError, AxiosResponse } from 'axios'; -import { IGeodesic } from '../../domain/interfaces/geodesic.interface'; -import { GeorouterSettings } from '../../domain/types/georouter-settings.type'; -import { Path } from '../../domain/types/path.type'; -import { NamedRoute } from '../../domain/types/named-route'; -import { GeographyException } from '../../exceptions/geography.exception'; -import { ExceptionCode } from '../../../utils/exception-code.enum'; -import { Route } from '../../domain/entities/route'; -import { SpacetimePoint } from '../../domain/entities/spacetime-point'; - -@Injectable() -export class GraphhopperGeorouter implements IGeorouter { - private url: string; - private urlArgs: string[]; - private withTime: boolean; - private withPoints: boolean; - private withDistance: boolean; - private paths: Path[]; - private httpService: HttpService; - private geodesic: IGeodesic; - - constructor(url: string, httpService: HttpService, geodesic: IGeodesic) { - this.url = url + '/route?'; - this.httpService = httpService; - this.geodesic = geodesic; - } - - route = async ( - paths: Path[], - settings: GeorouterSettings, - ): Promise => { - this.setDefaultUrlArgs(); - this.setWithTime(settings.withTime); - this.setWithPoints(settings.withPoints); - this.setWithDistance(settings.withDistance); - this.paths = paths; - return await this.getRoutes(); - }; - - private setDefaultUrlArgs = (): void => { - this.urlArgs = ['vehicle=car', 'weighting=fastest', 'points_encoded=false']; - }; - - private setWithTime = (withTime: boolean): void => { - this.withTime = withTime; - if (withTime) { - this.urlArgs.push('details=time'); - } - }; - - private setWithPoints = (withPoints: boolean): void => { - this.withPoints = withPoints; - if (!withPoints) { - this.urlArgs.push('calc_points=false'); - } - }; - - private setWithDistance = (withDistance: boolean): void => { - this.withDistance = withDistance; - if (withDistance) { - this.urlArgs.push('instructions=true'); - } else { - this.urlArgs.push('instructions=false'); - } - }; - - private getRoutes = async (): Promise => { - const routes = Promise.all( - this.paths.map(async (path) => { - const url: string = [ - this.getUrl(), - '&point=', - path.points - .map((point) => [point.lat, point.lon].join('%2C')) - .join('&point='), - ].join(''); - const route = await lastValueFrom( - this.httpService.get(url).pipe( - map((res) => (res.data ? this.createRoute(res) : undefined)), - catchError((error: AxiosError) => { - if (error.code == AxiosError.ERR_BAD_REQUEST) { - throw new GeographyException( - ExceptionCode.OUT_OF_RANGE, - 'No route found for given coordinates', - ); - } - throw new GeographyException( - ExceptionCode.UNAVAILABLE, - 'Georouter unavailable : ' + error.message, - ); - }), - ), - ); - return { - key: path.key, - route, - }; - }), - ); - return routes; - }; - - private getUrl = (): string => { - return [this.url, this.urlArgs.join('&')].join(''); - }; - - private createRoute = ( - response: AxiosResponse, - ): Route => { - const route = new Route(this.geodesic); - if (response.data.paths && response.data.paths[0]) { - const shortestPath = response.data.paths[0]; - route.distance = shortestPath.distance ?? 0; - route.duration = shortestPath.time ? shortestPath.time / 1000 : 0; - if (shortestPath.points && shortestPath.points.coordinates) { - route.setPoints( - shortestPath.points.coordinates.map((coordinate) => ({ - lon: coordinate[0], - lat: coordinate[1], - })), - ); - if ( - shortestPath.details && - shortestPath.details.time && - shortestPath.snapped_waypoints && - shortestPath.snapped_waypoints.coordinates - ) { - let instructions: GraphhopperInstruction[] = []; - if (shortestPath.instructions) - instructions = shortestPath.instructions; - route.setSpacetimePoints( - this.generateSpacetimePoints( - shortestPath.points.coordinates, - shortestPath.snapped_waypoints.coordinates, - shortestPath.details.time, - instructions, - ), - ); - } - } - } - return route; - }; - - private generateSpacetimePoints = ( - points: Array, - snappedWaypoints: Array, - durations: Array, - instructions: GraphhopperInstruction[], - ): SpacetimePoint[] => { - const indices = this.getIndices(points, snappedWaypoints); - const times = this.getTimes(durations, indices); - const distances = this.getDistances(instructions, indices); - return indices.map( - (index) => - new SpacetimePoint( - { lon: points[index][1], lat: points[index][0] }, - times.find((time) => time.index == index)?.duration, - distances.find((distance) => distance.index == index)?.distance, - ), - ); - }; - - private getIndices = ( - points: Array, - snappedWaypoints: Array, - ): number[] => { - const indices = snappedWaypoints.map((waypoint) => - points.findIndex( - (point) => point[0] == waypoint[0] && point[1] == waypoint[1], - ), - ); - if (indices.find((index) => index == -1) === undefined) return indices; - const missedWaypoints = indices - .map( - (value, index) => - < - { - index: number; - originIndex: number; - waypoint: number[]; - nearest: number; - distance: number; - } - >{ - index: value, - originIndex: index, - waypoint: snappedWaypoints[index], - nearest: undefined, - distance: 999999999, - }, - ) - .filter((element) => element.index == -1); - for (const index in points) { - for (const missedWaypoint of missedWaypoints) { - const inverse = this.geodesic.inverse( - missedWaypoint.waypoint[0], - missedWaypoint.waypoint[1], - points[index][0], - points[index][1], - ); - if (inverse.distance < missedWaypoint.distance) { - missedWaypoint.distance = inverse.distance; - missedWaypoint.nearest = parseInt(index); - } - } - } - for (const missedWaypoint of missedWaypoints) { - indices[missedWaypoint.originIndex] = missedWaypoint.nearest; - } - return indices; - }; - - private getTimes = ( - durations: Array, - indices: number[], - ): Array<{ index: number; duration: number }> => { - const times: Array<{ index: number; duration: number }> = []; - let duration = 0; - for (const [origin, destination, stepDuration] of durations) { - let indexFound = false; - const indexAsOrigin = indices.find((index) => index == origin); - if ( - indexAsOrigin !== undefined && - times.find((time) => origin == time.index) == undefined - ) { - times.push({ - index: indexAsOrigin, - duration: Math.round(stepDuration / 1000), - }); - indexFound = true; - } - if (!indexFound) { - const indexAsDestination = indices.find( - (index) => index == destination, - ); - if ( - indexAsDestination !== undefined && - times.find((time) => destination == time.index) == undefined - ) { - times.push({ - index: indexAsDestination, - duration: Math.round((duration + stepDuration) / 1000), - }); - indexFound = true; - } - } - if (!indexFound) { - const indexInBetween = indices.find( - (index) => origin < index && index < destination, - ); - if (indexInBetween !== undefined) { - times.push({ - index: indexInBetween, - duration: Math.round((duration + stepDuration / 2) / 1000), - }); - } - } - duration += stepDuration; - } - return times; - }; - - private getDistances = ( - instructions: GraphhopperInstruction[], - indices: number[], - ): Array<{ index: number; distance: number }> => { - let distance = 0; - const distances: Array<{ index: number; distance: number }> = [ - { - index: 0, - distance, - }, - ]; - for (const instruction of instructions) { - distance += instruction.distance; - if ( - (instruction.sign == GraphhopperSign.SIGN_WAYPOINT || - instruction.sign == GraphhopperSign.SIGN_FINISH) && - indices.find((index) => index == instruction.interval[0]) !== undefined - ) { - distances.push({ - index: instruction.interval[0], - distance: Math.round(distance), - }); - } - } - return distances; - }; -} - -type GraphhopperResponse = { - paths: [ - { - distance: number; - weight: number; - time: number; - points_encoded: boolean; - bbox: number[]; - points: GraphhopperCoordinates; - snapped_waypoints: GraphhopperCoordinates; - details: { - time: Array; - }; - instructions: GraphhopperInstruction[]; - }, - ]; -}; - -type GraphhopperCoordinates = { - coordinates: Array; -}; - -type GraphhopperInstruction = { - distance: number; - heading: number; - sign: GraphhopperSign; - interval: number[]; - text: string; -}; - -enum GraphhopperSign { - SIGN_START = 0, - SIGN_FINISH = 4, - SIGN_WAYPOINT = 5, -} diff --git a/old/modules/geography/adapters/secondaries/postgres-direction-encoder.ts b/old/modules/geography/adapters/secondaries/postgres-direction-encoder.ts deleted file mode 100644 index 3a85ace..0000000 --- a/old/modules/geography/adapters/secondaries/postgres-direction-encoder.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Coordinate } from '../../domain/entities/coordinate'; -import { IEncodeDirection } from '../../domain/interfaces/direction-encoder.interface'; - -export class PostgresDirectionEncoder implements IEncodeDirection { - encode = (coordinates: Coordinate[]): string => - [ - "'LINESTRING(", - coordinates.map((point) => [point.lon, point.lat].join(' ')).join(), - ")'", - ].join(''); -} diff --git a/old/modules/geography/domain/entities/coordinate.ts b/old/modules/geography/domain/entities/coordinate.ts deleted file mode 100644 index 4dd416a..0000000 --- a/old/modules/geography/domain/entities/coordinate.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { AutoMap } from '@automapper/classes'; -import { IsLatitude, IsLongitude, IsNumber } from 'class-validator'; - -export class Coordinate { - constructor(lon: number, lat: number) { - this.lon = lon; - this.lat = lat; - } - - @IsNumber() - @IsLongitude() - @AutoMap() - lon: number; - - @IsNumber() - @IsLatitude() - @AutoMap() - lat: number; -} diff --git a/old/modules/geography/domain/entities/route.ts b/old/modules/geography/domain/entities/route.ts deleted file mode 100644 index 48b8744..0000000 --- a/old/modules/geography/domain/entities/route.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { IGeodesic } from '../interfaces/geodesic.interface'; -import { Point } from '../types/point.type'; -import { SpacetimePoint } from './spacetime-point'; - -export class Route { - distance: number; - duration: number; - fwdAzimuth: number; - backAzimuth: number; - distanceAzimuth: number; - points: Point[]; - spacetimePoints: SpacetimePoint[]; - private geodesic: IGeodesic; - - constructor(geodesic: IGeodesic) { - this.distance = undefined; - this.duration = undefined; - this.fwdAzimuth = undefined; - this.backAzimuth = undefined; - this.distanceAzimuth = undefined; - this.points = []; - this.spacetimePoints = []; - this.geodesic = geodesic; - } - - setPoints = (points: Point[]): void => { - this.points = points; - this.setAzimuth(points); - }; - - setSpacetimePoints = (spacetimePoints: SpacetimePoint[]): void => { - this.spacetimePoints = spacetimePoints; - }; - - protected setAzimuth = (points: Point[]): void => { - const inverse = this.geodesic.inverse( - points[0].lon, - points[0].lat, - points[points.length - 1].lon, - points[points.length - 1].lat, - ); - this.fwdAzimuth = - inverse.azimuth >= 0 ? inverse.azimuth : 360 - Math.abs(inverse.azimuth); - this.backAzimuth = - this.fwdAzimuth > 180 ? this.fwdAzimuth - 180 : this.fwdAzimuth + 180; - this.distanceAzimuth = inverse.distance; - }; -} diff --git a/old/modules/geography/domain/entities/spacetime-point.ts b/old/modules/geography/domain/entities/spacetime-point.ts deleted file mode 100644 index 7d720e1..0000000 --- a/old/modules/geography/domain/entities/spacetime-point.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Coordinate } from './coordinate'; - -export class SpacetimePoint { - coordinate: Coordinate; - duration: number; - distance: number; - - constructor(coordinate: Coordinate, duration: number, distance: number) { - this.coordinate = coordinate; - this.duration = duration; - this.distance = distance; - } -} diff --git a/old/modules/geography/domain/interfaces/direction-encoder.interface.ts b/old/modules/geography/domain/interfaces/direction-encoder.interface.ts deleted file mode 100644 index 0f38a49..0000000 --- a/old/modules/geography/domain/interfaces/direction-encoder.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Coordinate } from '../entities/coordinate'; - -export interface IEncodeDirection { - encode(coordinates: Coordinate[]): string; -} diff --git a/old/modules/geography/domain/interfaces/geodesic.interface.ts b/old/modules/geography/domain/interfaces/geodesic.interface.ts deleted file mode 100644 index 95680e8..0000000 --- a/old/modules/geography/domain/interfaces/geodesic.interface.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface IGeodesic { - inverse( - lon1: number, - lat1: number, - lon2: number, - lat2: number, - ): { - azimuth: number; - distance: number; - }; -} diff --git a/old/modules/geography/domain/interfaces/georouter-creator.interface.ts b/old/modules/geography/domain/interfaces/georouter-creator.interface.ts deleted file mode 100644 index 7a6bd25..0000000 --- a/old/modules/geography/domain/interfaces/georouter-creator.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { IGeorouter } from './georouter.interface'; - -export interface ICreateGeorouter { - create(type: string, url: string): IGeorouter; -} diff --git a/old/modules/geography/domain/interfaces/georouter.interface.ts b/old/modules/geography/domain/interfaces/georouter.interface.ts deleted file mode 100644 index c2c2e05..0000000 --- a/old/modules/geography/domain/interfaces/georouter.interface.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GeorouterSettings } from '../types/georouter-settings.type'; -import { NamedRoute } from '../types/named-route'; -import { Path } from '../types/path.type'; - -export interface IGeorouter { - route(paths: Path[], settings: GeorouterSettings): Promise; -} diff --git a/old/modules/geography/domain/interfaces/timezone-finder.interface.ts b/old/modules/geography/domain/interfaces/timezone-finder.interface.ts deleted file mode 100644 index 61016f7..0000000 --- a/old/modules/geography/domain/interfaces/timezone-finder.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IFindTimezone { - timezones(lon: number, lat: number): string[]; -} diff --git a/old/modules/geography/domain/types/georouter-settings.type.ts b/old/modules/geography/domain/types/georouter-settings.type.ts deleted file mode 100644 index d8f73ae..0000000 --- a/old/modules/geography/domain/types/georouter-settings.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type GeorouterSettings = { - withPoints: boolean; - withTime: boolean; - withDistance: boolean; -}; diff --git a/old/modules/geography/domain/types/named-route.ts b/old/modules/geography/domain/types/named-route.ts deleted file mode 100644 index f1fdb2d..0000000 --- a/old/modules/geography/domain/types/named-route.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Route } from '../entities/route'; - -export type NamedRoute = { - key: string; - route: Route; -}; diff --git a/old/modules/geography/domain/types/path.type.ts b/old/modules/geography/domain/types/path.type.ts deleted file mode 100644 index 60766e6..0000000 --- a/old/modules/geography/domain/types/path.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Point } from './point.type'; - -export type Path = { - key: string; - points: Point[]; -}; diff --git a/old/modules/geography/domain/types/point-type.enum.ts b/old/modules/geography/domain/types/point-type.enum.ts deleted file mode 100644 index e1e57a2..0000000 --- a/old/modules/geography/domain/types/point-type.enum.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum PointType { - HOUSE_NUMBER = 'HOUSE_NUMBER', - STREET_ADDRESS = 'STREET_ADDRESS', - LOCALITY = 'LOCALITY', - VENUE = 'VENUE', - OTHER = 'OTHER', -} diff --git a/old/modules/geography/domain/types/point.type.ts b/old/modules/geography/domain/types/point.type.ts deleted file mode 100644 index 37c49e6..0000000 --- a/old/modules/geography/domain/types/point.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { PointType } from './point-type.enum'; -import { Coordinate } from '../entities/coordinate'; - -export type Point = Coordinate & { - type?: PointType; -}; diff --git a/old/modules/geography/domain/types/timezoner.ts b/old/modules/geography/domain/types/timezoner.ts deleted file mode 100644 index 8764400..0000000 --- a/old/modules/geography/domain/types/timezoner.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IFindTimezone } from '../interfaces/timezone-finder.interface'; - -export type Timezoner = { - timezone: string; - finder: IFindTimezone; -}; diff --git a/old/modules/geography/exceptions/geography.exception.ts b/old/modules/geography/exceptions/geography.exception.ts deleted file mode 100644 index ebc1813..0000000 --- a/old/modules/geography/exceptions/geography.exception.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class GeographyException implements Error { - name: string; - code: number; - message: string; - - constructor(code: number, message: string) { - this.name = 'GeographyException'; - this.code = code; - this.message = message; - } -} diff --git a/old/modules/geography/geography.module.ts b/old/modules/geography/geography.module.ts deleted file mode 100644 index d4be2c8..0000000 --- a/old/modules/geography/geography.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Module } from '@nestjs/common'; -import { GeoTimezoneFinder } from './adapters/secondaries/geo-timezone-finder'; -import { Geodesic } from './adapters/secondaries/geodesic'; - -@Module({ - providers: [GeoTimezoneFinder, Geodesic], - exports: [GeoTimezoneFinder, Geodesic], -}) -export class GeographyModule {} diff --git a/old/modules/geography/tests/unit/coordinate.spec.ts b/old/modules/geography/tests/unit/coordinate.spec.ts deleted file mode 100644 index 6bc92e1..0000000 --- a/old/modules/geography/tests/unit/coordinate.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Coordinate } from '../../domain/entities/coordinate'; - -describe('Coordinate entity', () => { - it('should be defined', () => { - const coordinate: Coordinate = new Coordinate(6, 47); - expect(coordinate).toBeDefined(); - }); -}); diff --git a/old/modules/geography/tests/unit/geo-timezone-finder.spec.ts b/old/modules/geography/tests/unit/geo-timezone-finder.spec.ts deleted file mode 100644 index 285761f..0000000 --- a/old/modules/geography/tests/unit/geo-timezone-finder.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { GeoTimezoneFinder } from '../../adapters/secondaries/geo-timezone-finder'; - -describe('Geo TZ Finder', () => { - it('should be defined', () => { - const timezoneFinder: GeoTimezoneFinder = new GeoTimezoneFinder(); - expect(timezoneFinder).toBeDefined(); - }); - it('should get timezone for Nancy(France) as Europe/Paris', () => { - const timezoneFinder: GeoTimezoneFinder = new GeoTimezoneFinder(); - const timezones = timezoneFinder.timezones(6.179373, 48.687913); - expect(timezones.length).toBe(1); - expect(timezones[0]).toBe('Europe/Paris'); - }); -}); diff --git a/old/modules/geography/tests/unit/geodesic.spec.ts b/old/modules/geography/tests/unit/geodesic.spec.ts deleted file mode 100644 index 750d7d4..0000000 --- a/old/modules/geography/tests/unit/geodesic.spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Geodesic } from '../../adapters/secondaries/geodesic'; - -describe('Matcher geodesic', () => { - it('should be defined', () => { - const geodesic: Geodesic = new Geodesic(); - expect(geodesic).toBeDefined(); - }); - it('should get inverse values', () => { - const geodesic: Geodesic = new Geodesic(); - const inv = geodesic.inverse(0, 0, 1, 1); - expect(Math.round(inv.azimuth)).toBe(45); - expect(Math.round(inv.distance)).toBe(156900); - }); -}); diff --git a/old/modules/geography/tests/unit/georouter-creator.spec.ts b/old/modules/geography/tests/unit/georouter-creator.spec.ts deleted file mode 100644 index 03afe6c..0000000 --- a/old/modules/geography/tests/unit/georouter-creator.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { HttpService } from '@nestjs/axios'; -import { GeorouterCreator } from '../../adapters/secondaries/georouter-creator'; -import { Geodesic } from '../../adapters/secondaries/geodesic'; -import { GraphhopperGeorouter } from '../../adapters/secondaries/graphhopper-georouter'; - -const mockHttpService = jest.fn(); -const mockGeodesic = jest.fn(); - -describe('Georouter creator', () => { - let georouterCreator: GeorouterCreator; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - GeorouterCreator, - { - provide: HttpService, - useValue: mockHttpService, - }, - { - provide: Geodesic, - useValue: mockGeodesic, - }, - ], - }).compile(); - - georouterCreator = module.get(GeorouterCreator); - }); - - it('should be defined', () => { - expect(georouterCreator).toBeDefined(); - }); - it('should create a graphhopper georouter', () => { - const georouter = georouterCreator.create( - 'graphhopper', - 'http://localhost', - ); - expect(georouter).toBeInstanceOf(GraphhopperGeorouter); - }); - it('should throw an exception if georouter type is unknown', () => { - expect(() => - georouterCreator.create('unknown', 'http://localhost'), - ).toThrow(); - }); -}); diff --git a/old/modules/geography/tests/unit/graphhopper-georouter.spec.ts b/old/modules/geography/tests/unit/graphhopper-georouter.spec.ts deleted file mode 100644 index e0e45f9..0000000 --- a/old/modules/geography/tests/unit/graphhopper-georouter.spec.ts +++ /dev/null @@ -1,456 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { HttpService } from '@nestjs/axios'; -import { of } from 'rxjs'; -import { AxiosError } from 'axios'; -import { GeorouterCreator } from '../../adapters/secondaries/georouter-creator'; -import { IGeorouter } from '../../domain/interfaces/georouter.interface'; -import { Geodesic } from '../../adapters/secondaries/geodesic'; - -const mockHttpService = { - get: jest - .fn() - .mockImplementationOnce(() => { - throw new AxiosError('Axios error !'); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - snapped_waypoints: { - coordinates: [ - [0, 0], - [10, 10], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [10, 10], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - details: { - time: [ - [0, 1, 180000], - [1, 2, 180000], - [2, 3, 180000], - [3, 4, 180000], - [4, 5, 180000], - [5, 6, 180000], - [6, 7, 180000], - [7, 9, 360000], - [9, 10, 180000], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [10, 10], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [5, 5], - [10, 10], - ], - }, - details: { - time: [ - [0, 1, 180000], - [1, 2, 180000], - [2, 3, 180000], - [3, 4, 180000], - [4, 7, 540000], - [7, 9, 360000], - [9, 10, 180000], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [5, 5], - [10, 10], - ], - }, - details: { - time: [ - [0, 1, 180000], - [1, 2, 180000], - [2, 3, 180000], - [3, 4, 180000], - [4, 7, 540000], - [7, 9, 360000], - [9, 10, 180000], - ], - }, - instructions: [ - { - distance: 25000, - sign: 0, - interval: [0, 5], - text: 'Some instructions', - time: 900000, - }, - { - distance: 0, - sign: 5, - interval: [5, 5], - text: 'Waypoint 1', - time: 0, - }, - { - distance: 25000, - sign: 2, - interval: [5, 10], - text: 'Some instructions', - time: 900000, - }, - { - distance: 0.0, - sign: 4, - interval: [10, 10], - text: 'Arrive at destination', - time: 0, - }, - ], - }, - ], - }, - }); - }), -}; - -const mockGeodesic = { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - inverse: jest.fn().mockImplementation(() => ({ - azimuth: 45, - distance: 50000, - })), -}; - -describe('Graphhopper Georouter', () => { - let georouterCreator: GeorouterCreator; - let graphhopperGeorouter: IGeorouter; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - GeorouterCreator, - { - provide: HttpService, - useValue: mockHttpService, - }, - { - provide: Geodesic, - useValue: mockGeodesic, - }, - ], - }).compile(); - - georouterCreator = module.get(GeorouterCreator); - graphhopperGeorouter = georouterCreator.create( - 'graphhopper', - 'http://localhost', - ); - }); - - it('should be defined', () => { - expect(graphhopperGeorouter).toBeDefined(); - }); - - describe('route function', () => { - it('should fail on axios error', async () => { - await expect( - graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 1, - lon: 1, - }, - ], - }, - ], - { - withDistance: false, - withPoints: false, - withTime: false, - }, - ), - ).rejects.toBeInstanceOf(Error); - }); - - it('should create one route with all settings to false', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: false, - withTime: false, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.distance).toBe(50000); - }); - - it('should create one route with points', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: true, - withTime: false, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.distance).toBe(50000); - expect(routes[0].route.duration).toBe(1800); - expect(routes[0].route.fwdAzimuth).toBe(45); - expect(routes[0].route.backAzimuth).toBe(225); - expect(routes[0].route.points.length).toBe(11); - }); - - it('should create one route with points and time', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: true, - withTime: true, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.spacetimePoints.length).toBe(2); - expect(routes[0].route.spacetimePoints[1].duration).toBe(1800); - expect(routes[0].route.spacetimePoints[1].distance).toBeUndefined(); - }); - - it('should create one route with points and missed waypoints extrapolations', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 5, - lon: 5, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: true, - withTime: true, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.spacetimePoints.length).toBe(3); - expect(routes[0].route.distance).toBe(50000); - expect(routes[0].route.duration).toBe(1800); - expect(routes[0].route.fwdAzimuth).toBe(45); - expect(routes[0].route.backAzimuth).toBe(225); - expect(routes[0].route.points.length).toBe(9); - }); - - it('should create one route with points, time and distance', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: true, - withPoints: true, - withTime: true, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.spacetimePoints.length).toBe(3); - expect(routes[0].route.spacetimePoints[1].duration).toBe(990); - expect(routes[0].route.spacetimePoints[1].distance).toBe(25000); - }); - }); -}); diff --git a/old/modules/geography/tests/unit/postgres-direction-encoder.spec.ts b/old/modules/geography/tests/unit/postgres-direction-encoder.spec.ts deleted file mode 100644 index 71b8ea3..0000000 --- a/old/modules/geography/tests/unit/postgres-direction-encoder.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { PostgresDirectionEncoder } from '../../adapters/secondaries/postgres-direction-encoder'; -import { Coordinate } from '../../domain/entities/coordinate'; - -describe('Postgres direction encoder', () => { - it('should be defined', () => { - const postgresDirectionEncoder: PostgresDirectionEncoder = - new PostgresDirectionEncoder(); - expect(postgresDirectionEncoder).toBeDefined(); - }); - it('should encode coordinates to a postgres direction', () => { - const postgresDirectionEncoder: PostgresDirectionEncoder = - new PostgresDirectionEncoder(); - const coordinates: Coordinate[] = [ - { - lon: 6, - lat: 47, - }, - { - lon: 6.1, - lat: 47.1, - }, - { - lon: 6.2, - lat: 47.2, - }, - ]; - const direction = postgresDirectionEncoder.encode(coordinates); - expect(direction).toBe("'LINESTRING(6 47,6.1 47.1,6.2 47.2)'"); - }); -}); diff --git a/old/modules/geography/tests/unit/route.spec.ts b/old/modules/geography/tests/unit/route.spec.ts deleted file mode 100644 index 7a8c1e4..0000000 --- a/old/modules/geography/tests/unit/route.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Route } from '../../domain/entities/route'; -import { SpacetimePoint } from '../../domain/entities/spacetime-point'; - -const mockGeodesic = { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - inverse: jest.fn().mockImplementation((lon1, lat1, lon2, lat2) => { - return lon1 == 0 - ? { - azimuth: 45, - distance: 50000, - } - : { - azimuth: -45, - distance: 60000, - }; - }), -}; - -describe('Route entity', () => { - it('should be defined', () => { - const route = new Route(mockGeodesic); - expect(route).toBeDefined(); - }); - it('should set points and geodesic values for a route', () => { - const route = new Route(mockGeodesic); - route.setPoints([ - { - lon: 10, - lat: 10, - }, - { - lon: 20, - lat: 20, - }, - ]); - expect(route.points.length).toBe(2); - expect(route.fwdAzimuth).toBe(315); - expect(route.backAzimuth).toBe(135); - expect(route.distanceAzimuth).toBe(60000); - }); - it('should set spacetimePoints for a route', () => { - const route = new Route(mockGeodesic); - const spacetimePoint1 = new SpacetimePoint({ lon: 0, lat: 0 }, 0, 0); - const spacetimePoint2 = new SpacetimePoint({ lon: 10, lat: 10 }, 500, 5000); - route.setSpacetimePoints([spacetimePoint1, spacetimePoint2]); - expect(route.spacetimePoints.length).toBe(2); - }); -}); diff --git a/old/modules/health/adapters/primaries/health-server.controller.ts b/old/modules/health/adapters/primaries/health-server.controller.ts deleted file mode 100644 index 3cdc70d..0000000 --- a/old/modules/health/adapters/primaries/health-server.controller.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Controller } from '@nestjs/common'; -import { GrpcMethod } from '@nestjs/microservices'; -import { RepositoriesHealthIndicatorUseCase } from '../../domain/usecases/repositories.health-indicator.usecase'; - -enum ServingStatus { - UNKNOWN = 0, - SERVING = 1, - NOT_SERVING = 2, -} - -interface HealthCheckRequest { - service: string; -} - -interface HealthCheckResponse { - status: ServingStatus; -} - -@Controller() -export class HealthServerController { - constructor( - private readonly repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase, - ) {} - - @GrpcMethod('Health', 'Check') - async check( - // eslint-disable-next-line @typescript-eslint/no-unused-vars - data: HealthCheckRequest, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - metadata: any, - ): Promise { - const healthCheck = await this.repositoriesHealthIndicatorUseCase.isHealthy( - 'repositories', - ); - return { - status: - healthCheck['repositories'].status == 'up' - ? ServingStatus.SERVING - : ServingStatus.NOT_SERVING, - }; - } -} diff --git a/old/modules/health/adapters/primaries/health.controller.ts b/old/modules/health/adapters/primaries/health.controller.ts deleted file mode 100644 index ba6ad9f..0000000 --- a/old/modules/health/adapters/primaries/health.controller.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Controller, Get, Inject } from '@nestjs/common'; -import { - HealthCheckService, - HealthCheck, - HealthCheckResult, -} from '@nestjs/terminus'; -import { MESSAGE_PUBLISHER } from 'src/app.constants'; -import { IPublishMessage } from 'src/interfaces/message-publisher'; -import { RepositoriesHealthIndicatorUseCase } from '../../domain/usecases/repositories.health-indicator.usecase'; - -@Controller('health') -export class HealthController { - constructor( - private readonly repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase, - private healthCheckService: HealthCheckService, - @Inject(MESSAGE_PUBLISHER) - private readonly messagePublisher: IPublishMessage, - ) {} - - @Get() - @HealthCheck() - async check() { - try { - return await this.healthCheckService.check([ - async () => - this.repositoriesHealthIndicatorUseCase.isHealthy('repositories'), - ]); - } catch (error) { - const healthCheckResult: HealthCheckResult = error.response; - this.messagePublisher.publish( - 'logging.user.health.crit', - JSON.stringify(healthCheckResult.error), - ); - throw error; - } - } -} diff --git a/old/modules/health/adapters/primaries/health.proto b/old/modules/health/adapters/primaries/health.proto deleted file mode 100644 index 74e1a4c..0000000 --- a/old/modules/health/adapters/primaries/health.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -package health; - - -service Health { - rpc Check(HealthCheckRequest) returns (HealthCheckResponse); -} - -message HealthCheckRequest { - string service = 1; -} - -message HealthCheckResponse { - enum ServingStatus { - UNKNOWN = 0; - SERVING = 1; - NOT_SERVING = 2; - } - ServingStatus status = 1; -} diff --git a/old/modules/health/adapters/secondaries/message-publisher.ts b/old/modules/health/adapters/secondaries/message-publisher.ts deleted file mode 100644 index 98a963b..0000000 --- a/old/modules/health/adapters/secondaries/message-publisher.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; -import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; -import { IPublishMessage } from 'src/interfaces/message-publisher'; - -@Injectable() -export class MessagePublisher implements IPublishMessage { - constructor( - @Inject(MESSAGE_BROKER_PUBLISHER) - private readonly messageBrokerPublisher: MessageBrokerPublisher, - ) {} - - publish = (routingKey: string, message: string): void => { - this.messageBrokerPublisher.publish(routingKey, message); - }; -} diff --git a/old/modules/health/domain/interfaces/check-repository.interface.ts b/old/modules/health/domain/interfaces/check-repository.interface.ts deleted file mode 100644 index 68c3178..0000000 --- a/old/modules/health/domain/interfaces/check-repository.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface ICheckRepository { - healthCheck(): Promise; -} diff --git a/old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts b/old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts deleted file mode 100644 index 7aaecfa..0000000 --- a/old/modules/health/domain/usecases/repositories.health-indicator.usecase.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { - HealthCheckError, - HealthIndicator, - HealthIndicatorResult, -} from '@nestjs/terminus'; -import { ICheckRepository } from '../interfaces/check-repository.interface'; -import { AdRepository } from '../../../ad/adapters/secondaries/ad.repository'; - -@Injectable() -export class RepositoriesHealthIndicatorUseCase extends HealthIndicator { - private checkRepositories: ICheckRepository[]; - constructor(private readonly adRepository: AdRepository) { - super(); - this.checkRepositories = [adRepository]; - } - isHealthy = async (key: string): Promise => { - try { - await Promise.all( - this.checkRepositories.map( - async (checkRepository: ICheckRepository) => { - await checkRepository.healthCheck(); - }, - ), - ); - return this.getStatus(key, true); - } catch (e: any) { - throw new HealthCheckError('Repository', { - repository: e.message, - }); - } - }; -} diff --git a/old/modules/health/health.module.ts b/old/modules/health/health.module.ts deleted file mode 100644 index 0c2511a..0000000 --- a/old/modules/health/health.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Module } from '@nestjs/common'; -import { HealthServerController } from './adapters/primaries/health-server.controller'; -import { DatabaseModule } from '../database/database.module'; -import { HealthController } from './adapters/primaries/health.controller'; -import { TerminusModule } from '@nestjs/terminus'; -import { MESSAGE_BROKER_PUBLISHER, MESSAGE_PUBLISHER } from 'src/app.constants'; -import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; -import { MessagePublisher } from './adapters/secondaries/message-publisher'; -import { RepositoriesHealthIndicatorUseCase } from './domain/usecases/repositories.health-indicator.usecase'; -import { AdRepository } from '../ad/adapters/secondaries/ad.repository'; - -@Module({ - imports: [TerminusModule, DatabaseModule], - controllers: [HealthServerController, HealthController], - providers: [ - RepositoriesHealthIndicatorUseCase, - AdRepository, - { - provide: MESSAGE_BROKER_PUBLISHER, - useClass: MessageBrokerPublisher, - }, - { - provide: MESSAGE_PUBLISHER, - useClass: MessagePublisher, - }, - ], -}) -export class HealthModule {} diff --git a/old/modules/health/tests/unit/message-publisher.spec.ts b/old/modules/health/tests/unit/message-publisher.spec.ts deleted file mode 100644 index eec02ea..0000000 --- a/old/modules/health/tests/unit/message-publisher.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { MessagePublisher } from '../../adapters/secondaries/message-publisher'; -import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; - -const mockMessageBrokerPublisher = { - publish: jest.fn().mockImplementation(), -}; - -describe('Messager', () => { - let messagePublisher: MessagePublisher; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - MessagePublisher, - { - provide: MESSAGE_BROKER_PUBLISHER, - useValue: mockMessageBrokerPublisher, - }, - ], - }).compile(); - - messagePublisher = module.get(MessagePublisher); - }); - - it('should be defined', () => { - expect(messagePublisher).toBeDefined(); - }); - - it('should publish a message', async () => { - jest.spyOn(mockMessageBrokerPublisher, 'publish'); - messagePublisher.publish('health.info', 'my-test'); - expect(mockMessageBrokerPublisher.publish).toHaveBeenCalledTimes(1); - }); -}); diff --git a/old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts b/old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts deleted file mode 100644 index c726f27..0000000 --- a/old/modules/health/tests/unit/repositories.health-indicator.usecase.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { HealthCheckError, HealthIndicatorResult } from '@nestjs/terminus'; -import { RepositoriesHealthIndicatorUseCase } from '../../domain/usecases/repositories.health-indicator.usecase'; -import { AdRepository } from '../../../ad/adapters/secondaries/ad.repository'; - -const mockAdRepository = { - healthCheck: jest - .fn() - .mockImplementationOnce(() => { - return Promise.resolve(true); - }) - .mockImplementation(() => { - throw new Error('an error occured in the repository'); - }), -}; - -describe('RepositoriesHealthIndicatorUseCase', () => { - let repositoriesHealthIndicatorUseCase: RepositoriesHealthIndicatorUseCase; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - RepositoriesHealthIndicatorUseCase, - { - provide: AdRepository, - useValue: mockAdRepository, - }, - ], - }).compile(); - - repositoriesHealthIndicatorUseCase = - module.get( - RepositoriesHealthIndicatorUseCase, - ); - }); - - it('should be defined', () => { - expect(repositoriesHealthIndicatorUseCase).toBeDefined(); - }); - - describe('execute', () => { - it('should check health successfully', async () => { - const healthIndicatorResult: HealthIndicatorResult = - await repositoriesHealthIndicatorUseCase.isHealthy('repositories'); - - expect(healthIndicatorResult['repositories'].status).toBe('up'); - }); - - it('should throw an error if database is unavailable', async () => { - await expect( - repositoriesHealthIndicatorUseCase.isHealthy('repositories'), - ).rejects.toBeInstanceOf(HealthCheckError); - }); - }); -}); diff --git a/old/modules/matcher/adapters/primaries/matcher.controller.ts b/old/modules/matcher/adapters/primaries/matcher.controller.ts deleted file mode 100644 index bc926b2..0000000 --- a/old/modules/matcher/adapters/primaries/matcher.controller.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Mapper } from '@automapper/core'; -import { InjectMapper } from '@automapper/nestjs'; -import { Controller, UsePipes } from '@nestjs/common'; -import { QueryBus } from '@nestjs/cqrs'; -import { GrpcMethod, RpcException } from '@nestjs/microservices'; -import { RpcValidationPipe } from '../../../utils/pipes/rpc.validation-pipe'; -import { MatchRequest } from '../../domain/dtos/match.request'; -import { ICollection } from '../../../database/interfaces/collection.interface'; -import { MatchQuery } from '../../queries/match.query'; -import { MatchPresenter } from '../secondaries/match.presenter'; -import { DefaultParamsProvider } from '../secondaries/default-params.provider'; -import { GeorouterCreator } from '../secondaries/georouter-creator'; -import { Match } from '../../domain/entities/ecosystem/match'; -import { GeoTimezoneFinder } from '../../../geography/adapters/secondaries/geo-timezone-finder'; -import { TimeConverter } from '../secondaries/time-converter'; - -@UsePipes( - new RpcValidationPipe({ - whitelist: false, - forbidUnknownValues: false, - }), -) -@Controller() -export class MatcherController { - constructor( - private readonly queryBus: QueryBus, - private readonly defaultParamsProvider: DefaultParamsProvider, - @InjectMapper() private readonly mapper: Mapper, - private readonly georouterCreator: GeorouterCreator, - private readonly timezoneFinder: GeoTimezoneFinder, - private readonly timeConverter: TimeConverter, - ) {} - - @GrpcMethod('MatcherService', 'Match') - async match(data: MatchRequest): Promise> { - try { - const matchCollection = await this.queryBus.execute( - new MatchQuery( - data, - this.defaultParamsProvider.getParams(), - this.georouterCreator, - this.timezoneFinder, - this.timeConverter, - ), - ); - return Promise.resolve({ - data: matchCollection.data.map((match: Match) => - this.mapper.map(match, Match, MatchPresenter), - ), - total: matchCollection.total, - }); - } catch (e) { - throw new RpcException({ - code: e.code, - message: e.message, - }); - } - } -} diff --git a/old/modules/matcher/adapters/primaries/matcher.proto b/old/modules/matcher/adapters/primaries/matcher.proto deleted file mode 100644 index 898e6ee..0000000 --- a/old/modules/matcher/adapters/primaries/matcher.proto +++ /dev/null @@ -1,70 +0,0 @@ -syntax = "proto3"; - -package matcher; - -service MatcherService { - rpc Match(MatchRequest) returns (Matches); -} - -message MatchRequest { - string uuid = 1; - repeated Coordinates waypoints = 2; - string departure = 3; - string fromDate = 4; - Schedule schedule = 5; - bool driver = 6; - bool passenger = 7; - string toDate = 8; - int32 marginDuration = 9; - MarginDurations marginDurations = 10; - int32 seatsPassenger = 11; - int32 seatsDriver = 12; - bool strict = 13; - Algorithm algorithm = 14; - int32 remoteness = 15; - bool useProportion = 16; - int32 proportion = 17; - bool useAzimuth = 18; - int32 azimuthMargin = 19; - float maxDetourDistanceRatio = 20; - float maxDetourDurationRatio = 21; - repeated int32 exclusions = 22; -} - -message Coordinates { - float lon = 1; - float lat = 2; -} - -message Schedule { - string mon = 1; - string tue = 2; - string wed = 3; - string thu = 4; - string fri = 5; - string sat = 6; - string sun = 7; -} - -message MarginDurations { - int32 mon = 1; - int32 tue = 2; - int32 wed = 3; - int32 thu = 4; - int32 fri = 5; - int32 sat = 6; - int32 sun = 7; -} - -enum Algorithm { - CLASSIC = 0; -} - -message Match { - string uuid = 1; -} - -message Matches { - repeated Match data = 1; - int32 total = 2; -} diff --git a/old/modules/matcher/adapters/secondaries/default-params.provider.ts b/old/modules/matcher/adapters/secondaries/default-params.provider.ts deleted file mode 100644 index d331919..0000000 --- a/old/modules/matcher/adapters/secondaries/default-params.provider.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { IDefaultParams } from '../../domain/types/default-params.type'; - -@Injectable() -export class DefaultParamsProvider { - constructor(private readonly configService: ConfigService) {} - - getParams = (): IDefaultParams => { - return { - DEFAULT_UUID: this.configService.get('DEFAULT_UUID'), - MARGIN_DURATION: parseInt(this.configService.get('MARGIN_DURATION')), - VALIDITY_DURATION: parseInt(this.configService.get('VALIDITY_DURATION')), - DEFAULT_TIMEZONE: this.configService.get('DEFAULT_TIMEZONE'), - DEFAULT_SEATS: parseInt(this.configService.get('DEFAULT_SEATS')), - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: this.configService.get('ALGORITHM'), - STRICT: !!parseInt(this.configService.get('STRICT_ALGORITHM')), - REMOTENESS: parseInt(this.configService.get('REMOTENESS')), - USE_PROPORTION: !!parseInt(this.configService.get('USE_PROPORTION')), - PROPORTION: parseInt(this.configService.get('PROPORTION')), - USE_AZIMUTH: !!parseInt(this.configService.get('USE_AZIMUTH')), - AZIMUTH_MARGIN: parseInt(this.configService.get('AZIMUTH_MARGIN')), - MAX_DETOUR_DISTANCE_RATIO: parseFloat( - this.configService.get('MAX_DETOUR_DISTANCE_RATIO'), - ), - MAX_DETOUR_DURATION_RATIO: parseFloat( - this.configService.get('MAX_DETOUR_DURATION_RATIO'), - ), - GEOROUTER_TYPE: this.configService.get('GEOROUTER_TYPE'), - GEOROUTER_URL: this.configService.get('GEOROUTER_URL'), - }, - }; - }; -} diff --git a/old/modules/matcher/adapters/secondaries/geodesic.ts b/old/modules/matcher/adapters/secondaries/geodesic.ts deleted file mode 100644 index deb304a..0000000 --- a/old/modules/matcher/adapters/secondaries/geodesic.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { Geodesic } from '../../../geography/adapters/secondaries/geodesic'; -import { IGeodesic } from '../../../geography/domain/interfaces/geodesic.interface'; - -@Injectable() -export class MatcherGeodesic implements IGeodesic { - constructor(private readonly geodesic: Geodesic) {} - - inverse = ( - lon1: number, - lat1: number, - lon2: number, - lat2: number, - ): { azimuth: number; distance: number } => - this.geodesic.inverse(lon1, lat1, lon2, lat2); -} diff --git a/old/modules/matcher/adapters/secondaries/georouter-creator.ts b/old/modules/matcher/adapters/secondaries/georouter-creator.ts deleted file mode 100644 index 5589e7a..0000000 --- a/old/modules/matcher/adapters/secondaries/georouter-creator.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { ICreateGeorouter } from '../../domain/interfaces/georouter-creator.interface'; -import { IGeorouter } from '../../domain/interfaces/georouter.interface'; -import { GraphhopperGeorouter } from './graphhopper-georouter'; -import { HttpService } from '@nestjs/axios'; -import { MatcherGeodesic } from './geodesic'; -import { - MatcherException, - MatcherExceptionCode, -} from '../../exceptions/matcher.exception'; - -@Injectable() -export class GeorouterCreator implements ICreateGeorouter { - constructor( - private readonly httpService: HttpService, - private readonly geodesic: MatcherGeodesic, - ) {} - - create = (type: string, url: string): IGeorouter => { - switch (type) { - case 'graphhopper': - return new GraphhopperGeorouter(url, this.httpService, this.geodesic); - default: - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'Unknown geocoder', - ); - } - }; -} diff --git a/old/modules/matcher/adapters/secondaries/graphhopper-georouter.ts b/old/modules/matcher/adapters/secondaries/graphhopper-georouter.ts deleted file mode 100644 index 472a333..0000000 --- a/old/modules/matcher/adapters/secondaries/graphhopper-georouter.ts +++ /dev/null @@ -1,326 +0,0 @@ -import { HttpService } from '@nestjs/axios'; -import { IGeorouter } from '../../domain/interfaces/georouter.interface'; -import { GeorouterSettings } from '../../domain/types/georouter-settings.type'; -import { Path } from '../../domain/types/path.type'; -import { Injectable } from '@nestjs/common'; -import { catchError, lastValueFrom, map } from 'rxjs'; -import { AxiosError, AxiosResponse } from 'axios'; -import { IGeodesic } from '../../../geography/domain/interfaces/geodesic.interface'; -import { NamedRoute } from '../../domain/entities/ecosystem/named-route'; -import { MatcherRoute } from '../../domain/entities/ecosystem/matcher-route'; -import { SpacetimePoint } from '../../domain/entities/ecosystem/spacetime-point'; -import { - MatcherException, - MatcherExceptionCode, -} from '../../exceptions/matcher.exception'; - -@Injectable() -export class GraphhopperGeorouter implements IGeorouter { - private url: string; - private urlArgs: string[]; - private withTime: boolean; - private withPoints: boolean; - private withDistance: boolean; - private paths: Path[]; - private httpService: HttpService; - private geodesic: IGeodesic; - - constructor(url: string, httpService: HttpService, geodesic: IGeodesic) { - this.url = url + '/route?'; - this.httpService = httpService; - this.geodesic = geodesic; - } - - route = async ( - paths: Path[], - settings: GeorouterSettings, - ): Promise => { - this.setDefaultUrlArgs(); - this.setWithTime(settings.withTime); - this.setWithPoints(settings.withPoints); - this.setWithDistance(settings.withDistance); - this.paths = paths; - return await this.getRoutes(); - }; - - private setDefaultUrlArgs = (): void => { - this.urlArgs = ['vehicle=car', 'weighting=fastest', 'points_encoded=false']; - }; - - private setWithTime = (withTime: boolean): void => { - this.withTime = withTime; - if (withTime) { - this.urlArgs.push('details=time'); - } - }; - - private setWithPoints = (withPoints: boolean): void => { - this.withPoints = withPoints; - if (!withPoints) { - this.urlArgs.push('calc_points=false'); - } - }; - - private setWithDistance = (withDistance: boolean): void => { - this.withDistance = withDistance; - if (withDistance) { - this.urlArgs.push('instructions=true'); - } else { - this.urlArgs.push('instructions=false'); - } - }; - - private getRoutes = async (): Promise => { - const routes = Promise.all( - this.paths.map(async (path) => { - const url: string = [ - this.getUrl(), - '&point=', - path.points - .map((point) => [point.lat, point.lon].join()) - .join('&point='), - ].join(''); - const route = await lastValueFrom( - this.httpService.get(url).pipe( - map((res) => (res.data ? this.createRoute(res) : undefined)), - catchError((error: AxiosError) => { - throw new MatcherException( - MatcherExceptionCode.INTERNAL, - 'Georouter unavailable : ' + error.message, - ); - }), - ), - ); - return { - key: path.key, - route, - }; - }), - ); - return routes; - }; - - private getUrl = (): string => { - return [this.url, this.urlArgs.join('&')].join(''); - }; - - private createRoute = ( - response: AxiosResponse, - ): MatcherRoute => { - const route = new MatcherRoute(this.geodesic); - if (response.data.paths && response.data.paths[0]) { - const shortestPath = response.data.paths[0]; - route.distance = shortestPath.distance ?? 0; - route.duration = shortestPath.time ? shortestPath.time / 1000 : 0; - if (shortestPath.points && shortestPath.points.coordinates) { - route.setPoints( - shortestPath.points.coordinates.map((coordinate) => ({ - lon: coordinate[0], - lat: coordinate[1], - })), - ); - if ( - shortestPath.details && - shortestPath.details.time && - shortestPath.snapped_waypoints && - shortestPath.snapped_waypoints.coordinates - ) { - let instructions: GraphhopperInstruction[] = []; - if (shortestPath.instructions) - instructions = shortestPath.instructions; - route.setSpacetimePoints( - this.generateSpacetimePoints( - shortestPath.points.coordinates, - shortestPath.snapped_waypoints.coordinates, - shortestPath.details.time, - instructions, - ), - ); - } - } - } - return route; - }; - - private generateSpacetimePoints = ( - points: Array, - snappedWaypoints: Array, - durations: Array, - instructions: GraphhopperInstruction[], - ): SpacetimePoint[] => { - const indices = this.getIndices(points, snappedWaypoints); - const times = this.getTimes(durations, indices); - const distances = this.getDistances(instructions, indices); - return indices.map( - (index) => - new SpacetimePoint( - { lon: points[index][1], lat: points[index][0] }, - times.find((time) => time.index == index)?.duration, - distances.find((distance) => distance.index == index)?.distance, - ), - ); - }; - - private getIndices = ( - points: Array, - snappedWaypoints: Array, - ): number[] => { - const indices = snappedWaypoints.map((waypoint) => - points.findIndex( - (point) => point[0] == waypoint[0] && point[1] == waypoint[1], - ), - ); - if (indices.find((index) => index == -1) === undefined) return indices; - const missedWaypoints = indices - .map( - (value, index) => - < - { - index: number; - originIndex: number; - waypoint: number[]; - nearest: number; - distance: number; - } - >{ - index: value, - originIndex: index, - waypoint: snappedWaypoints[index], - nearest: undefined, - distance: 999999999, - }, - ) - .filter((element) => element.index == -1); - for (const index in points) { - for (const missedWaypoint of missedWaypoints) { - const inverse = this.geodesic.inverse( - missedWaypoint.waypoint[0], - missedWaypoint.waypoint[1], - points[index][0], - points[index][1], - ); - if (inverse.distance < missedWaypoint.distance) { - missedWaypoint.distance = inverse.distance; - missedWaypoint.nearest = parseInt(index); - } - } - } - for (const missedWaypoint of missedWaypoints) { - indices[missedWaypoint.originIndex] = missedWaypoint.nearest; - } - return indices; - }; - - private getTimes = ( - durations: Array, - indices: number[], - ): Array<{ index: number; duration: number }> => { - const times: Array<{ index: number; duration: number }> = []; - let duration = 0; - for (const [origin, destination, stepDuration] of durations) { - let indexFound = false; - const indexAsOrigin = indices.find((index) => index == origin); - if ( - indexAsOrigin !== undefined && - times.find((time) => origin == time.index) == undefined - ) { - times.push({ - index: indexAsOrigin, - duration: Math.round(stepDuration / 1000), - }); - indexFound = true; - } - if (!indexFound) { - const indexAsDestination = indices.find( - (index) => index == destination, - ); - if ( - indexAsDestination !== undefined && - times.find((time) => destination == time.index) == undefined - ) { - times.push({ - index: indexAsDestination, - duration: Math.round((duration + stepDuration) / 1000), - }); - indexFound = true; - } - } - if (!indexFound) { - const indexInBetween = indices.find( - (index) => origin < index && index < destination, - ); - if (indexInBetween !== undefined) { - times.push({ - index: indexInBetween, - duration: Math.round((duration + stepDuration / 2) / 1000), - }); - } - } - duration += stepDuration; - } - return times; - }; - - private getDistances = ( - instructions: GraphhopperInstruction[], - indices: number[], - ): Array<{ index: number; distance: number }> => { - let distance = 0; - const distances: Array<{ index: number; distance: number }> = [ - { - index: 0, - distance, - }, - ]; - for (const instruction of instructions) { - distance += instruction.distance; - if ( - (instruction.sign == GraphhopperSign.SIGN_WAYPOINT || - instruction.sign == GraphhopperSign.SIGN_FINISH) && - indices.find((index) => index == instruction.interval[0]) !== undefined - ) { - distances.push({ - index: instruction.interval[0], - distance: Math.round(distance), - }); - } - } - return distances; - }; -} - -type GraphhopperResponse = { - paths: [ - { - distance: number; - weight: number; - time: number; - points_encoded: boolean; - bbox: number[]; - points: GraphhopperCoordinates; - snapped_waypoints: GraphhopperCoordinates; - details: { - time: Array; - }; - instructions: GraphhopperInstruction[]; - }, - ]; -}; - -type GraphhopperCoordinates = { - coordinates: Array; -}; - -type GraphhopperInstruction = { - distance: number; - heading: number; - sign: GraphhopperSign; - interval: number[]; - text: string; -}; - -enum GraphhopperSign { - SIGN_START = 0, - SIGN_FINISH = 4, - SIGN_WAYPOINT = 5, -} diff --git a/old/modules/matcher/adapters/secondaries/match.presenter.ts b/old/modules/matcher/adapters/secondaries/match.presenter.ts deleted file mode 100644 index 4d7fd5e..0000000 --- a/old/modules/matcher/adapters/secondaries/match.presenter.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { AutoMap } from '@automapper/classes'; - -export class MatchPresenter { - @AutoMap() - uuid: string; -} diff --git a/old/modules/matcher/adapters/secondaries/message-publisher.ts b/old/modules/matcher/adapters/secondaries/message-publisher.ts deleted file mode 100644 index 315bb6b..0000000 --- a/old/modules/matcher/adapters/secondaries/message-publisher.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { MESSAGE_BROKER_PUBLISHER } from '../../../../app.constants'; -import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; -import { IPublishMessage } from '../../../../interfaces/message-publisher'; - -@Injectable() -export class MessagePublisher implements IPublishMessage { - constructor( - @Inject(MESSAGE_BROKER_PUBLISHER) - private readonly messageBrokerPublisher: MessageBrokerPublisher, - ) {} - - publish = (routingKey: string, message: string): void => { - this.messageBrokerPublisher.publish(routingKey, message); - }; -} diff --git a/old/modules/matcher/adapters/secondaries/time-converter.ts b/old/modules/matcher/adapters/secondaries/time-converter.ts deleted file mode 100644 index 63e8e62..0000000 --- a/old/modules/matcher/adapters/secondaries/time-converter.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { DateTime, TimeZone } from 'timezonecomplete'; -import { IConvertTime } from '../../domain/interfaces/time-converter.interface'; - -@Injectable() -export class TimeConverter implements IConvertTime { - toUtcDate = (date: Date, timezone: string): Date => { - try { - return new Date( - new DateTime( - `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}T${date.getHours()}:${date.getMinutes()}`, - TimeZone.zone(timezone, false), - ) - .convert(TimeZone.zone('UTC')) - .toIsoString(), - ); - } catch (e) { - return undefined; - } - }; -} diff --git a/old/modules/matcher/adapters/secondaries/timezone-finder.ts b/old/modules/matcher/adapters/secondaries/timezone-finder.ts deleted file mode 100644 index 8459661..0000000 --- a/old/modules/matcher/adapters/secondaries/timezone-finder.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { GeoTimezoneFinder } from '../../../geography/adapters/secondaries/geo-timezone-finder'; -import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-finder.interface'; - -@Injectable() -export class TimezoneFinder implements IFindTimezone { - constructor(private readonly geoTimezoneFinder: GeoTimezoneFinder) {} - - timezones = (lon: number, lat: number): string[] => - this.geoTimezoneFinder.timezones(lon, lat); -} diff --git a/old/modules/matcher/domain/dtos/match.request.ts b/old/modules/matcher/domain/dtos/match.request.ts deleted file mode 100644 index bcd1824..0000000 --- a/old/modules/matcher/domain/dtos/match.request.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { - IsArray, - IsBoolean, - IsEnum, - IsInt, - IsNumber, - IsOptional, - IsString, - Max, - Min, -} from 'class-validator'; -import { AutoMap } from '@automapper/classes'; -import { Point } from '../../../geography/domain/types/point.type'; -import { Schedule } from '../types/schedule.type'; -import { MarginDurations } from '../types/margin-durations.type'; -import { AlgorithmType } from '../types/algorithm.enum'; -import { IRequestTime } from '../interfaces/time-request.interface'; -import { IRequestAd } from '../interfaces/ad-request.interface'; -import { IRequestGeography } from '../interfaces/geography-request.interface'; -import { IRequestRequirement } from '../interfaces/requirement-request.interface'; -import { IRequestAlgorithmSettings } from '../interfaces/algorithm-settings-request.interface'; -import { Mode } from '../types/mode.enum'; - -export class MatchRequest - implements - IRequestTime, - IRequestAd, - IRequestGeography, - IRequestRequirement, - IRequestAlgorithmSettings -{ - @IsOptional() - @IsString() - @AutoMap() - uuid: string; - - @IsOptional() - @IsEnum(Mode) - @AutoMap() - mode: Mode; - - @IsArray() - @AutoMap() - waypoints: Point[]; - - @IsOptional() - @IsString() - @AutoMap() - departure: string; - - @IsOptional() - @IsString() - @AutoMap() - fromDate: string; - - @IsOptional() - @AutoMap() - schedule: Schedule; - - @IsOptional() - @IsBoolean() - @AutoMap() - driver: boolean; - - @IsOptional() - @IsBoolean() - @AutoMap() - passenger: boolean; - - @IsOptional() - @IsString() - @AutoMap() - toDate: string; - - @IsOptional() - @IsInt() - @AutoMap() - marginDuration: number; - - @IsOptional() - @AutoMap() - marginDurations: MarginDurations; - - @IsOptional() - @IsNumber() - @Min(1) - @Max(10) - @AutoMap() - seatsPassenger: number; - - @IsOptional() - @IsNumber() - @Min(1) - @Max(10) - @AutoMap() - seatsDriver: number; - - @IsOptional() - @AutoMap() - strict: boolean; - - @IsOptional() - @IsEnum(AlgorithmType) - @AutoMap() - algorithm: AlgorithmType; - - @IsOptional() - @IsNumber() - @AutoMap() - remoteness: number; - - @IsOptional() - @IsBoolean() - @AutoMap() - useProportion: boolean; - - @IsOptional() - @IsNumber() - @Min(0) - @Max(1) - @AutoMap() - proportion: number; - - @IsOptional() - @IsBoolean() - @AutoMap() - useAzimuth: boolean; - - @IsOptional() - @IsInt() - @Min(0) - @Max(359) - @AutoMap() - azimuthMargin: number; - - @IsOptional() - @IsNumber() - @Min(0) - @Max(1) - @AutoMap() - maxDetourDistanceRatio: number; - - @IsOptional() - @IsNumber() - @Min(0) - @Max(1) - @AutoMap() - maxDetourDurationRatio: number; - - @IsOptional() - @IsArray() - exclusions: string[]; - - timezone?: string; -} diff --git a/old/modules/matcher/domain/entities/ecosystem/actor.ts b/old/modules/matcher/domain/entities/ecosystem/actor.ts deleted file mode 100644 index 78ea643..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/actor.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Role } from '../../types/role.enum'; -import { Step } from '../../types/step.enum'; -import { Ad } from './ad'; - -export class Actor { - ad: Ad; - role: Role; - step: Step; - - constructor(ad: Ad, role: Role, step: Step) { - this.ad = ad; - this.role = role; - this.step = step; - } -} diff --git a/old/modules/matcher/domain/entities/ecosystem/ad.ts b/old/modules/matcher/domain/entities/ecosystem/ad.ts deleted file mode 100644 index 5046579..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/ad.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { IRequestAd } from '../../interfaces/ad-request.interface'; - -export class Ad { - private adRequest: IRequestAd; - private defaultUuid: string; - private defaultMarginDuration: number; - uuid: string; - marginDurations: number[]; - - constructor( - adRequest: IRequestAd, - defaultUuid: string, - defaultMarginDuration: number, - ) { - this.adRequest = adRequest; - this.defaultUuid = defaultUuid; - this.defaultMarginDuration = defaultMarginDuration; - } - - init = (): void => { - this.setUuid(this.adRequest.uuid ?? this.defaultUuid); - this.setMarginDurations([ - this.defaultMarginDuration, - this.defaultMarginDuration, - this.defaultMarginDuration, - this.defaultMarginDuration, - this.defaultMarginDuration, - this.defaultMarginDuration, - this.defaultMarginDuration, - ]); - }; - - setUuid = (uuid: string): void => { - this.uuid = uuid; - }; - - setMarginDurations = (marginDurations: number[]): void => { - this.marginDurations = marginDurations; - }; -} diff --git a/old/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts b/old/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts deleted file mode 100644 index 0e5dd92..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/algorithm-settings.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { IRequestAlgorithmSettings } from '../../interfaces/algorithm-settings-request.interface'; -import { DefaultAlgorithmSettings } from '../../types/default-algorithm-settings.type'; -import { AlgorithmType } from '../../types/algorithm.enum'; -import { ICreateGeorouter } from '../../interfaces/georouter-creator.interface'; -import { IGeorouter } from '../../interfaces/georouter.interface'; -import { Frequency } from '../../../../ad/domain/types/frequency.enum'; - -export class AlgorithmSettings { - private algorithmSettingsRequest: IRequestAlgorithmSettings; - private strict: boolean; - algorithmType: AlgorithmType; - restrict: Frequency; - remoteness: number; - useProportion: boolean; - proportion: number; - useAzimuth: boolean; - azimuthMargin: number; - maxDetourDurationRatio: number; - maxDetourDistanceRatio: number; - georouter: IGeorouter; - - constructor( - algorithmSettingsRequest: IRequestAlgorithmSettings, - defaultAlgorithmSettings: DefaultAlgorithmSettings, - frequency: Frequency, - georouterCreator: ICreateGeorouter, - ) { - this.algorithmSettingsRequest = algorithmSettingsRequest; - this.algorithmType = - algorithmSettingsRequest.algorithm ?? defaultAlgorithmSettings.ALGORITHM; - this.strict = - algorithmSettingsRequest.strict ?? defaultAlgorithmSettings.STRICT; - this.remoteness = algorithmSettingsRequest.remoteness - ? Math.abs(algorithmSettingsRequest.remoteness) - : defaultAlgorithmSettings.REMOTENESS; - this.useProportion = - algorithmSettingsRequest.useProportion ?? - defaultAlgorithmSettings.USE_PROPORTION; - this.proportion = algorithmSettingsRequest.proportion - ? Math.abs(algorithmSettingsRequest.proportion) - : defaultAlgorithmSettings.PROPORTION; - this.useAzimuth = - algorithmSettingsRequest.useAzimuth ?? - defaultAlgorithmSettings.USE_AZIMUTH; - this.azimuthMargin = algorithmSettingsRequest.azimuthMargin - ? Math.abs(algorithmSettingsRequest.azimuthMargin) - : defaultAlgorithmSettings.AZIMUTH_MARGIN; - this.maxDetourDistanceRatio = - algorithmSettingsRequest.maxDetourDistanceRatio ?? - defaultAlgorithmSettings.MAX_DETOUR_DISTANCE_RATIO; - this.maxDetourDurationRatio = - algorithmSettingsRequest.maxDetourDurationRatio ?? - defaultAlgorithmSettings.MAX_DETOUR_DURATION_RATIO; - this.georouter = georouterCreator.create( - defaultAlgorithmSettings.GEOROUTER_TYPE, - defaultAlgorithmSettings.GEOROUTER_URL, - ); - if (this.strict) { - this.restrict = frequency; - } - } -} diff --git a/old/modules/matcher/domain/entities/ecosystem/geography.ts b/old/modules/matcher/domain/entities/ecosystem/geography.ts deleted file mode 100644 index abf9be7..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/geography.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { - MatcherException, - MatcherExceptionCode, -} from '../../../exceptions/matcher.exception'; -import { IRequestGeography } from '../../interfaces/geography-request.interface'; -import { PointType } from '../../../../geography/domain/types/point-type.enum'; -import { Point } from '../../../../geography/domain/types/point.type'; -import { MatcherRoute } from './matcher-route'; -import { Role } from '../../types/role.enum'; -import { IGeorouter } from '../../interfaces/georouter.interface'; -import { Waypoint } from './waypoint'; -import { Actor } from './actor'; -import { Ad } from './ad'; -import { Step } from '../../types/step.enum'; -import { Path } from '../../types/path.type'; -import { IFindTimezone } from '../../../../geography/domain/interfaces/timezone-finder.interface'; -import { Timezoner } from './timezoner'; - -export class Geography { - private geographyRequest: IRequestGeography; - private ad: Ad; - private points: Point[]; - originType: PointType; - destinationType: PointType; - timezones: string[]; - driverRoute: MatcherRoute; - passengerRoute: MatcherRoute; - timezoneFinder: IFindTimezone; - - constructor( - geographyRequest: IRequestGeography, - timezoner: Timezoner, - ad: Ad, - ) { - this.geographyRequest = geographyRequest; - this.ad = ad; - this.points = []; - this.originType = undefined; - this.destinationType = undefined; - this.timezones = [timezoner.timezone]; - this.timezoneFinder = timezoner.finder; - } - - init = (): void => { - this.validateWaypoints(); - this.setTimezones(); - this.setPointTypes(); - }; - - createRoutes = async ( - roles: Role[], - georouter: IGeorouter, - ): Promise => { - let driverWaypoints: Waypoint[] = []; - let passengerWaypoints: Waypoint[] = []; - const paths: Path[] = []; - if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) { - if (this.points.length == 2) { - // 2 points => same route for driver and passenger - const commonPath: Path = { - key: RouteKey.COMMON, - points: this.points, - }; - driverWaypoints = this.createWaypoints(commonPath.points, Role.DRIVER); - passengerWaypoints = this.createWaypoints( - commonPath.points, - Role.PASSENGER, - ); - paths.push(commonPath); - } else { - const driverPath: Path = { - key: RouteKey.DRIVER, - points: this.points, - }; - driverWaypoints = this.createWaypoints(driverPath.points, Role.DRIVER); - const passengerPath: Path = { - key: RouteKey.PASSENGER, - points: [this.points[0], this.points[this.points.length - 1]], - }; - passengerWaypoints = this.createWaypoints( - passengerPath.points, - Role.PASSENGER, - ); - paths.push(driverPath, passengerPath); - } - } else if (roles.includes(Role.DRIVER)) { - const driverPath: Path = { - key: RouteKey.DRIVER, - points: this.points, - }; - driverWaypoints = this.createWaypoints(driverPath.points, Role.DRIVER); - paths.push(driverPath); - } else if (roles.includes(Role.PASSENGER)) { - const passengerPath: Path = { - key: RouteKey.PASSENGER, - points: [this.points[0], this.points[this.points.length - 1]], - }; - passengerWaypoints = this.createWaypoints( - passengerPath.points, - Role.PASSENGER, - ); - paths.push(passengerPath); - } - const routes = await georouter.route(paths, { - withDistance: false, - withPoints: true, - withTime: false, - }); - if (routes.some((route) => route.key == RouteKey.COMMON)) { - this.driverRoute = routes.find( - (route) => route.key == RouteKey.COMMON, - ).route; - this.passengerRoute = routes.find( - (route) => route.key == RouteKey.COMMON, - ).route; - this.driverRoute.setWaypoints(driverWaypoints); - this.passengerRoute.setWaypoints(passengerWaypoints); - } else { - if (routes.some((route) => route.key == RouteKey.DRIVER)) { - this.driverRoute = routes.find( - (route) => route.key == RouteKey.DRIVER, - ).route; - this.driverRoute.setWaypoints(driverWaypoints); - } - if (routes.some((route) => route.key == RouteKey.PASSENGER)) { - this.passengerRoute = routes.find( - (route) => route.key == RouteKey.PASSENGER, - ).route; - this.passengerRoute.setWaypoints(passengerWaypoints); - } - } - }; - - private validateWaypoints = (): void => { - if (this.geographyRequest.waypoints.length < 2) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'At least 2 waypoints are required', - ); - } - this.geographyRequest.waypoints.map((point) => { - if (!this.isValidPoint(point)) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - `Waypoint { Lon: ${point.lon}, Lat: ${point.lat} } is not valid`, - ); - } - this.points.push(point); - }); - }; - - private setTimezones = (): void => { - this.timezones = this.timezoneFinder.timezones( - this.geographyRequest.waypoints[0].lat, - this.geographyRequest.waypoints[0].lon, - ); - }; - - private setPointTypes = (): void => { - this.originType = - this.geographyRequest.waypoints[0].type ?? PointType.OTHER; - this.destinationType = - this.geographyRequest.waypoints[ - this.geographyRequest.waypoints.length - 1 - ].type ?? PointType.OTHER; - }; - - private isValidPoint = (point: Point): boolean => - this.isValidLongitude(point.lon) && this.isValidLatitude(point.lat); - - private isValidLongitude = (longitude: number): boolean => - longitude >= -180 && longitude <= 180; - - private isValidLatitude = (latitude: number): boolean => - latitude >= -90 && latitude <= 90; - - private createWaypoints = (points: Point[], role: Role): Waypoint[] => { - return points.map((point, index) => { - const waypoint = new Waypoint(point); - if (index == 0) { - waypoint.addActor(new Actor(this.ad, role, Step.START)); - } else if (index == points.length - 1) { - waypoint.addActor(new Actor(this.ad, role, Step.FINISH)); - } else { - waypoint.addActor(new Actor(this.ad, role, Step.INTERMEDIATE)); - } - return waypoint; - }); - }; -} - -export enum RouteKey { - COMMON = 'common', - DRIVER = 'driver', - PASSENGER = 'passenger', -} diff --git a/old/modules/matcher/domain/entities/ecosystem/match.ts b/old/modules/matcher/domain/entities/ecosystem/match.ts deleted file mode 100644 index 83c399c..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/match.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { AutoMap } from '@automapper/classes'; - -export class Match { - @AutoMap() - uuid: string; -} diff --git a/old/modules/matcher/domain/entities/ecosystem/matcher-route.ts b/old/modules/matcher/domain/entities/ecosystem/matcher-route.ts deleted file mode 100644 index 197741d..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/matcher-route.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Route } from '../../../../geography/domain/entities/route'; -import { IGeodesic } from '../../../../geography/domain/interfaces/geodesic.interface'; -import { Waypoint } from './waypoint'; - -export class MatcherRoute extends Route { - waypoints: Waypoint[]; - - constructor(geodesic: IGeodesic) { - super(geodesic); - } - - setWaypoints = (waypoints: Waypoint[]): void => { - this.waypoints = waypoints; - this.setAzimuth(waypoints.map((waypoint) => waypoint.point)); - }; -} diff --git a/old/modules/matcher/domain/entities/ecosystem/named-route.ts b/old/modules/matcher/domain/entities/ecosystem/named-route.ts deleted file mode 100644 index c026769..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/named-route.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { MatcherRoute } from './matcher-route'; - -export type NamedRoute = { - key: string; - route: MatcherRoute; -}; diff --git a/old/modules/matcher/domain/entities/ecosystem/requirement.ts b/old/modules/matcher/domain/entities/ecosystem/requirement.ts deleted file mode 100644 index 7100667..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/requirement.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IRequestRequirement } from '../../interfaces/requirement-request.interface'; - -export class Requirement { - private requirementRequest: IRequestRequirement; - seatsDriver: number; - seatsPassenger: number; - - constructor(requirementRequest: IRequestRequirement, defaultSeats: number) { - this.requirementRequest = requirementRequest; - this.seatsDriver = requirementRequest.seatsDriver ?? defaultSeats; - this.seatsPassenger = requirementRequest.seatsPassenger ?? 1; - } -} diff --git a/old/modules/matcher/domain/entities/ecosystem/spacetime-point.ts b/old/modules/matcher/domain/entities/ecosystem/spacetime-point.ts deleted file mode 100644 index 8a45b80..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/spacetime-point.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Coordinate } from '../../../../geography/domain/entities/coordinate'; - -export class SpacetimePoint { - coordinate: Coordinate; - duration: number; - distance: number; - - constructor(coordinate: Coordinate, duration: number, distance: number) { - this.coordinate = coordinate; - this.duration = duration; - this.distance = distance; - } -} diff --git a/old/modules/matcher/domain/entities/ecosystem/time.ts b/old/modules/matcher/domain/entities/ecosystem/time.ts deleted file mode 100644 index 83e3415..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/time.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { - MatcherException, - MatcherExceptionCode, -} from '../../../exceptions/matcher.exception'; -import { MarginDurations } from '../../types/margin-durations.type'; -import { IRequestTime } from '../../interfaces/time-request.interface'; -import { DAYS } from '../../types/days.const'; -import { TimeSchedule } from '../../types/time-schedule.type'; -import { Frequency } from '../../../../ad/domain/types/frequency.enum'; -import { Day } from '../../types/day.type'; -import { IConvertTime } from '../../interfaces/time-converter.interface'; - -export class Time { - private timeRequest: IRequestTime; - private defaultValidityDuration: number; - private timeConverter: IConvertTime; - frequency: Frequency; - fromDate: Date; - toDate: Date; - schedule: TimeSchedule; - marginDurations: MarginDurations; - - constructor( - timeRequest: IRequestTime, - defaultMarginDuration: number, - defaultValidityDuration: number, - timeConverter: IConvertTime, - ) { - this.timeRequest = timeRequest; - this.defaultValidityDuration = defaultValidityDuration; - this.timeConverter = timeConverter; - this.schedule = {}; - this.marginDurations = { - mon: defaultMarginDuration, - tue: defaultMarginDuration, - wed: defaultMarginDuration, - thu: defaultMarginDuration, - fri: defaultMarginDuration, - sat: defaultMarginDuration, - sun: defaultMarginDuration, - }; - } - - init = (): void => { - this.validateBaseDate(); - this.validatePunctualRequest(); - this.validateRecurrentRequest(); - this.setPunctualRequest(); - this.setRecurrentRequest(); - this.setMargindurations(); - }; - - private validateBaseDate = (): void => { - if (!this.timeRequest.departure && !this.timeRequest.fromDate) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'departure or fromDate is required', - ); - } - }; - - private validatePunctualRequest = (): void => { - if (this.timeRequest.departure) { - this.fromDate = this.toDate = new Date(this.timeRequest.departure); - if (!this.isDate(this.fromDate)) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'Wrong departure date', - ); - } - } - }; - - private validateRecurrentRequest = (): void => { - if (this.timeRequest.fromDate) { - this.fromDate = new Date(this.timeRequest.fromDate); - if (!this.isDate(this.fromDate)) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'Wrong fromDate', - ); - } - } - if (this.timeRequest.toDate) { - this.toDate = new Date(this.timeRequest.toDate); - if (!this.isDate(this.toDate)) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'Wrong toDate', - ); - } - if (this.toDate < this.fromDate) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'toDate must be after fromDate', - ); - } - } - if (this.timeRequest.fromDate) { - this.validateSchedule(); - } - }; - - private validateSchedule = (): void => { - if (!this.timeRequest.schedule) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'Schedule is required', - ); - } - if ( - !Object.keys(this.timeRequest.schedule).some((elem) => - DAYS.includes(elem), - ) - ) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'No valid day in the given schedule', - ); - } - Object.keys(this.timeRequest.schedule).map((day) => { - const time = new Date('1970-01-01 ' + this.timeRequest.schedule[day]); - if (!this.isDate(time)) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - `Wrong time for ${day} in schedule`, - ); - } - }); - }; - - private setPunctualRequest = (): void => { - if (this.timeRequest.departure) { - this.frequency = Frequency.PUNCTUAL; - this.schedule[Day[this.fromDate.getDay()]] = this.timeConverter.toUtcDate( - this.fromDate, - this.timeRequest.timezone, - ); - } - }; - - private setRecurrentRequest = (): void => { - if (this.timeRequest.fromDate) { - this.frequency = Frequency.RECURRENT; - if (!this.toDate) { - this.toDate = this.addDays(this.fromDate, this.defaultValidityDuration); - } - this.setSchedule(); - } - }; - - private setSchedule = (): void => { - Object.keys(this.timeRequest.schedule).map((day) => { - this.schedule[day] = this.timeConverter.toUtcDate( - new Date( - `${this.fromDate.getFullYear()}-${this.fromDate.getMonth()}-${this.fromDate.getDate()} ${ - this.timeRequest.schedule[day] - }`, - ), - this.timeRequest.timezone, - ); - }); - }; - - private setMargindurations = (): void => { - if (this.timeRequest.marginDuration) { - const duration = Math.abs(this.timeRequest.marginDuration); - this.marginDurations = { - mon: duration, - tue: duration, - wed: duration, - thu: duration, - fri: duration, - sat: duration, - sun: duration, - }; - } - if (this.timeRequest.marginDurations) { - if ( - !Object.keys(this.timeRequest.marginDurations).some((elem) => - DAYS.includes(elem), - ) - ) { - throw new MatcherException( - MatcherExceptionCode.INVALID_ARGUMENT, - 'No valid day in the given margin durations', - ); - } - Object.keys(this.timeRequest.marginDurations).map((day) => { - this.marginDurations[day] = Math.abs( - this.timeRequest.marginDurations[day], - ); - }); - } - }; - - private isDate = (date: Date): boolean => { - return date instanceof Date && isFinite(+date); - }; - - private addDays = (date: Date, days: number): Date => { - const result = new Date(date); - result.setDate(result.getDate() + days); - return result; - }; -} diff --git a/old/modules/matcher/domain/entities/ecosystem/timezoner.ts b/old/modules/matcher/domain/entities/ecosystem/timezoner.ts deleted file mode 100644 index 29f6e0b..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/timezoner.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IFindTimezone } from '../../../../geography/domain/interfaces/timezone-finder.interface'; - -export type Timezoner = { - timezone: string; - finder: IFindTimezone; -}; diff --git a/old/modules/matcher/domain/entities/ecosystem/waypoint.ts b/old/modules/matcher/domain/entities/ecosystem/waypoint.ts deleted file mode 100644 index 48c0899..0000000 --- a/old/modules/matcher/domain/entities/ecosystem/waypoint.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Point } from '../../../../geography/domain/types/point.type'; -import { Actor } from './actor'; - -export class Waypoint { - point: Point; - actors: Actor[]; - - constructor(point: Point) { - this.point = point; - this.actors = []; - } - - addActor = (actor: Actor) => this.actors.push(actor); -} diff --git a/old/modules/matcher/domain/entities/engine/candidate.ts b/old/modules/matcher/domain/entities/engine/candidate.ts deleted file mode 100644 index 0ace859..0000000 --- a/old/modules/matcher/domain/entities/engine/candidate.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Ad } from '../ecosystem/ad'; - -export class Candidate { - ad: Ad; -} diff --git a/old/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts b/old/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts deleted file mode 100644 index 1bce748..0000000 --- a/old/modules/matcher/domain/entities/engine/factory/algorithm-factory-creator.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { MatchQuery } from 'src/modules/matcher/queries/match.query'; -import { AlgorithmType } from '../../../types/algorithm.enum'; -import { AlgorithmFactory } from './algorithm-factory.abstract'; -import { ClassicAlgorithmFactory } from './classic'; -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class AlgorithmFactoryCreator { - create = (matchQuery: MatchQuery): AlgorithmFactory => { - let algorithmFactory: AlgorithmFactory; - switch (matchQuery.algorithmSettings.algorithmType) { - case AlgorithmType.CLASSIC: - algorithmFactory = new ClassicAlgorithmFactory(matchQuery); - break; - } - return algorithmFactory; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts b/old/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts deleted file mode 100644 index 9405266..0000000 --- a/old/modules/matcher/domain/entities/engine/factory/algorithm-factory.abstract.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { MatchQuery } from 'src/modules/matcher/queries/match.query'; -import { Processor } from '../processor/processor.abstract'; -import { Candidate } from '../candidate'; -import { Selector } from '../selector/selector.abstract'; - -export abstract class AlgorithmFactory { - protected matchQuery: MatchQuery; - private candidates: Candidate[]; - - constructor(matchQuery: MatchQuery) { - this.matchQuery = matchQuery; - this.candidates = []; - } - - abstract createSelector(): Selector; - abstract createProcessors(): Processor[]; -} diff --git a/old/modules/matcher/domain/entities/engine/factory/classic.ts b/old/modules/matcher/domain/entities/engine/factory/classic.ts deleted file mode 100644 index fc06888..0000000 --- a/old/modules/matcher/domain/entities/engine/factory/classic.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { AlgorithmFactory } from './algorithm-factory.abstract'; -import { ClassicWaypointsCompleter } from '../processor/completer/classic-waypoint.completer.processor'; -import { RouteCompleter } from '../processor/completer/route.completer.processor'; -import { ClassicGeoFilter } from '../processor/filter/geofilter/classic.filter.processor'; -import { JourneyCompleter } from '../processor/completer/journey.completer.processor'; -import { ClassicTimeFilter } from '../processor/filter/timefilter/classic.filter.processor'; -import { Processor } from '../processor/processor.abstract'; -import { Selector } from '../selector/selector.abstract'; -import { ClassicSelector } from '../selector/classic.selector'; - -export class ClassicAlgorithmFactory extends AlgorithmFactory { - createSelector = (): Selector => new ClassicSelector(this.matchQuery); - createProcessors = (): Processor[] => [ - new ClassicWaypointsCompleter(this.matchQuery), - new RouteCompleter(this.matchQuery, true, true, true), - new ClassicGeoFilter(this.matchQuery), - new RouteCompleter(this.matchQuery), - new JourneyCompleter(this.matchQuery), - new ClassicTimeFilter(this.matchQuery), - ]; -} diff --git a/old/modules/matcher/domain/entities/engine/matcher.ts b/old/modules/matcher/domain/entities/engine/matcher.ts deleted file mode 100644 index 923b69f..0000000 --- a/old/modules/matcher/domain/entities/engine/matcher.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { MatchQuery } from '../../../queries/match.query'; -import { Match } from '../ecosystem/match'; -import { Candidate } from './candidate'; -import { AlgorithmFactory } from './factory/algorithm-factory.abstract'; -import { AlgorithmFactoryCreator } from './factory/algorithm-factory-creator'; - -@Injectable() -export class Matcher { - constructor( - private readonly algorithmFactoryCreator: AlgorithmFactoryCreator, - ) {} - - match = async (matchQuery: MatchQuery): Promise => { - const algorithmFactory: AlgorithmFactory = - this.algorithmFactoryCreator.create(matchQuery); - let candidates: Candidate[] = await algorithmFactory - .createSelector() - .select(); - for (const processor of algorithmFactory.createProcessors()) { - candidates = processor.execute(candidates); - } - const match = new Match(); - match.uuid = 'e23f9725-2c19-49a0-9ef6-17d8b9a5ec85'; - return [match]; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts b/old/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts deleted file mode 100644 index dee2a2f..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/completer/classic-waypoint.completer.processor.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Candidate } from '../../candidate'; -import { Completer } from './completer.abstract'; - -export class ClassicWaypointsCompleter extends Completer { - complete = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts b/old/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts deleted file mode 100644 index b72064f..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/completer/completer.abstract.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Candidate } from '../../candidate'; -import { Processor } from '../processor.abstract'; - -export abstract class Completer extends Processor { - execute = (candidates: Candidate[]): Candidate[] => this.complete(candidates); - - abstract complete(candidates: Candidate[]): Candidate[]; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts b/old/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts deleted file mode 100644 index d1a028c..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/completer/journey.completer.processor.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Candidate } from '../../candidate'; -import { Completer } from './completer.abstract'; - -export class JourneyCompleter extends Completer { - complete = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts b/old/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts deleted file mode 100644 index 38ca7b1..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/completer/route.completer.processor.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { MatchQuery } from 'src/modules/matcher/queries/match.query'; -import { Candidate } from '../../candidate'; -import { Completer } from './completer.abstract'; - -export class RouteCompleter extends Completer { - private withPoints: boolean; - private withTime: boolean; - private withDistance: boolean; - - constructor( - matchQuery: MatchQuery, - withPoints = false, - withTime = false, - withDistance = false, - ) { - super(matchQuery); - this.withPoints = withPoints; - this.withTime = withTime; - this.withDistance = withDistance; - } - - complete = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts b/old/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts deleted file mode 100644 index 1198383..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/filter/filter.abstract.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Candidate } from '../../candidate'; -import { Processor } from '../processor.abstract'; - -export abstract class Filter extends Processor { - execute = (candidates: Candidate[]): Candidate[] => this.filter(candidates); - - abstract filter(candidates: Candidate[]): Candidate[]; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts b/old/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts deleted file mode 100644 index 77b4663..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/filter/geofilter/classic.filter.processor.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Candidate } from '../../../candidate'; -import { Filter } from '../filter.abstract'; - -export class ClassicGeoFilter extends Filter { - filter = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts b/old/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts deleted file mode 100644 index 2d48c49..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/filter/timefilter/classic.filter.processor.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Candidate } from '../../../candidate'; -import { Filter } from '../filter.abstract'; - -export class ClassicTimeFilter extends Filter { - filter = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/processor/processor.abstract.ts b/old/modules/matcher/domain/entities/engine/processor/processor.abstract.ts deleted file mode 100644 index d4eeabc..0000000 --- a/old/modules/matcher/domain/entities/engine/processor/processor.abstract.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { MatchQuery } from 'src/modules/matcher/queries/match.query'; -import { Candidate } from '../candidate'; - -export abstract class Processor { - private matchQuery: MatchQuery; - - constructor(matchQuery: MatchQuery) { - this.matchQuery = matchQuery; - } - - abstract execute(candidates: Candidate[]): Candidate[]; -} diff --git a/old/modules/matcher/domain/entities/engine/selector/classic.selector.ts b/old/modules/matcher/domain/entities/engine/selector/classic.selector.ts deleted file mode 100644 index 5b1d2da..0000000 --- a/old/modules/matcher/domain/entities/engine/selector/classic.selector.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Candidate } from '../candidate'; -import { Selector } from './selector.abstract'; - -export class ClassicSelector extends Selector { - select = async (): Promise => { - return []; - }; -} diff --git a/old/modules/matcher/domain/entities/engine/selector/selector.abstract.ts b/old/modules/matcher/domain/entities/engine/selector/selector.abstract.ts deleted file mode 100644 index c1b58bf..0000000 --- a/old/modules/matcher/domain/entities/engine/selector/selector.abstract.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { MatchQuery } from 'src/modules/matcher/queries/match.query'; -import { Candidate } from '../candidate'; - -export abstract class Selector { - private matchQuery: MatchQuery; - - constructor(matchQuery: MatchQuery) { - this.matchQuery = matchQuery; - } - - abstract select(): Promise; -} diff --git a/old/modules/matcher/domain/interfaces/ad-request.interface.ts b/old/modules/matcher/domain/interfaces/ad-request.interface.ts deleted file mode 100644 index 4914482..0000000 --- a/old/modules/matcher/domain/interfaces/ad-request.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IRequestAd { - uuid?: string; -} diff --git a/old/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts b/old/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts deleted file mode 100644 index 484ec15..0000000 --- a/old/modules/matcher/domain/interfaces/algorithm-settings-request.interface.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { AlgorithmType } from '../types/algorithm.enum'; - -export interface IRequestAlgorithmSettings { - algorithm: AlgorithmType; - strict: boolean; - remoteness: number; - useProportion: boolean; - proportion: number; - useAzimuth: boolean; - azimuthMargin: number; - maxDetourDistanceRatio: number; - maxDetourDurationRatio: number; -} diff --git a/old/modules/matcher/domain/interfaces/geography-request.interface.ts b/old/modules/matcher/domain/interfaces/geography-request.interface.ts deleted file mode 100644 index 8a58ac1..0000000 --- a/old/modules/matcher/domain/interfaces/geography-request.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Point } from '../../../geography/domain/types/point.type'; - -export interface IRequestGeography { - waypoints: Point[]; -} diff --git a/old/modules/matcher/domain/interfaces/georouter-creator.interface.ts b/old/modules/matcher/domain/interfaces/georouter-creator.interface.ts deleted file mode 100644 index 7a6bd25..0000000 --- a/old/modules/matcher/domain/interfaces/georouter-creator.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { IGeorouter } from './georouter.interface'; - -export interface ICreateGeorouter { - create(type: string, url: string): IGeorouter; -} diff --git a/old/modules/matcher/domain/interfaces/georouter.interface.ts b/old/modules/matcher/domain/interfaces/georouter.interface.ts deleted file mode 100644 index 7c64cc2..0000000 --- a/old/modules/matcher/domain/interfaces/georouter.interface.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { NamedRoute } from '../entities/ecosystem/named-route'; -import { GeorouterSettings } from '../types/georouter-settings.type'; -import { Path } from '../types/path.type'; - -export interface IGeorouter { - route(paths: Path[], settings: GeorouterSettings): Promise; -} diff --git a/old/modules/matcher/domain/interfaces/requirement-request.interface.ts b/old/modules/matcher/domain/interfaces/requirement-request.interface.ts deleted file mode 100644 index 61e5900..0000000 --- a/old/modules/matcher/domain/interfaces/requirement-request.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IRequestRequirement { - seatsDriver?: number; - seatsPassenger?: number; -} diff --git a/old/modules/matcher/domain/interfaces/time-converter.interface.ts b/old/modules/matcher/domain/interfaces/time-converter.interface.ts deleted file mode 100644 index cbbbfb0..0000000 --- a/old/modules/matcher/domain/interfaces/time-converter.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IConvertTime { - toUtcDate(date: Date, timezone: string): Date; -} diff --git a/old/modules/matcher/domain/interfaces/time-request.interface.ts b/old/modules/matcher/domain/interfaces/time-request.interface.ts deleted file mode 100644 index d7f7df7..0000000 --- a/old/modules/matcher/domain/interfaces/time-request.interface.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { MarginDurations } from '../types/margin-durations.type'; -import { Schedule } from '../types/schedule.type'; - -export interface IRequestTime { - departure?: string; - fromDate?: string; - toDate?: string; - schedule?: Schedule; - marginDuration?: number; - marginDurations?: MarginDurations; - timezone?: string; -} diff --git a/old/modules/matcher/domain/types/actor.type..ts b/old/modules/matcher/domain/types/actor.type..ts deleted file mode 100644 index 22315f7..0000000 --- a/old/modules/matcher/domain/types/actor.type..ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Ad } from '../entities/ecosystem/ad'; -import { Role } from './role.enum'; -import { Step } from './step.enum'; - -export type Actor = { - ad: Ad; - role: Role; - step: Step; -}; diff --git a/old/modules/matcher/domain/types/algorithm.enum.ts b/old/modules/matcher/domain/types/algorithm.enum.ts deleted file mode 100644 index 52f14bd..0000000 --- a/old/modules/matcher/domain/types/algorithm.enum.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum AlgorithmType { - CLASSIC = 'CLASSIC', -} diff --git a/old/modules/matcher/domain/types/day.type.ts b/old/modules/matcher/domain/types/day.type.ts deleted file mode 100644 index c275d7a..0000000 --- a/old/modules/matcher/domain/types/day.type.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum Day { - 'sun', - 'mon', - 'tue', - 'wed', - 'thu', - 'fri', - 'sat', -} diff --git a/old/modules/matcher/domain/types/days.const.ts b/old/modules/matcher/domain/types/days.const.ts deleted file mode 100644 index 4794839..0000000 --- a/old/modules/matcher/domain/types/days.const.ts +++ /dev/null @@ -1 +0,0 @@ -export const DAYS = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']; diff --git a/old/modules/matcher/domain/types/default-algorithm-settings.type.ts b/old/modules/matcher/domain/types/default-algorithm-settings.type.ts deleted file mode 100644 index 98fa3b1..0000000 --- a/old/modules/matcher/domain/types/default-algorithm-settings.type.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { AlgorithmType } from './algorithm.enum'; - -export type DefaultAlgorithmSettings = { - ALGORITHM: AlgorithmType; - STRICT: boolean; - REMOTENESS: number; - USE_PROPORTION: boolean; - PROPORTION: number; - USE_AZIMUTH: boolean; - AZIMUTH_MARGIN: number; - MAX_DETOUR_DISTANCE_RATIO: number; - MAX_DETOUR_DURATION_RATIO: number; - GEOROUTER_TYPE: string; - GEOROUTER_URL: string; -}; diff --git a/old/modules/matcher/domain/types/default-params.type.ts b/old/modules/matcher/domain/types/default-params.type.ts deleted file mode 100644 index c91a26a..0000000 --- a/old/modules/matcher/domain/types/default-params.type.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DefaultAlgorithmSettings } from './default-algorithm-settings.type'; - -export type IDefaultParams = { - DEFAULT_UUID: string; - MARGIN_DURATION: number; - VALIDITY_DURATION: number; - DEFAULT_TIMEZONE: string; - DEFAULT_SEATS: number; - DEFAULT_ALGORITHM_SETTINGS: DefaultAlgorithmSettings; -}; diff --git a/old/modules/matcher/domain/types/georouter-settings.type.ts b/old/modules/matcher/domain/types/georouter-settings.type.ts deleted file mode 100644 index d8f73ae..0000000 --- a/old/modules/matcher/domain/types/georouter-settings.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type GeorouterSettings = { - withPoints: boolean; - withTime: boolean; - withDistance: boolean; -}; diff --git a/old/modules/matcher/domain/types/margin-durations.type.ts b/old/modules/matcher/domain/types/margin-durations.type.ts deleted file mode 100644 index 8e09329..0000000 --- a/old/modules/matcher/domain/types/margin-durations.type.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type MarginDurations = { - mon?: number; - tue?: number; - wed?: number; - thu?: number; - fri?: number; - sat?: number; - sun?: number; -}; diff --git a/old/modules/matcher/domain/types/mode.enum.ts b/old/modules/matcher/domain/types/mode.enum.ts deleted file mode 100644 index be6d1eb..0000000 --- a/old/modules/matcher/domain/types/mode.enum.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum Mode { - MATCH = 'MATCH', - PUBLISH = 'PUBLISH', - PUBLISH_AND_MATCH = 'PUBLISH_AND_MATCH', -} diff --git a/old/modules/matcher/domain/types/path.type.ts b/old/modules/matcher/domain/types/path.type.ts deleted file mode 100644 index 44e03b6..0000000 --- a/old/modules/matcher/domain/types/path.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Point } from '../../../geography/domain/types/point.type'; - -export type Path = { - key: string; - points: Point[]; -}; diff --git a/old/modules/matcher/domain/types/role.enum.ts b/old/modules/matcher/domain/types/role.enum.ts deleted file mode 100644 index 7522f80..0000000 --- a/old/modules/matcher/domain/types/role.enum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Role { - DRIVER = 'DRIVER', - PASSENGER = 'PASSENGER', -} diff --git a/old/modules/matcher/domain/types/schedule.type.ts b/old/modules/matcher/domain/types/schedule.type.ts deleted file mode 100644 index 03f8485..0000000 --- a/old/modules/matcher/domain/types/schedule.type.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type Schedule = { - mon?: string; - tue?: string; - wed?: string; - thu?: string; - fri?: string; - sat?: string; - sun?: string; -}; diff --git a/old/modules/matcher/domain/types/step.enum.ts b/old/modules/matcher/domain/types/step.enum.ts deleted file mode 100644 index 4b2fce4..0000000 --- a/old/modules/matcher/domain/types/step.enum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum Step { - START = 'start', - INTERMEDIATE = 'intermediate', - NEUTRAL = 'neutral', - FINISH = 'finish', -} diff --git a/old/modules/matcher/domain/types/time-schedule.type.ts b/old/modules/matcher/domain/types/time-schedule.type.ts deleted file mode 100644 index 4bd6ea2..0000000 --- a/old/modules/matcher/domain/types/time-schedule.type.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type TimeSchedule = { - mon?: Date; - tue?: Date; - wed?: Date; - thu?: Date; - fri?: Date; - sat?: Date; - sun?: Date; -}; diff --git a/old/modules/matcher/domain/types/waypoint.ts b/old/modules/matcher/domain/types/waypoint.ts deleted file mode 100644 index bc15ea5..0000000 --- a/old/modules/matcher/domain/types/waypoint.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Actor } from './actor.type.'; -import { Point } from '../../../geography/domain/types/point.type'; - -export type Waypoint = { - point: Point; - actors: Actor[]; -}; diff --git a/old/modules/matcher/domain/usecases/match.usecase.ts b/old/modules/matcher/domain/usecases/match.usecase.ts deleted file mode 100644 index 1e0616e..0000000 --- a/old/modules/matcher/domain/usecases/match.usecase.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Mapper } from '@automapper/core'; -import { InjectMapper } from '@automapper/nestjs'; -import { QueryHandler } from '@nestjs/cqrs'; -import { MatchQuery } from '../../queries/match.query'; -import { Match } from '../entities/ecosystem/match'; -import { ICollection } from '../../../database/interfaces/collection.interface'; -import { Matcher } from '../entities/engine/matcher'; -import { MESSAGE_PUBLISHER } from '../../../../app.constants'; -import { Inject } from '@nestjs/common'; -import { IPublishMessage } from '../../../../interfaces/message-publisher'; - -@QueryHandler(MatchQuery) -export class MatchUseCase { - constructor( - private readonly matcher: Matcher, - @Inject(MESSAGE_PUBLISHER) - private readonly messagePublisher: IPublishMessage, - @InjectMapper() private readonly mapper: Mapper, - ) {} - - execute = async (matchQuery: MatchQuery): Promise> => { - try { - const data: Match[] = await this.matcher.match(matchQuery); - this.messagePublisher.publish('matcher.match', 'match !'); - return { - data, - total: data.length, - }; - } catch (error) { - const err: Error = error; - this.messagePublisher.publish( - 'logging.matcher.match.crit', - JSON.stringify({ - matchQuery, - error: err.message, - }), - ); - throw error; - } - }; -} - -// const paths = []; -// for (let i = 0; i < 1; i++) { -// paths.push({ -// key: 'route' + i, -// points: [ -// { -// lat: 48.110899, -// lon: -1.68365, -// }, -// { -// lat: 48.131105, -// lon: -1.690067, -// }, -// { -// lat: 48.534769, -// lon: -1.894032, -// }, -// { -// lat: 48.56516, -// lon: -1.923553, -// }, -// { -// lat: 48.622813, -// lon: -1.997177, -// }, -// { -// lat: 48.67846, -// lon: -1.8554, -// }, -// ], -// }); -// } -// const routes = await matchQuery.algorithmSettings.georouter.route(paths, { -// withDistance: false, -// withPoints: true, -// withTime: true, -// }); -// routes.map((route) => console.log(route.route.spacetimePoints)); diff --git a/old/modules/matcher/exceptions/matcher.exception.ts b/old/modules/matcher/exceptions/matcher.exception.ts deleted file mode 100644 index af70214..0000000 --- a/old/modules/matcher/exceptions/matcher.exception.ts +++ /dev/null @@ -1,33 +0,0 @@ -export class MatcherException implements Error { - name: string; - message: string; - - constructor(private _code: number, private _message: string) { - this.name = 'MatcherException'; - this.message = _message; - } - - get code(): number { - return this._code; - } -} - -export enum MatcherExceptionCode { - OK = 0, - CANCELLED = 1, - UNKNOWN = 2, - INVALID_ARGUMENT = 3, - DEADLINE_EXCEEDED = 4, - NOT_FOUND = 5, - ALREADY_EXISTS = 6, - PERMISSION_DENIED = 7, - RESOURCE_EXHAUSTED = 8, - FAILED_PRECONDITION = 9, - ABORTED = 10, - OUT_OF_RANGE = 11, - UNIMPLEMENTED = 12, - INTERNAL = 13, - UNAVAILABLE = 14, - DATA_LOSS = 15, - UNAUTHENTICATED = 16, -} diff --git a/old/modules/matcher/mappers/match.profile.ts b/old/modules/matcher/mappers/match.profile.ts deleted file mode 100644 index c44fef8..0000000 --- a/old/modules/matcher/mappers/match.profile.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createMap, Mapper } from '@automapper/core'; -import { AutomapperProfile, InjectMapper } from '@automapper/nestjs'; -import { Injectable } from '@nestjs/common'; -import { MatchPresenter } from '../adapters/secondaries/match.presenter'; -import { Match } from '../domain/entities/ecosystem/match'; - -@Injectable() -export class MatchProfile extends AutomapperProfile { - constructor(@InjectMapper() mapper: Mapper) { - super(mapper); - } - - override get profile() { - return (mapper: Mapper) => { - createMap(mapper, Match, MatchPresenter); - }; - } -} diff --git a/old/modules/matcher/matcher.module.ts b/old/modules/matcher/matcher.module.ts deleted file mode 100644 index 7b736aa..0000000 --- a/old/modules/matcher/matcher.module.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ConfigModule, ConfigService } from '@nestjs/config'; -import { CqrsModule } from '@nestjs/cqrs'; -import { DatabaseModule } from '../database/database.module'; -import { MatcherController } from './adapters/primaries/matcher.controller'; -import { MatchProfile } from './mappers/match.profile'; -import { MatchUseCase } from './domain/usecases/match.usecase'; -import { CacheModule } from '@nestjs/cache-manager'; -import { RedisClientOptions } from '@liaoliaots/nestjs-redis'; -import { redisStore } from 'cache-manager-ioredis-yet'; -import { DefaultParamsProvider } from './adapters/secondaries/default-params.provider'; -import { GeorouterCreator } from './adapters/secondaries/georouter-creator'; -import { HttpModule } from '@nestjs/axios'; -import { MatcherGeodesic } from './adapters/secondaries/geodesic'; -import { Matcher } from './domain/entities/engine/matcher'; -import { AlgorithmFactoryCreator } from './domain/entities/engine/factory/algorithm-factory-creator'; -import { TimezoneFinder } from './adapters/secondaries/timezone-finder'; -import { GeoTimezoneFinder } from '../geography/adapters/secondaries/geo-timezone-finder'; -import { GeographyModule } from '../geography/geography.module'; -import { TimeConverter } from './adapters/secondaries/time-converter'; -import { MESSAGE_BROKER_PUBLISHER, MESSAGE_PUBLISHER } from 'src/app.constants'; -import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; -import { MessagePublisher } from './adapters/secondaries/message-publisher'; - -@Module({ - imports: [ - GeographyModule, - DatabaseModule, - CqrsModule, - HttpModule, - CacheModule.registerAsync({ - imports: [ConfigModule], - useFactory: async (configService: ConfigService) => ({ - store: await redisStore({ - host: configService.get('REDIS_HOST'), - port: configService.get('REDIS_PORT'), - password: configService.get('REDIS_PASSWORD'), - ttl: configService.get('CACHE_TTL'), - }), - }), - inject: [ConfigService], - }), - ], - controllers: [MatcherController], - providers: [ - MatchProfile, - DefaultParamsProvider, - MatchUseCase, - GeorouterCreator, - MatcherGeodesic, - TimezoneFinder, - TimeConverter, - Matcher, - AlgorithmFactoryCreator, - GeoTimezoneFinder, - { - provide: MESSAGE_BROKER_PUBLISHER, - useClass: MessageBrokerPublisher, - }, - { - provide: MESSAGE_PUBLISHER, - useClass: MessagePublisher, - }, - ], - exports: [], -}) -export class MatcherModule {} diff --git a/old/modules/matcher/queries/match.query.ts b/old/modules/matcher/queries/match.query.ts deleted file mode 100644 index 8ac0388..0000000 --- a/old/modules/matcher/queries/match.query.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { MatchRequest } from '../domain/dtos/match.request'; -import { Geography } from '../domain/entities/ecosystem/geography'; -import { Ad } from '../domain/entities/ecosystem/ad'; -import { Requirement } from '../domain/entities/ecosystem/requirement'; -import { Role } from '../domain/types/role.enum'; -import { AlgorithmSettings } from '../domain/entities/ecosystem/algorithm-settings'; -import { Time } from '../domain/entities/ecosystem/time'; -import { IDefaultParams } from '../domain/types/default-params.type'; -import { IGeorouter } from '../domain/interfaces/georouter.interface'; -import { ICreateGeorouter } from '../domain/interfaces/georouter-creator.interface'; -import { IFindTimezone } from '../../geography/domain/interfaces/timezone-finder.interface'; -import { Mode } from '../domain/types/mode.enum'; -import { IConvertTime } from '../domain/interfaces/time-converter.interface'; - -export class MatchQuery { - private readonly matchRequest: MatchRequest; - private readonly defaultParams: IDefaultParams; - private readonly georouterCreator: ICreateGeorouter; - mode: Mode; - ad: Ad; - roles: Role[]; - time: Time; - geography: Geography; - exclusions: string[]; - requirement: Requirement; - algorithmSettings: AlgorithmSettings; - georouter: IGeorouter; - timezoneFinder: IFindTimezone; - timeConverter: IConvertTime; - - constructor( - matchRequest: MatchRequest, - defaultParams: IDefaultParams, - georouterCreator: ICreateGeorouter, - timezoneFinder: IFindTimezone, - timeConverter: IConvertTime, - ) { - this.matchRequest = matchRequest; - this.defaultParams = defaultParams; - this.georouterCreator = georouterCreator; - this.timezoneFinder = timezoneFinder; - this.timeConverter = timeConverter; - this.setMode(); - this.setAd(); - this.setRoles(); - this.setGeography(); - this.setTime(); - this.setRequirement(); - this.setAlgorithmSettings(); - this.setExclusions(); - } - - createRoutes = (): void => { - this.geography.createRoutes(this.roles, this.algorithmSettings.georouter); - }; - - private setMode = (): void => { - this.mode = this.matchRequest.mode ?? Mode.MATCH; - }; - - private setAd = (): void => { - this.ad = new Ad( - this.matchRequest, - this.defaultParams.DEFAULT_UUID, - this.defaultParams.MARGIN_DURATION, - ); - this.ad.init(); - }; - - private setRoles = (): void => { - this.roles = []; - if (this.matchRequest.driver) this.roles.push(Role.DRIVER); - if (this.matchRequest.passenger) this.roles.push(Role.PASSENGER); - if (this.roles.length == 0) this.roles.push(Role.PASSENGER); - }; - - private setGeography = (): void => { - this.geography = new Geography( - this.matchRequest, - { - timezone: this.defaultParams.DEFAULT_TIMEZONE, - finder: this.timezoneFinder, - }, - this.ad, - ); - this.geography.init(); - if (this.geography.timezones.length > 0) - this.matchRequest.timezone = this.geography.timezones[0]; - }; - - private setTime = (): void => { - this.time = new Time( - this.matchRequest, - this.defaultParams.MARGIN_DURATION, - this.defaultParams.VALIDITY_DURATION, - this.timeConverter, - ); - this.time.init(); - }; - - private setRequirement = (): void => { - this.requirement = new Requirement( - this.matchRequest, - this.defaultParams.DEFAULT_SEATS, - ); - }; - - private setAlgorithmSettings = (): void => { - this.algorithmSettings = new AlgorithmSettings( - this.matchRequest, - this.defaultParams.DEFAULT_ALGORITHM_SETTINGS, - this.time.frequency, - this.georouterCreator, - ); - }; - - private setExclusions = (): void => { - this.exclusions = []; - if (this.matchRequest.uuid) this.exclusions.push(this.matchRequest.uuid); - if (this.matchRequest.exclusions) - this.exclusions.push(...this.matchRequest.exclusions); - }; -} diff --git a/old/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts deleted file mode 100644 index a23a4d0..0000000 --- a/old/modules/matcher/tests/unit/adapters/secondaries/default-params.provider.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ConfigService } from '@nestjs/config'; -import { Test, TestingModule } from '@nestjs/testing'; -import { DefaultParamsProvider } from '../../../../adapters/secondaries/default-params.provider'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; - -const mockConfigService = { - get: jest.fn().mockImplementationOnce(() => 99), -}; - -describe('DefaultParamsProvider', () => { - let defaultParamsProvider: DefaultParamsProvider; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - DefaultParamsProvider, - { - provide: ConfigService, - useValue: mockConfigService, - }, - ], - }).compile(); - - defaultParamsProvider = module.get( - DefaultParamsProvider, - ); - }); - - it('should be defined', () => { - expect(defaultParamsProvider).toBeDefined(); - }); - - it('should provide default params', async () => { - const params: IDefaultParams = defaultParamsProvider.getParams(); - expect(params.DEFAULT_UUID).toBe(99); - }); -}); diff --git a/old/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts deleted file mode 100644 index 6e878a9..0000000 --- a/old/modules/matcher/tests/unit/adapters/secondaries/geodesic.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { MatcherGeodesic } from '../../../../adapters/secondaries/geodesic'; -import { Geodesic } from '../../../../../geography/adapters/secondaries/geodesic'; - -const mockGeodesic = { - inverse: jest.fn().mockImplementation(() => ({ - azimuth: 45, - distance: 50000, - })), -}; - -describe('Matcher geodesic', () => { - let matcherGeodesic: MatcherGeodesic; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - MatcherGeodesic, - { - provide: Geodesic, - useValue: mockGeodesic, - }, - ], - }).compile(); - - matcherGeodesic = module.get(MatcherGeodesic); - }); - - it('should be defined', () => { - expect(matcherGeodesic).toBeDefined(); - }); - it('should get inverse values', () => { - const inv = matcherGeodesic.inverse(0, 0, 1, 1); - expect(Math.round(inv.azimuth)).toBe(45); - expect(Math.round(inv.distance)).toBe(50000); - }); -}); diff --git a/old/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts deleted file mode 100644 index 543991b..0000000 --- a/old/modules/matcher/tests/unit/adapters/secondaries/georouter-creator.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { GeorouterCreator } from '../../../../adapters/secondaries/georouter-creator'; -import { GraphhopperGeorouter } from '../../../../adapters/secondaries/graphhopper-georouter'; -import { HttpService } from '@nestjs/axios'; -import { MatcherGeodesic } from '../../../../adapters/secondaries/geodesic'; - -const mockHttpService = jest.fn(); -const mockMatcherGeodesic = jest.fn(); - -describe('Georouter creator', () => { - let georouterCreator: GeorouterCreator; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - GeorouterCreator, - { - provide: HttpService, - useValue: mockHttpService, - }, - { - provide: MatcherGeodesic, - useValue: mockMatcherGeodesic, - }, - ], - }).compile(); - - georouterCreator = module.get(GeorouterCreator); - }); - - it('should be defined', () => { - expect(georouterCreator).toBeDefined(); - }); - it('should create a graphhopper georouter', () => { - const georouter = georouterCreator.create( - 'graphhopper', - 'http://localhost', - ); - expect(georouter).toBeInstanceOf(GraphhopperGeorouter); - }); - it('should throw an exception if georouter type is unknown', () => { - expect(() => - georouterCreator.create('unknown', 'http://localhost'), - ).toThrow(); - }); -}); diff --git a/old/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts deleted file mode 100644 index fdfef4b..0000000 --- a/old/modules/matcher/tests/unit/adapters/secondaries/graphhopper-georouter.spec.ts +++ /dev/null @@ -1,456 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { HttpService } from '@nestjs/axios'; -import { GeorouterCreator } from '../../../../adapters/secondaries/georouter-creator'; -import { IGeorouter } from '../../../../domain/interfaces/georouter.interface'; -import { of } from 'rxjs'; -import { AxiosError } from 'axios'; -import { MatcherGeodesic } from '../../../../adapters/secondaries/geodesic'; - -const mockHttpService = { - get: jest - .fn() - .mockImplementationOnce(() => { - throw new AxiosError('Axios error !'); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - snapped_waypoints: { - coordinates: [ - [0, 0], - [10, 10], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [10, 10], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - details: { - time: [ - [0, 1, 180000], - [1, 2, 180000], - [2, 3, 180000], - [3, 4, 180000], - [4, 5, 180000], - [5, 6, 180000], - [6, 7, 180000], - [7, 9, 360000], - [9, 10, 180000], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [10, 10], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [5, 5], - [10, 10], - ], - }, - details: { - time: [ - [0, 1, 180000], - [1, 2, 180000], - [2, 3, 180000], - [3, 4, 180000], - [4, 7, 540000], - [7, 9, 360000], - [9, 10, 180000], - ], - }, - }, - ], - }, - }); - }) - .mockImplementationOnce(() => { - return of({ - status: 200, - data: { - paths: [ - { - distance: 50000, - time: 1800000, - points: { - coordinates: [ - [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - [7, 7], - [8, 8], - [9, 9], - [10, 10], - ], - }, - snapped_waypoints: { - coordinates: [ - [0, 0], - [5, 5], - [10, 10], - ], - }, - details: { - time: [ - [0, 1, 180000], - [1, 2, 180000], - [2, 3, 180000], - [3, 4, 180000], - [4, 7, 540000], - [7, 9, 360000], - [9, 10, 180000], - ], - }, - instructions: [ - { - distance: 25000, - sign: 0, - interval: [0, 5], - text: 'Some instructions', - time: 900000, - }, - { - distance: 0, - sign: 5, - interval: [5, 5], - text: 'Waypoint 1', - time: 0, - }, - { - distance: 25000, - sign: 2, - interval: [5, 10], - text: 'Some instructions', - time: 900000, - }, - { - distance: 0.0, - sign: 4, - interval: [10, 10], - text: 'Arrive at destination', - time: 0, - }, - ], - }, - ], - }, - }); - }), -}; - -const mockMatcherGeodesic = { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - inverse: jest.fn().mockImplementation(() => ({ - azimuth: 45, - distance: 50000, - })), -}; - -describe('Graphhopper Georouter', () => { - let georouterCreator: GeorouterCreator; - let graphhopperGeorouter: IGeorouter; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - GeorouterCreator, - { - provide: HttpService, - useValue: mockHttpService, - }, - { - provide: MatcherGeodesic, - useValue: mockMatcherGeodesic, - }, - ], - }).compile(); - - georouterCreator = module.get(GeorouterCreator); - graphhopperGeorouter = georouterCreator.create( - 'graphhopper', - 'http://localhost', - ); - }); - - it('should be defined', () => { - expect(graphhopperGeorouter).toBeDefined(); - }); - - describe('route function', () => { - it('should fail on axios error', async () => { - await expect( - graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 1, - lon: 1, - }, - ], - }, - ], - { - withDistance: false, - withPoints: false, - withTime: false, - }, - ), - ).rejects.toBeInstanceOf(Error); - }); - - it('should create one route with all settings to false', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: false, - withTime: false, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.distance).toBe(50000); - }); - - it('should create one route with points', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: true, - withTime: false, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.distance).toBe(50000); - expect(routes[0].route.duration).toBe(1800); - expect(routes[0].route.fwdAzimuth).toBe(45); - expect(routes[0].route.backAzimuth).toBe(225); - expect(routes[0].route.points.length).toBe(11); - }); - - it('should create one route with points and time', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: true, - withTime: true, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.spacetimePoints.length).toBe(2); - expect(routes[0].route.spacetimePoints[1].duration).toBe(1800); - expect(routes[0].route.spacetimePoints[1].distance).toBeUndefined(); - }); - - it('should create one route with points and missed waypoints extrapolations', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 5, - lon: 5, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: false, - withPoints: true, - withTime: true, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.spacetimePoints.length).toBe(3); - expect(routes[0].route.distance).toBe(50000); - expect(routes[0].route.duration).toBe(1800); - expect(routes[0].route.fwdAzimuth).toBe(45); - expect(routes[0].route.backAzimuth).toBe(225); - expect(routes[0].route.points.length).toBe(9); - }); - - it('should create one route with points, time and distance', async () => { - const routes = await graphhopperGeorouter.route( - [ - { - key: 'route1', - points: [ - { - lat: 0, - lon: 0, - }, - { - lat: 10, - lon: 10, - }, - ], - }, - ], - { - withDistance: true, - withPoints: true, - withTime: true, - }, - ); - expect(routes).toHaveLength(1); - expect(routes[0].route.spacetimePoints.length).toBe(3); - expect(routes[0].route.spacetimePoints[1].duration).toBe(990); - expect(routes[0].route.spacetimePoints[1].distance).toBe(25000); - }); - }); -}); diff --git a/old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts deleted file mode 100644 index a60708f..0000000 --- a/old/modules/matcher/tests/unit/adapters/secondaries/message-publisher.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { MessagePublisher } from '../../../../adapters/secondaries/message-publisher'; -import { MESSAGE_BROKER_PUBLISHER } from '../../../../../../app.constants'; - -const mockMessageBrokerPublisher = { - publish: jest.fn().mockImplementation(), -}; - -describe('Messager', () => { - let messagePublisher: MessagePublisher; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - MessagePublisher, - { - provide: MESSAGE_BROKER_PUBLISHER, - useValue: mockMessageBrokerPublisher, - }, - ], - }).compile(); - - messagePublisher = module.get(MessagePublisher); - }); - - it('should be defined', () => { - expect(messagePublisher).toBeDefined(); - }); - - it('should publish a message', async () => { - jest.spyOn(mockMessageBrokerPublisher, 'publish'); - messagePublisher.publish('ad.info', 'my-test'); - expect(mockMessageBrokerPublisher.publish).toHaveBeenCalledTimes(1); - }); -}); diff --git a/old/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts b/old/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts deleted file mode 100644 index 63d8462..0000000 --- a/old/modules/matcher/tests/unit/adapters/secondaries/timezone-finder.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { TimezoneFinder } from '../../../../adapters/secondaries/timezone-finder'; -import { GeoTimezoneFinder } from '../../../../../geography/adapters/secondaries/geo-timezone-finder'; - -const mockGeoTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -describe('Timezone Finder', () => { - let timezoneFinder: TimezoneFinder; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [], - providers: [ - TimezoneFinder, - { - provide: GeoTimezoneFinder, - useValue: mockGeoTimezoneFinder, - }, - ], - }).compile(); - - timezoneFinder = module.get(TimezoneFinder); - }); - - it('should be defined', () => { - expect(timezoneFinder).toBeDefined(); - }); - it('should get timezone for Nancy(France) as Europe/Paris', () => { - const timezones = timezoneFinder.timezones(6.179373, 48.687913); - expect(timezones.length).toBe(1); - expect(timezones[0]).toBe('Europe/Paris'); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts deleted file mode 100644 index 3480b2b..0000000 --- a/old/modules/matcher/tests/unit/domain/ecosystem/geography.spec.ts +++ /dev/null @@ -1,315 +0,0 @@ -import { Ad } from '../../../../domain/entities/ecosystem/ad'; -import { - Geography, - RouteKey, -} from '../../../../domain/entities/ecosystem/geography'; -import { Role } from '../../../../domain/types/role.enum'; -import { NamedRoute } from '../../../../domain/entities/ecosystem/named-route'; -import { MatcherRoute } from '../../../../domain/entities/ecosystem/matcher-route'; -import { IGeodesic } from '../../../../../geography/domain/interfaces/geodesic.interface'; -import { PointType } from '../../../../../geography/domain/types/point-type.enum'; - -const ad: Ad = new Ad( - { - uuid: '774aaab2-77df-4c6c-b70d-7b9e972e5bbc', - }, - '00000000-0000-0000-0000-000000000000', - 900, -); - -const mockGeodesic: IGeodesic = { - inverse: jest.fn().mockImplementation(() => ({ - azimuth: 45, - distance: 50000, - })), -}; - -const mockGeorouter = { - route: jest - .fn() - .mockImplementationOnce(() => { - return [ - { - key: RouteKey.COMMON, - route: new MatcherRoute(mockGeodesic), - }, - ]; - }) - .mockImplementationOnce(() => { - return [ - { - key: RouteKey.DRIVER, - route: new MatcherRoute(mockGeodesic), - }, - { - key: RouteKey.PASSENGER, - route: new MatcherRoute(mockGeodesic), - }, - ]; - }) - .mockImplementationOnce(() => { - return [ - { - key: RouteKey.DRIVER, - route: new MatcherRoute(mockGeodesic), - }, - ]; - }) - .mockImplementationOnce(() => { - return [ - { - key: RouteKey.PASSENGER, - route: new MatcherRoute(mockGeodesic), - }, - ]; - }), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -describe('Geography entity', () => { - it('should be defined', () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - expect(geography).toBeDefined(); - }); - - describe('init', () => { - it('should initialize a geography request with point types', () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - type: PointType.LOCALITY, - }, - { - lat: 50.630992, - lon: 3.045432, - type: PointType.LOCALITY, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - geography.init(); - expect(geography.originType).toBe(PointType.LOCALITY); - expect(geography.destinationType).toBe(PointType.LOCALITY); - }); - it('should throw an exception if waypoints are empty', () => { - const geography = new Geography( - { - waypoints: [], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - expect(() => geography.init()).toThrow(); - }); - it('should throw an exception if only one waypoint is provided', () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - expect(() => geography.init()).toThrow(); - }); - it('should throw an exception if a waypoint has invalid longitude', () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 201.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - expect(() => geography.init()).toThrow(); - }); - it('should throw an exception if a waypoint has invalid latitude', () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 250.630992, - lon: 3.045432, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - expect(() => geography.init()).toThrow(); - }); - }); - - describe('create route', () => { - it('should create routes as driver and passenger', async () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - geography.init(); - await geography.createRoutes( - [Role.DRIVER, Role.PASSENGER], - mockGeorouter, - ); - expect(geography.driverRoute.waypoints.length).toBe(2); - expect(geography.passengerRoute.waypoints.length).toBe(2); - }); - - it('should create routes as driver and passenger with 3 waypoints', async () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 49.781215, - lon: 2.198475, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - geography.init(); - await geography.createRoutes( - [Role.DRIVER, Role.PASSENGER], - mockGeorouter, - ); - expect(geography.driverRoute.waypoints.length).toBe(3); - expect(geography.passengerRoute.waypoints.length).toBe(2); - }); - - it('should create routes as driver', async () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - geography.init(); - await geography.createRoutes([Role.DRIVER], mockGeorouter); - expect(geography.driverRoute.waypoints.length).toBe(2); - expect(geography.passengerRoute).toBeUndefined(); - }); - - it('should create routes as passenger', async () => { - const geography = new Geography( - { - waypoints: [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ], - }, - { - timezone: 'Europe/Paris', - finder: mockTimezoneFinder, - }, - ad, - ); - geography.init(); - await geography.createRoutes([Role.PASSENGER], mockGeorouter); - expect(geography.passengerRoute.waypoints.length).toBe(2); - expect(geography.driverRoute).toBeUndefined(); - }); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts deleted file mode 100644 index feb1b6e..0000000 --- a/old/modules/matcher/tests/unit/domain/ecosystem/matcher-route.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { MatcherRoute } from '../../../../domain/entities/ecosystem/matcher-route'; -import { SpacetimePoint } from '../../../../domain/entities/ecosystem/spacetime-point'; -import { Waypoint } from '../../../../domain/entities/ecosystem/waypoint'; - -const mockGeodesic = { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - inverse: jest.fn().mockImplementation((lon1, lat1, lon2, lat2) => { - return lon1 == 0 - ? { - azimuth: 45, - distance: 50000, - } - : { - azimuth: -45, - distance: 60000, - }; - }), -}; - -describe('Matcher route entity', () => { - it('should be defined', () => { - const route = new MatcherRoute(mockGeodesic); - expect(route).toBeDefined(); - }); - it('should set waypoints and geodesic values for a route', () => { - const route = new MatcherRoute(mockGeodesic); - const waypoint1: Waypoint = new Waypoint({ - lon: 0, - lat: 0, - }); - const waypoint2: Waypoint = new Waypoint({ - lon: 10, - lat: 10, - }); - route.setWaypoints([waypoint1, waypoint2]); - expect(route.waypoints.length).toBe(2); - expect(route.fwdAzimuth).toBe(45); - expect(route.backAzimuth).toBe(225); - expect(route.distanceAzimuth).toBe(50000); - }); - it('should set points and geodesic values for a route', () => { - const route = new MatcherRoute(mockGeodesic); - route.setPoints([ - { - lon: 10, - lat: 10, - }, - { - lon: 20, - lat: 20, - }, - ]); - expect(route.points.length).toBe(2); - expect(route.fwdAzimuth).toBe(315); - expect(route.backAzimuth).toBe(135); - expect(route.distanceAzimuth).toBe(60000); - }); - it('should set spacetimePoints for a route', () => { - const route = new MatcherRoute(mockGeodesic); - const spacetimePoint1 = new SpacetimePoint({ lon: 0, lat: 0 }, 0, 0); - const spacetimePoint2 = new SpacetimePoint({ lon: 10, lat: 10 }, 500, 5000); - route.setSpacetimePoints([spacetimePoint1, spacetimePoint2]); - expect(route.spacetimePoints.length).toBe(2); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts deleted file mode 100644 index 974d93e..0000000 --- a/old/modules/matcher/tests/unit/domain/ecosystem/person.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Ad } from '../../../../domain/entities/ecosystem/ad'; - -const DEFAULT_UUID = '00000000-0000-0000-0000-000000000000'; -const MARGIN_DURATION = 900; - -describe('Ad entity', () => { - it('should be defined', () => { - const ad = new Ad( - { - uuid: '774aaab2-77df-4c6c-b70d-7b9e972e5bbc', - }, - DEFAULT_UUID, - MARGIN_DURATION, - ); - expect(ad).toBeDefined(); - }); - - describe('init', () => { - it('should initialize an ad with a uuid', () => { - const ad = new Ad( - { - uuid: '774aaab2-77df-4c6c-b70d-7b9e972e5bbc', - }, - DEFAULT_UUID, - MARGIN_DURATION, - ); - ad.init(); - expect(ad.uuid).toBe('774aaab2-77df-4c6c-b70d-7b9e972e5bbc'); - expect(ad.marginDurations[0]).toBe(900); - expect(ad.marginDurations[6]).toBe(900); - }); - it('should initialize an ad without a uuid', () => { - const ad = new Ad({}, DEFAULT_UUID, MARGIN_DURATION); - ad.init(); - expect(ad.uuid).toBe('00000000-0000-0000-0000-000000000000'); - expect(ad.marginDurations[0]).toBe(900); - expect(ad.marginDurations[6]).toBe(900); - }); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts b/old/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts deleted file mode 100644 index 1df151d..0000000 --- a/old/modules/matcher/tests/unit/domain/ecosystem/time.spec.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { Time } from '../../../../domain/entities/ecosystem/time'; - -const MARGIN_DURATION = 900; -const VALIDITY_DURATION = 365; -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -describe('Time entity', () => { - it('should be defined', () => { - const time = new Time( - { - departure: '2023-04-01 12:24:00', - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(time).toBeDefined(); - }); - - describe('init', () => { - it('should initialize a punctual time request', () => { - const time = new Time( - { - departure: '2023-04-01 12:24:00', - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - time.init(); - expect(time.fromDate.getFullYear()).toBe( - new Date('2023-04-01 12:24:00').getFullYear(), - ); - }); - it('should initialize a punctual time request with specific single margin duration', () => { - const time = new Time( - { - departure: '2023-04-01 12:24:00', - marginDuration: 300, - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - time.init(); - expect(time.marginDurations['tue']).toBe(300); - }); - it('should initialize a punctual time request with specific margin durations', () => { - const time = new Time( - { - departure: '2023-04-01 12:24:00', - marginDurations: { - sat: 350, - }, - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - time.init(); - expect(time.marginDurations['tue']).toBe(900); - expect(time.marginDurations['sat']).toBe(350); - }); - it('should initialize a punctual time request with specific single margin duration and margin durations', () => { - const time = new Time( - { - departure: '2023-04-01 12:24:00', - marginDuration: 500, - marginDurations: { - sat: 350, - }, - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - time.init(); - expect(time.marginDurations['tue']).toBe(500); - expect(time.marginDurations['sat']).toBe(350); - }); - it('should initialize a recurrent time request', () => { - const time = new Time( - { - fromDate: '2023-04-01', - schedule: { - mon: '12:00', - }, - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - time.init(); - expect(time.fromDate.getFullYear()).toBe( - new Date('2023-04-01').getFullYear(), - ); - }); - it('should throw an exception if no date is provided', () => { - const time = new Time( - {}, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - it('should throw an exception if punctual date is invalid', () => { - const time = new Time( - { - departure: '2023-15-01 12:24:00', - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - it('should throw an exception if recurrent fromDate is invalid', () => { - const time = new Time( - { - fromDate: '2023-15-01', - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - it('should throw an exception if recurrent toDate is invalid', () => { - const time = new Time( - { - fromDate: '2023-04-01', - toDate: '2023-13-01', - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - it('should throw an exception if recurrent toDate is before fromDate', () => { - const time = new Time( - { - fromDate: '2023-04-01', - toDate: '2023-03-01', - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - it('should throw an exception if schedule is missing', () => { - const time = new Time( - { - fromDate: '2023-04-01', - toDate: '2024-03-31', - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - it('should throw an exception if schedule is empty', () => { - const time = new Time( - { - fromDate: '2023-04-01', - toDate: '2024-03-31', - schedule: {}, - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - it('should throw an exception if schedule is invalid', () => { - const time = new Time( - { - fromDate: '2023-04-01', - toDate: '2024-03-31', - schedule: { - mon: '32:78', - }, - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); - }); - it('should throw an exception if margin durations is provided but empty', () => { - const time = new Time( - { - departure: '2023-04-01 12:24:00', - marginDurations: {}, - }, - MARGIN_DURATION, - VALIDITY_DURATION, - mockTimeConverter, - ); - expect(() => time.init()).toThrow(); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts b/old/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts deleted file mode 100644 index 7c715a6..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/algorithm-factory-creator.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { AlgorithmFactoryCreator } from '../../../../domain/entities/engine/factory/algorithm-factory-creator'; -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { ClassicAlgorithmFactory } from '../../../../domain/entities/engine/factory/classic'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('AlgorithmFactoryCreator', () => { - it('should be defined', () => { - expect(new AlgorithmFactoryCreator()).toBeDefined(); - }); - - it('should create a classic algorithm factory', () => { - expect(new AlgorithmFactoryCreator().create(matchQuery)).toBeInstanceOf( - ClassicAlgorithmFactory, - ); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts deleted file mode 100644 index 74e2494..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/algorithm-factory.abstract.spec.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { AlgorithmFactory } from '../../../../domain/entities/engine/factory/algorithm-factory.abstract'; -import { Processor } from '../../../../domain/entities/engine/processor/processor.abstract'; -import { Selector } from '../../../../domain/entities/engine/selector/selector.abstract'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -class FakeSelector extends Selector { - select = (): Promise => { - return Promise.resolve([new Candidate()]); - }; -} - -class FakeProcessor extends Processor { - execute = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} - -class FakeAlgorithmFactory extends AlgorithmFactory { - createSelector = (): Selector => { - return new FakeSelector(matchQuery); - }; - createProcessors = (): Processor[] => { - return [new FakeProcessor(matchQuery)]; - }; -} - -describe('AlgorithmFactory', () => { - it('should create an extended class', () => { - expect(new FakeAlgorithmFactory(matchQuery)).toBeDefined(); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts deleted file mode 100644 index 4859189..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/classic-algorithm-factory.spec.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { ClassicSelector } from '../../../../domain/entities/engine/selector/classic.selector'; -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { ClassicAlgorithmFactory } from '../../../../domain/entities/engine/factory/classic'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('ClassicAlgorithmFactory', () => { - it('should be defined', () => { - expect(new ClassicAlgorithmFactory(matchQuery)).toBeDefined(); - }); - - it('should create a classic selector', () => { - const classicAlgorithmFactory: ClassicAlgorithmFactory = - new ClassicAlgorithmFactory(matchQuery); - expect(classicAlgorithmFactory.createSelector()).toBeInstanceOf( - ClassicSelector, - ); - }); - - it('should create processors', () => { - const classicAlgorithmFactory: ClassicAlgorithmFactory = - new ClassicAlgorithmFactory(matchQuery); - expect(classicAlgorithmFactory.createProcessors().length).toBe(6); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts deleted file mode 100644 index ea3b506..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/classic-geo.filter.processor.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { ClassicGeoFilter } from '../../../../domain/entities/engine/processor/filter/geofilter/classic.filter.processor'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('ClassicGeoFilter', () => { - it('should be defined', () => { - expect(new ClassicGeoFilter(matchQuery)).toBeDefined(); - }); - - it('should filter candidates', () => { - const candidates = [new Candidate(), new Candidate()]; - const classicWaypointCompleter: ClassicGeoFilter = new ClassicGeoFilter( - matchQuery, - ); - expect(classicWaypointCompleter.filter(candidates).length).toBe(2); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts deleted file mode 100644 index c489684..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/classic-time.filter.processor.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { ClassicTimeFilter } from '../../../../domain/entities/engine/processor/filter/timefilter/classic.filter.processor'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('ClassicTimeFilter', () => { - it('should be defined', () => { - expect(new ClassicTimeFilter(matchQuery)).toBeDefined(); - }); - - it('should filter candidates', () => { - const candidates = [new Candidate(), new Candidate()]; - const classicWaypointCompleter: ClassicTimeFilter = new ClassicTimeFilter( - matchQuery, - ); - expect(classicWaypointCompleter.filter(candidates).length).toBe(2); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts deleted file mode 100644 index 68cfca7..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/classic-waypoint.completer.processor.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { ClassicWaypointsCompleter } from '../../../../domain/entities/engine/processor/completer/classic-waypoint.completer.processor'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('ClassicWaypointCompleter', () => { - it('should be defined', () => { - expect(new ClassicWaypointsCompleter(matchQuery)).toBeDefined(); - }); - - it('should complete candidates', () => { - const candidates = [new Candidate(), new Candidate()]; - const classicWaypointCompleter: ClassicWaypointsCompleter = - new ClassicWaypointsCompleter(matchQuery); - expect(classicWaypointCompleter.complete(candidates).length).toBe(2); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts b/old/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts deleted file mode 100644 index 19dcfdb..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/classic.selector.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { ClassicSelector } from '../../../../domain/entities/engine/selector/classic.selector'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('ClassicSelector', () => { - it('should be defined', () => { - expect(new ClassicSelector(matchQuery)).toBeDefined(); - }); - - it('should select candidates', async () => { - const classicSelector: ClassicSelector = new ClassicSelector(matchQuery); - const candidates: Candidate[] = await classicSelector.select(); - expect(candidates.length).toBe(0); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts deleted file mode 100644 index 7d4bdb9..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/completer.abstract.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Completer } from '../../../../domain/entities/engine/processor/completer/completer.abstract'; -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -class FakeCompleter extends Completer { - complete = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} - -describe('Completer', () => { - it('should create an extended class', () => { - expect(new FakeCompleter(matchQuery)).toBeDefined(); - }); - - it('should call complete method', () => { - const fakeCompleter: Completer = new FakeCompleter(matchQuery); - const completerSpy = jest.spyOn(fakeCompleter, 'complete'); - fakeCompleter.execute([new Candidate()]); - expect(completerSpy).toHaveBeenCalled(); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts deleted file mode 100644 index 3e6ceb6..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/filter.abstract.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Filter } from '../../../../domain/entities/engine/processor/filter/filter.abstract'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -class FakeFilter extends Filter { - filter = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} - -describe('Filter', () => { - it('should create an extended class', () => { - expect(new FakeFilter(matchQuery)).toBeDefined(); - }); - - it('should call complete method', () => { - const fakeFilter: Filter = new FakeFilter(matchQuery); - const filterSpy = jest.spyOn(fakeFilter, 'filter'); - fakeFilter.execute([new Candidate()]); - expect(filterSpy).toHaveBeenCalled(); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts deleted file mode 100644 index 85bd6d8..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/journey.completer.processor.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { JourneyCompleter } from '../../../../domain/entities/engine/processor/completer/journey.completer.processor'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('JourneyCompleter', () => { - it('should be defined', () => { - expect(new JourneyCompleter(matchQuery)).toBeDefined(); - }); - - it('should complete candidates', () => { - const candidates = [new Candidate(), new Candidate()]; - const journeyCompleter: JourneyCompleter = new JourneyCompleter(matchQuery); - expect(journeyCompleter.complete(candidates).length).toBe(2); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/matcher.spec.ts b/old/modules/matcher/tests/unit/domain/engine/matcher.spec.ts deleted file mode 100644 index 5b73254..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/matcher.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Matcher } from '../../../../domain/entities/engine/matcher'; - -const mockAlgorithmFactoryCreator = { - create: jest.fn().mockReturnValue({ - createSelector: jest.fn().mockReturnValue({ - select: jest.fn(), - }), - createProcessors: jest.fn().mockReturnValue([ - { - execute: jest.fn(), - }, - ]), - }), -}; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('Matcher', () => { - it('should be defined', () => { - expect(new Matcher(mockAlgorithmFactoryCreator)).toBeDefined(); - }); - - it('should return matches', async () => { - const matcher = new Matcher(mockAlgorithmFactoryCreator); - const matches = await matcher.match(matchQuery); - expect(matches.length).toBe(1); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts deleted file mode 100644 index c83eb82..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/processor.abstract.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { Processor } from '../../../../domain/entities/engine/processor/processor.abstract'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn().mockImplementation(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -class FakeProcessor extends Processor { - execute = (candidates: Candidate[]): Candidate[] => { - return candidates; - }; -} - -describe('Processor', () => { - it('should create an extended class', () => { - expect(new FakeProcessor(matchQuery)).toBeDefined(); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts b/old/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts deleted file mode 100644 index cdd2a5a..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/route.completer.processor.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { RouteCompleter } from '../../../../domain/entities/engine/processor/completer/route.completer.processor'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -describe('RouteCompleter', () => { - it('should be defined', () => { - expect(new RouteCompleter(matchQuery)).toBeDefined(); - }); - - it('should complete candidates', () => { - const candidates = [new Candidate(), new Candidate()]; - const routeCompleter: RouteCompleter = new RouteCompleter(matchQuery); - expect(routeCompleter.complete(candidates).length).toBe(2); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts b/old/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts deleted file mode 100644 index 677e43f..0000000 --- a/old/modules/matcher/tests/unit/domain/engine/selector.abstract.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { MatchRequest } from '../../../../domain/dtos/match.request'; -import { Candidate } from '../../../../domain/entities/engine/candidate'; -import { AlgorithmType } from '../../../../domain/types/algorithm.enum'; -import { IDefaultParams } from '../../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../../queries/match.query'; -import { Selector } from '../../../../domain/entities/engine/selector/selector.abstract'; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.departure = '2023-04-01 12:00'; -matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, -); - -class FakeSelector extends Selector { - select = (): Promise => { - return Promise.resolve([new Candidate()]); - }; -} - -describe('Selector', () => { - it('should create an extended class', () => { - expect(new FakeSelector(matchQuery)).toBeDefined(); - }); -}); diff --git a/old/modules/matcher/tests/unit/domain/match.usecase.spec.ts b/old/modules/matcher/tests/unit/domain/match.usecase.spec.ts deleted file mode 100644 index ef7512a..0000000 --- a/old/modules/matcher/tests/unit/domain/match.usecase.spec.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { MatchUseCase } from '../../../domain/usecases/match.usecase'; -import { MatchRequest } from '../../../domain/dtos/match.request'; -import { MatchQuery } from '../../../queries/match.query'; -import { AutomapperModule } from '@automapper/nestjs'; -import { classes } from '@automapper/classes'; -import { IDefaultParams } from '../../../domain/types/default-params.type'; -import { AlgorithmType } from '../../../domain/types/algorithm.enum'; -import { Matcher } from '../../../domain/entities/engine/matcher'; -import { Match } from '../../../domain/entities/ecosystem/match'; -import { - MatcherException, - MatcherExceptionCode, -} from '../../../exceptions/matcher.exception'; -import { MESSAGE_PUBLISHER } from '../../../../../app.constants'; - -const mockMatcher = { - match: jest - .fn() - .mockImplementationOnce(() => [new Match(), new Match(), new Match()]) - .mockImplementationOnce(() => { - throw new MatcherException( - MatcherExceptionCode.INTERNAL, - 'Something terrible happened !', - ); - }), -}; - -const mockMessagePublisher = { - publish: jest.fn().mockImplementation(), -}; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const matchRequest: MatchRequest = new MatchRequest(); -matchRequest.waypoints = [ - { - lon: 1.093912, - lat: 49.440041, - }, - { - lat: 50.630992, - lon: 3.045432, - }, -]; -matchRequest.departure = '2023-04-01 12:23:00'; - -describe('MatchUseCase', () => { - let matchUseCase: MatchUseCase; - - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })], - providers: [ - { - provide: MESSAGE_PUBLISHER, - useValue: mockMessagePublisher, - }, - { - provide: Matcher, - useValue: mockMatcher, - }, - MatchUseCase, - ], - }).compile(); - - matchUseCase = module.get(MatchUseCase); - }); - - it('should be defined', () => { - expect(matchUseCase).toBeDefined(); - }); - - describe('execute', () => { - it('should return matches', async () => { - const matches = await matchUseCase.execute( - new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ), - ); - expect(matches.total).toBe(3); - }); - - it('should throw an exception when error occurs', async () => { - await expect( - matchUseCase.execute( - new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ), - ), - ).rejects.toBeInstanceOf(MatcherException); - }); - }); -}); diff --git a/old/modules/matcher/tests/unit/queries/match.query.spec.ts b/old/modules/matcher/tests/unit/queries/match.query.spec.ts deleted file mode 100644 index b11a0e5..0000000 --- a/old/modules/matcher/tests/unit/queries/match.query.spec.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { MatchRequest } from '../../../domain/dtos/match.request'; -import { Role } from '../../../domain/types/role.enum'; -import { IDefaultParams } from '../../../domain/types/default-params.type'; -import { MatchQuery } from '../../../queries/match.query'; -import { AlgorithmType } from '../../../domain/types/algorithm.enum'; -import { Frequency } from '../../../../ad/domain/types/frequency.enum'; -import { Mode } from '../../../domain/types/mode.enum'; - -const defaultParams: IDefaultParams = { - DEFAULT_UUID: '00000000-0000-0000-0000-000000000000', - MARGIN_DURATION: 900, - VALIDITY_DURATION: 365, - DEFAULT_TIMEZONE: 'Europe/Paris', - DEFAULT_SEATS: 3, - DEFAULT_ALGORITHM_SETTINGS: { - ALGORITHM: AlgorithmType.CLASSIC, - STRICT: false, - REMOTENESS: 15000, - USE_PROPORTION: true, - PROPORTION: 0.3, - USE_AZIMUTH: true, - AZIMUTH_MARGIN: 10, - MAX_DETOUR_DISTANCE_RATIO: 0.3, - MAX_DETOUR_DURATION_RATIO: 0.3, - GEOROUTER_TYPE: 'graphhopper', - GEOROUTER_URL: 'http://localhost', - }, -}; - -const mockGeorouterCreator = { - create: jest.fn().mockImplementation(), -}; - -const mockTimezoneFinder = { - timezones: jest.fn().mockImplementation(() => ['Europe/Paris']), -}; - -const mockTimeConverter = { - toUtcDate: jest.fn(), -}; - -describe('Match query', () => { - it('should be defined', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery).toBeDefined(); - expect(matchQuery.mode).toBe(Mode.MATCH); - }); - - it('should create a query with publish and match mode', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - matchRequest.mode = Mode.PUBLISH_AND_MATCH; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery.mode).toBe(Mode.PUBLISH_AND_MATCH); - }); - - it('should create a query with excluded identifiers', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - matchRequest.uuid = '445aa6e4-99e4-4899-9456-3be8c3ada368'; - matchRequest.exclusions = [ - 'eacf5e53-e63c-4551-860c-73f95b8a8895', - 'a4098161-13a9-4e55-8999-de134fbf89c4', - 'b18f7ffa-20b9-4a1a-89bc-e238ea8289f3', - ]; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery.exclusions.length).toBe(4); - }); - - it('should create a query with driver role only', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - matchRequest.driver = true; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery.roles).toEqual([Role.DRIVER]); - }); - - it('should create a query with passenger role only', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - matchRequest.passenger = true; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery.roles).toEqual([Role.PASSENGER]); - }); - - it('should create a query with driver and passenger roles', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - matchRequest.passenger = true; - matchRequest.driver = true; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery.roles.length).toBe(2); - expect(matchQuery.roles).toContain(Role.PASSENGER); - expect(matchQuery.roles).toContain(Role.DRIVER); - }); - - it('should create a query with number of seats modified', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - matchRequest.seatsDriver = 1; - matchRequest.seatsPassenger = 2; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery.requirement.seatsDriver).toBe(1); - expect(matchQuery.requirement.seatsPassenger).toBe(2); - }); - - it('should create a query with modified algorithm settings', () => { - const matchRequest: MatchRequest = new MatchRequest(); - matchRequest.departure = '2023-04-01 12:00'; - matchRequest.waypoints = [ - { - lat: 49.440041, - lon: 1.093912, - }, - { - lat: 50.630992, - lon: 3.045432, - }, - ]; - matchRequest.algorithm = AlgorithmType.CLASSIC; - matchRequest.strict = true; - matchRequest.useProportion = true; - matchRequest.proportion = 0.45; - matchRequest.useAzimuth = true; - matchRequest.azimuthMargin = 15; - matchRequest.remoteness = 20000; - matchRequest.maxDetourDistanceRatio = 0.41; - matchRequest.maxDetourDurationRatio = 0.42; - const matchQuery: MatchQuery = new MatchQuery( - matchRequest, - defaultParams, - mockGeorouterCreator, - mockTimezoneFinder, - mockTimeConverter, - ); - expect(matchQuery.algorithmSettings.algorithmType).toBe( - AlgorithmType.CLASSIC, - ); - expect(matchQuery.algorithmSettings.restrict).toBe(Frequency.PUNCTUAL); - expect(matchQuery.algorithmSettings.useProportion).toBeTruthy(); - expect(matchQuery.algorithmSettings.proportion).toBe(0.45); - expect(matchQuery.algorithmSettings.useAzimuth).toBeTruthy(); - expect(matchQuery.algorithmSettings.azimuthMargin).toBe(15); - expect(matchQuery.algorithmSettings.remoteness).toBe(20000); - expect(matchQuery.algorithmSettings.maxDetourDistanceRatio).toBe(0.41); - expect(matchQuery.algorithmSettings.maxDetourDurationRatio).toBe(0.42); - }); -}); diff --git a/old/modules/utils/exception-code.enum.ts b/old/modules/utils/exception-code.enum.ts deleted file mode 100644 index 59554ae..0000000 --- a/old/modules/utils/exception-code.enum.ts +++ /dev/null @@ -1,19 +0,0 @@ -export enum ExceptionCode { - OK = 0, - CANCELLED = 1, - UNKNOWN = 2, - INVALID_ARGUMENT = 3, - DEADLINE_EXCEEDED = 4, - NOT_FOUND = 5, - ALREADY_EXISTS = 6, - PERMISSION_DENIED = 7, - RESOURCE_EXHAUSTED = 8, - FAILED_PRECONDITION = 9, - ABORTED = 10, - OUT_OF_RANGE = 11, - UNIMPLEMENTED = 12, - INTERNAL = 13, - UNAVAILABLE = 14, - DATA_LOSS = 15, - UNAUTHENTICATED = 16, -} diff --git a/old/modules/utils/pipes/rpc.validation-pipe.ts b/old/modules/utils/pipes/rpc.validation-pipe.ts deleted file mode 100644 index f2b8c19..0000000 --- a/old/modules/utils/pipes/rpc.validation-pipe.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Injectable, ValidationPipe } from '@nestjs/common'; -import { RpcException } from '@nestjs/microservices'; - -@Injectable() -export class RpcValidationPipe extends ValidationPipe { - createExceptionFactory() { - return (validationErrors = []) => { - return new RpcException({ - code: 3, - message: this.flattenValidationErrors(validationErrors), - }); - }; - } -} diff --git a/old/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts b/old/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts deleted file mode 100644 index 911466c..0000000 --- a/old/modules/utils/tests/unit/rpc-validation-pipe.usecase.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ArgumentMetadata } from '@nestjs/common'; -import { RpcValidationPipe } from '../../pipes/rpc.validation-pipe'; -import { MatchRequest } from '../../../matcher/domain/dtos/match.request'; - -describe('RpcValidationPipe', () => { - it('should not validate request', async () => { - const target: RpcValidationPipe = new RpcValidationPipe({ - whitelist: true, - forbidUnknownValues: false, - }); - const metadata: ArgumentMetadata = { - type: 'body', - metatype: MatchRequest, - data: '', - }; - await target.transform({}, metadata).catch((err) => { - expect(err.message).toEqual('Rpc Exception'); - }); - }); -}); diff --git a/src/main.ts b/src/main.ts index 0daaf12..8db905d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,11 +11,8 @@ async function bootstrap() { app.connectMicroservice({ transport: Transport.GRPC, options: { - package: ['matcher', 'health'], - protoPath: [ - join(__dirname, 'modules/matcher/adapters/primaries/matcher.proto'), - join(__dirname, 'modules/health/adapters/primaries/health.proto'), - ], + package: ['health'], + protoPath: [join(__dirname, 'health.proto')], url: process.env.SERVICE_URL + ':' + process.env.SERVICE_PORT, loader: { keepCase: true }, }, diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index a98751d..3bfdd2e 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -5,6 +5,7 @@ import { AD_REPOSITORY, AD_DIRECTION_ENCODER, AD_ROUTE_PROVIDER, + AD_GET_BASIC_ROUTE_CONTROLLER, } from './ad.di-tokens'; import { MessageBrokerPublisher } from '@mobicoop/message-broker-module'; import { AdRepository } from './infrastructure/ad.repository'; @@ -12,7 +13,9 @@ import { PrismaService } from './infrastructure/prisma.service'; import { AdMapper } from './ad.mapper'; import { AdCreatedMessageHandler } from './interface/message-handlers/ad-created.message-handler'; import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder'; -import { GetRouteController } from '@modules/geography/interface/controllers/get-route.controller'; +import { GetBasicRouteController } from '@modules/geography/interface/controllers/get-basic-route.controller'; +import { RouteProvider } from './infrastructure/route-provider'; +import { GeographyModule } from '@modules/geography/geography.module'; const messageHandlers = [AdCreatedMessageHandler]; @@ -41,12 +44,16 @@ const adapters: Provider[] = [ }, { provide: AD_ROUTE_PROVIDER, - useClass: GetRouteController, + useClass: RouteProvider, + }, + { + provide: AD_GET_BASIC_ROUTE_CONTROLLER, + useClass: GetBasicRouteController, }, ]; @Module({ - imports: [CqrsModule], + imports: [CqrsModule, GeographyModule], providers: [ ...messageHandlers, ...mappers, diff --git a/src/modules/geography/geography.module.ts b/src/modules/geography/geography.module.ts index 192f6df..e1a0c46 100644 --- a/src/modules/geography/geography.module.ts +++ b/src/modules/geography/geography.module.ts @@ -4,6 +4,9 @@ import { DIRECTION_ENCODER, PARAMS_PROVIDER } from './geography.di-tokens'; import { DefaultParamsProvider } from './infrastructure/default-params-provider'; import { PostgresDirectionEncoder } from './infrastructure/postgres-direction-encoder'; import { GetBasicRouteController } from './interface/controllers/get-basic-route.controller'; +import { RouteMapper } from './route.mapper'; + +const mappers: Provider[] = [RouteMapper]; const adapters: Provider[] = [ { @@ -19,7 +22,7 @@ const adapters: Provider[] = [ @Module({ imports: [CqrsModule], - providers: [...adapters], - exports: [DIRECTION_ENCODER, GetBasicRouteController], + providers: [...mappers, ...adapters], + exports: [RouteMapper, DIRECTION_ENCODER, GetBasicRouteController], }) export class GeographyModule {} From 158b12b150b8b4088919a10acd2195cf7c011934 Mon Sep 17 00:00:00 2001 From: sbriat Date: Wed, 23 Aug 2023 11:35:48 +0200 Subject: [PATCH 18/24] add graphhopper georouter --- .../ports/direction-encoder.port.ts | 2 +- .../ports/georouter-creator.port.ts | 5 - .../queries/get-route/get-route.query.ts | 3 +- .../application/types/coordinates.type.ts | 4 - .../core/application/types/path.type.ts | 7 - .../core/application/types/route.type.ts | 13 -- .../application/types/spacetime-point.type.ts | 6 - .../core/application/types/waypoint.type.ts | 5 - .../geography/core/domain/route.entity.ts | 24 ++- .../geography/core/domain/route.errors.ts | 10 ++ .../geography/core/domain/route.types.ts | 14 +- .../infrastructure/graphhopper-georouter.ts | 139 ++++++++++++++++++ .../postgres-direction-encoder.ts | 2 +- .../controllers/dtos/get-route.request.dto.ts | 3 +- .../interface/dtos/route.response.dto.ts | 6 +- .../unit/core/get-route.query-handler.spec.ts | 3 +- .../tests/unit/core/route.entity.spec.ts | 2 +- .../graphhopper-georouter.spec.ts | 74 ++++++++++ .../postgres-direction-encoder.spec.ts | 2 +- 19 files changed, 253 insertions(+), 71 deletions(-) delete mode 100644 src/modules/geography/core/application/ports/georouter-creator.port.ts delete mode 100644 src/modules/geography/core/application/types/coordinates.type.ts delete mode 100644 src/modules/geography/core/application/types/path.type.ts delete mode 100644 src/modules/geography/core/application/types/route.type.ts delete mode 100644 src/modules/geography/core/application/types/spacetime-point.type.ts delete mode 100644 src/modules/geography/core/application/types/waypoint.type.ts create mode 100644 src/modules/geography/infrastructure/graphhopper-georouter.ts create mode 100644 src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts diff --git a/src/modules/geography/core/application/ports/direction-encoder.port.ts b/src/modules/geography/core/application/ports/direction-encoder.port.ts index 3251915..737456a 100644 --- a/src/modules/geography/core/application/ports/direction-encoder.port.ts +++ b/src/modules/geography/core/application/ports/direction-encoder.port.ts @@ -1,4 +1,4 @@ -import { Coordinates } from '../types/coordinates.type'; +import { Coordinates } from '../../domain/route.types'; export interface DirectionEncoderPort { encode(coordinates: Coordinates[]): string; diff --git a/src/modules/geography/core/application/ports/georouter-creator.port.ts b/src/modules/geography/core/application/ports/georouter-creator.port.ts deleted file mode 100644 index 0f3957d..0000000 --- a/src/modules/geography/core/application/ports/georouter-creator.port.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { GeorouterPort } from './georouter.port'; - -export interface GeorouterCreatorPort { - create(type: string, url: string): GeorouterPort; -} diff --git a/src/modules/geography/core/application/queries/get-route/get-route.query.ts b/src/modules/geography/core/application/queries/get-route/get-route.query.ts index 4b8c6fd..eef3ed1 100644 --- a/src/modules/geography/core/application/queries/get-route/get-route.query.ts +++ b/src/modules/geography/core/application/queries/get-route/get-route.query.ts @@ -1,6 +1,5 @@ import { QueryBase } from '@mobicoop/ddd-library'; -import { Role } from '@modules/geography/core/domain/route.types'; -import { Waypoint } from '../../types/waypoint.type'; +import { Role, Waypoint } from '@modules/geography/core/domain/route.types'; import { GeorouterSettings } from '../../types/georouter-settings.type'; export class GetRouteQuery extends QueryBase { diff --git a/src/modules/geography/core/application/types/coordinates.type.ts b/src/modules/geography/core/application/types/coordinates.type.ts deleted file mode 100644 index 8e149ed..0000000 --- a/src/modules/geography/core/application/types/coordinates.type.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type Coordinates = { - lon: number; - lat: number; -}; diff --git a/src/modules/geography/core/application/types/path.type.ts b/src/modules/geography/core/application/types/path.type.ts deleted file mode 100644 index 2f8e46e..0000000 --- a/src/modules/geography/core/application/types/path.type.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { PathType } from '../../domain/route.types'; -import { Coordinates } from './coordinates.type'; - -export type Path = { - type: PathType; - points: Coordinates[]; -}; diff --git a/src/modules/geography/core/application/types/route.type.ts b/src/modules/geography/core/application/types/route.type.ts deleted file mode 100644 index 791a00e..0000000 --- a/src/modules/geography/core/application/types/route.type.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { PathType } from '../../domain/route.types'; -import { Coordinates } from './coordinates.type'; -import { SpacetimePoint } from './spacetime-point.type'; - -export type Route = { - type: PathType; - distance: number; - duration: number; - fwdAzimuth: number; - backAzimuth: number; - distanceAzimuth: number; - points: Coordinates[] | SpacetimePoint[]; -}; diff --git a/src/modules/geography/core/application/types/spacetime-point.type.ts b/src/modules/geography/core/application/types/spacetime-point.type.ts deleted file mode 100644 index 9bed0c5..0000000 --- a/src/modules/geography/core/application/types/spacetime-point.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Coordinates } from './coordinates.type'; - -export type SpacetimePoint = Coordinates & { - duration: number; - distance: number; -}; diff --git a/src/modules/geography/core/application/types/waypoint.type.ts b/src/modules/geography/core/application/types/waypoint.type.ts deleted file mode 100644 index 3c635d5..0000000 --- a/src/modules/geography/core/application/types/waypoint.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Coordinates } from './coordinates.type'; - -export type Waypoint = Coordinates & { - position: number; -}; diff --git a/src/modules/geography/core/domain/route.entity.ts b/src/modules/geography/core/domain/route.entity.ts index dc81161..46177b7 100644 --- a/src/modules/geography/core/domain/route.entity.ts +++ b/src/modules/geography/core/domain/route.entity.ts @@ -5,10 +5,9 @@ import { Role, RouteProps, PathType, - Direction, + Route, } from './route.types'; import { WaypointProps } from './value-objects/waypoint.value-object'; -import { Route } from '../application/types/route.type'; import { v4 } from 'uuid'; import { RouteNotFoundException } from './route.errors'; @@ -16,33 +15,30 @@ export class RouteEntity extends AggregateRoot { protected readonly _id: AggregateID; static create = async (create: CreateRouteProps): Promise => { - let directions: Direction[]; + let routes: Route[]; try { - directions = await create.georouter.routes( + routes = await create.georouter.routes( this.getPaths(create.roles, create.waypoints), create.georouterSettings, ); - if (!directions || directions.length == 0) - throw new RouteNotFoundException(); + if (!routes || routes.length == 0) throw new RouteNotFoundException(); } catch (e: any) { throw e; } let driverRoute: Route; let passengerRoute: Route; - if (directions.some((route: Route) => route.type == PathType.GENERIC)) { - driverRoute = passengerRoute = directions.find( + if (routes.some((route: Route) => route.type == PathType.GENERIC)) { + driverRoute = passengerRoute = routes.find( (route: Route) => route.type == PathType.GENERIC, ); } else { - driverRoute = directions.some( - (route: Route) => route.type == PathType.DRIVER, - ) - ? directions.find((route: Route) => route.type == PathType.DRIVER) + driverRoute = routes.some((route: Route) => route.type == PathType.DRIVER) + ? routes.find((route: Route) => route.type == PathType.DRIVER) : undefined; - passengerRoute = directions.some( + passengerRoute = routes.some( (route: Route) => route.type == PathType.PASSENGER, ) - ? directions.find((route: Route) => route.type == PathType.PASSENGER) + ? routes.find((route: Route) => route.type == PathType.PASSENGER) : undefined; } const routeProps: RouteProps = { diff --git a/src/modules/geography/core/domain/route.errors.ts b/src/modules/geography/core/domain/route.errors.ts index a0f484b..420f096 100644 --- a/src/modules/geography/core/domain/route.errors.ts +++ b/src/modules/geography/core/domain/route.errors.ts @@ -9,3 +9,13 @@ export class RouteNotFoundException extends ExceptionBase { super(RouteNotFoundException.message, cause, metadata); } } + +export class GeorouterUnavailableException extends ExceptionBase { + static readonly message = 'Georouter unavailable'; + + public readonly code = 'GEOROUTER.UNAVAILABLE'; + + constructor(cause?: Error, metadata?: unknown) { + super(GeorouterUnavailableException.message, cause, metadata); + } +} diff --git a/src/modules/geography/core/domain/route.types.ts b/src/modules/geography/core/domain/route.types.ts index 7fe7776..ba47f02 100644 --- a/src/modules/geography/core/domain/route.types.ts +++ b/src/modules/geography/core/domain/route.types.ts @@ -25,27 +25,31 @@ export interface CreateRouteProps { georouterSettings: GeorouterSettings; } -export type Direction = { +export type Route = { type: PathType; distance: number; duration: number; fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; - points: SpacetimePoint[] | Point[]; + points: SpacetimePoint[] | Coordinates[]; }; export type Path = { type: PathType; - points: Point[]; + points: Coordinates[]; }; -export type Point = { +export type Coordinates = { lon: number; lat: number; }; -export type SpacetimePoint = Point & { +export type Waypoint = Coordinates & { + position: number; +}; + +export type SpacetimePoint = Coordinates & { duration: number; distance: number; }; diff --git a/src/modules/geography/infrastructure/graphhopper-georouter.ts b/src/modules/geography/infrastructure/graphhopper-georouter.ts new file mode 100644 index 0000000..a6f6f3a --- /dev/null +++ b/src/modules/geography/infrastructure/graphhopper-georouter.ts @@ -0,0 +1,139 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { HttpService } from '@nestjs/axios'; +import { GeorouterPort } from '../core/application/ports/georouter.port'; +import { GeorouterSettings } from '../core/application/types/georouter-settings.type'; +import { Path, PathType, Route } from '../core/domain/route.types'; +import { DefaultParamsProviderPort } from '../core/application/ports/default-params-provider.port'; +import { PARAMS_PROVIDER } from '../geography.di-tokens'; +import { catchError, lastValueFrom, map } from 'rxjs'; +import { AxiosError, AxiosResponse } from 'axios'; +import { + GeorouterUnavailableException, + RouteNotFoundException, +} from '../core/domain/route.errors'; + +@Injectable() +export class GraphhopperGeorouter implements GeorouterPort { + private url: string; + private urlArgs: string[]; + + constructor( + private readonly httpService: HttpService, + @Inject(PARAMS_PROVIDER) + private readonly defaultParamsProvider: DefaultParamsProviderPort, + ) { + this.url = defaultParamsProvider.getParams().GEOROUTER_URL; + } + + routes = async ( + paths: Path[], + settings: GeorouterSettings, + ): Promise => { + this.setDefaultUrlArgs(); + this.setSettings(settings); + return [ + { + type: PathType.DRIVER, + distance: 1000, + duration: 1000, + fwdAzimuth: 280, + backAzimuth: 100, + distanceAzimuth: 900, + points: [], + }, + ]; + }; + + private setDefaultUrlArgs = (): void => { + this.urlArgs = ['vehicle=car', 'weighting=fastest', 'points_encoded=false']; + }; + + private setSettings = (settings: GeorouterSettings): void => { + if (settings.detailedDuration) { + this.urlArgs.push('details=time'); + } + if (settings.detailedDistance) { + this.urlArgs.push('instructions=true'); + } else { + this.urlArgs.push('instructions=false'); + } + if (!settings.points) { + this.urlArgs.push('calc_points=false'); + } + }; + + private getRoutes = async (paths: Path[]): Promise => { + const routes = Promise.all( + paths.map(async (path) => { + const url: string = [ + this.getUrl(), + '&point=', + path.points + .map((point) => [point.lat, point.lon].join('%2C')) + .join('&point='), + ].join(''); + const route = await lastValueFrom( + this.httpService.get(url).pipe( + map((res) => + res.data ? this.createRoute(res, path.type) : undefined, + ), + catchError((error: AxiosError) => { + if (error.code == AxiosError.ERR_BAD_REQUEST) { + throw new RouteNotFoundException( + error, + 'No route found for given coordinates', + ); + } + throw new GeorouterUnavailableException(error); + }), + ), + ); + return route; + }), + ); + return routes; + }; + + private getUrl = (): string => [this.url, this.urlArgs.join('&')].join(''); + + private createRoute = ( + response: AxiosResponse, + type: PathType, + ): Route => undefined; +} + +type GraphhopperResponse = { + paths: [ + { + distance: number; + weight: number; + time: number; + points_encoded: boolean; + bbox: number[]; + points: GraphhopperCoordinates; + snapped_waypoints: GraphhopperCoordinates; + details: { + time: number[]; + }; + instructions: GraphhopperInstruction[]; + }, + ]; +}; + +type GraphhopperCoordinates = { + coordinates: number[]; +}; + +type GraphhopperInstruction = { + distance: number; + heading: number; + sign: GraphhopperSign; + interval: number[]; + text: string; +}; + +enum GraphhopperSign { + SIGN_START = 0, + SIGN_FINISH = 4, + SIGN_WAYPOINT = 5, +} diff --git a/src/modules/geography/infrastructure/postgres-direction-encoder.ts b/src/modules/geography/infrastructure/postgres-direction-encoder.ts index b4c8001..d6cb0b6 100644 --- a/src/modules/geography/infrastructure/postgres-direction-encoder.ts +++ b/src/modules/geography/infrastructure/postgres-direction-encoder.ts @@ -1,6 +1,6 @@ -import { Coordinates } from '../core/application/types/coordinates.type'; import { DirectionEncoderPort } from '../core/application/ports/direction-encoder.port'; import { Injectable } from '@nestjs/common'; +import { Coordinates } from '../core/domain/route.types'; @Injectable() export class PostgresDirectionEncoder implements DirectionEncoderPort { diff --git a/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts b/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts index c6948df..7790bba 100644 --- a/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts +++ b/src/modules/geography/interface/controllers/dtos/get-route.request.dto.ts @@ -1,5 +1,4 @@ -import { Waypoint } from '@modules/geography/core/application/types/waypoint.type'; -import { Role } from '@modules/geography/core/domain/route.types'; +import { Role, Waypoint } from '@modules/geography/core/domain/route.types'; export type GetRouteRequestDto = { roles: Role[]; diff --git a/src/modules/geography/interface/dtos/route.response.dto.ts b/src/modules/geography/interface/dtos/route.response.dto.ts index 58d3c52..714fb68 100644 --- a/src/modules/geography/interface/dtos/route.response.dto.ts +++ b/src/modules/geography/interface/dtos/route.response.dto.ts @@ -1,5 +1,7 @@ -import { Coordinates } from '@modules/geography/core/application/types/coordinates.type'; -import { SpacetimePoint } from '@modules/geography/core/application/types/spacetime-point.type'; +import { + Coordinates, + SpacetimePoint, +} from '@modules/geography/core/domain/route.types'; export class RouteResponseDto { driverDistance?: number; diff --git a/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts b/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts index d9c142e..d8df206 100644 --- a/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts +++ b/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts @@ -1,9 +1,8 @@ import { GeorouterPort } from '@modules/geography/core/application/ports/georouter.port'; import { GetRouteQuery } from '@modules/geography/core/application/queries/get-route/get-route.query'; import { GetRouteQueryHandler } from '@modules/geography/core/application/queries/get-route/get-route.query-handler'; -import { Waypoint } from '@modules/geography/core/application/types/waypoint.type'; import { RouteEntity } from '@modules/geography/core/domain/route.entity'; -import { Role } from '@modules/geography/core/domain/route.types'; +import { Role, Waypoint } from '@modules/geography/core/domain/route.types'; import { GEOROUTER } from '@modules/geography/geography.di-tokens'; import { Test, TestingModule } from '@nestjs/testing'; diff --git a/src/modules/geography/tests/unit/core/route.entity.spec.ts b/src/modules/geography/tests/unit/core/route.entity.spec.ts index 5c0eaf3..edbe7a9 100644 --- a/src/modules/geography/tests/unit/core/route.entity.spec.ts +++ b/src/modules/geography/tests/unit/core/route.entity.spec.ts @@ -1,8 +1,8 @@ import { GeorouterPort } from '@modules/geography/core/application/ports/georouter.port'; -import { Coordinates } from '@modules/geography/core/application/types/coordinates.type'; import { RouteEntity } from '@modules/geography/core/domain/route.entity'; import { RouteNotFoundException } from '@modules/geography/core/domain/route.errors'; import { + Coordinates, CreateRouteProps, PathType, Role, diff --git a/src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts b/src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts new file mode 100644 index 0000000..adda4e8 --- /dev/null +++ b/src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts @@ -0,0 +1,74 @@ +import { DefaultParamsProviderPort } from '@modules/geography/core/application/ports/default-params-provider.port'; +import { + Path, + PathType, + Route, +} from '@modules/geography/core/domain/route.types'; +import { PARAMS_PROVIDER } from '@modules/geography/geography.di-tokens'; +import { GraphhopperGeorouter } from '@modules/geography/infrastructure/graphhopper-georouter'; +import { HttpService } from '@nestjs/axios'; +import { Test, TestingModule } from '@nestjs/testing'; + +const driverPath: Path = { + type: PathType.DRIVER, + points: [ + { + lon: 6, + lat: 47, + }, + { + lon: 6.1, + lat: 47.1, + }, + { + lon: 6.2, + lat: 47.2, + }, + ], +}; + +const mockHttpService = {}; + +const mockDefaultParamsProvider: DefaultParamsProviderPort = { + getParams: jest.fn().mockImplementation(() => ({ + GEOROUTER_URL: 'http://localhost:8989', + })), +}; + +describe('Graphhopper Georouter', () => { + let graphhopperGeorouter: GraphhopperGeorouter; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [], + providers: [ + GraphhopperGeorouter, + { + provide: HttpService, + useValue: mockHttpService, + }, + { + provide: PARAMS_PROVIDER, + useValue: mockDefaultParamsProvider, + }, + ], + }).compile(); + + graphhopperGeorouter = + module.get(GraphhopperGeorouter); + }); + + it('should be defined', () => { + expect(graphhopperGeorouter).toBeDefined(); + }); + + it('should return basic driver routes', async () => { + const paths: Path[] = [driverPath]; + const driverRoutes: Route[] = await graphhopperGeorouter.routes(paths, { + detailedDistance: false, + detailedDuration: false, + points: true, + }); + expect(driverRoutes.length).toBe(1); + }); +}); diff --git a/src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts b/src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts index 6f12ed5..fd4cbab 100644 --- a/src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts +++ b/src/modules/geography/tests/unit/infrastructure/postgres-direction-encoder.spec.ts @@ -1,4 +1,4 @@ -import { Coordinates } from '@modules/geography/core/application/types/coordinates.type'; +import { Coordinates } from '@modules/geography/core/domain/route.types'; import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder'; describe('Postgres direction encoder', () => { From 66d4d58dd15f8cd1e9f7e37ea5f2cb508b394fd5 Mon Sep 17 00:00:00 2001 From: sbriat Date: Wed, 23 Aug 2023 14:32:17 +0200 Subject: [PATCH 19/24] almost full coverage for graphhopper georouter --- .../geography/core/domain/route.types.ts | 3 +- src/modules/geography/geography.di-tokens.ts | 1 + src/modules/geography/geography.module.ts | 11 +- .../geography/infrastructure/geodesic.ts | 27 + .../infrastructure/graphhopper-georouter.ts | 226 +++++++- .../unit/infrastructure/geodesic.spec.ts | 14 + .../graphhopper-georouter.spec.ts | 486 ++++++++++++++++-- 7 files changed, 718 insertions(+), 50 deletions(-) create mode 100644 src/modules/geography/infrastructure/geodesic.ts create mode 100644 src/modules/geography/tests/unit/infrastructure/geodesic.spec.ts diff --git a/src/modules/geography/core/domain/route.types.ts b/src/modules/geography/core/domain/route.types.ts index ba47f02..5860261 100644 --- a/src/modules/geography/core/domain/route.types.ts +++ b/src/modules/geography/core/domain/route.types.ts @@ -32,7 +32,8 @@ export type Route = { fwdAzimuth: number; backAzimuth: number; distanceAzimuth: number; - points: SpacetimePoint[] | Coordinates[]; + points: Coordinates[]; + spacetimeWaypoints: SpacetimePoint[]; }; export type Path = { diff --git a/src/modules/geography/geography.di-tokens.ts b/src/modules/geography/geography.di-tokens.ts index 98e9456..101e426 100644 --- a/src/modules/geography/geography.di-tokens.ts +++ b/src/modules/geography/geography.di-tokens.ts @@ -1,3 +1,4 @@ export const PARAMS_PROVIDER = Symbol('PARAMS_PROVIDER'); export const DIRECTION_ENCODER = Symbol('DIRECTION_ENCODER'); export const GEOROUTER = Symbol('GEOROUTER'); +export const GEODESIC = Symbol('GEODESIC'); diff --git a/src/modules/geography/geography.module.ts b/src/modules/geography/geography.module.ts index e1a0c46..8c2df42 100644 --- a/src/modules/geography/geography.module.ts +++ b/src/modules/geography/geography.module.ts @@ -1,10 +1,15 @@ import { Module, Provider } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; -import { DIRECTION_ENCODER, PARAMS_PROVIDER } from './geography.di-tokens'; +import { + DIRECTION_ENCODER, + GEODESIC, + PARAMS_PROVIDER, +} from './geography.di-tokens'; import { DefaultParamsProvider } from './infrastructure/default-params-provider'; import { PostgresDirectionEncoder } from './infrastructure/postgres-direction-encoder'; import { GetBasicRouteController } from './interface/controllers/get-basic-route.controller'; import { RouteMapper } from './route.mapper'; +import { Geodesic } from './infrastructure/geodesic'; const mappers: Provider[] = [RouteMapper]; @@ -17,6 +22,10 @@ const adapters: Provider[] = [ provide: DIRECTION_ENCODER, useClass: PostgresDirectionEncoder, }, + { + provide: GEODESIC, + useClass: Geodesic, + }, GetBasicRouteController, ]; diff --git a/src/modules/geography/infrastructure/geodesic.ts b/src/modules/geography/infrastructure/geodesic.ts new file mode 100644 index 0000000..a0f1e76 --- /dev/null +++ b/src/modules/geography/infrastructure/geodesic.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@nestjs/common'; +import { Geodesic as Geolib, GeodesicClass } from 'geographiclib-geodesic'; +import { GeodesicPort } from '../core/application/ports/geodesic.port'; + +@Injectable() +export class Geodesic implements GeodesicPort { + private geod: GeodesicClass; + + constructor() { + this.geod = Geolib.WGS84; + } + + inverse = ( + lon1: number, + lat1: number, + lon2: number, + lat2: number, + ): { azimuth: number; distance: number } => { + const { azi2: azimuth, s12: distance } = this.geod.Inverse( + lat1, + lon1, + lat2, + lon2, + ); + return { azimuth, distance }; + }; +} diff --git a/src/modules/geography/infrastructure/graphhopper-georouter.ts b/src/modules/geography/infrastructure/graphhopper-georouter.ts index a6f6f3a..ce67939 100644 --- a/src/modules/geography/infrastructure/graphhopper-georouter.ts +++ b/src/modules/geography/infrastructure/graphhopper-georouter.ts @@ -2,15 +2,21 @@ import { Inject, Injectable } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { GeorouterPort } from '../core/application/ports/georouter.port'; import { GeorouterSettings } from '../core/application/types/georouter-settings.type'; -import { Path, PathType, Route } from '../core/domain/route.types'; +import { + Path, + PathType, + Route, + SpacetimePoint, +} from '../core/domain/route.types'; import { DefaultParamsProviderPort } from '../core/application/ports/default-params-provider.port'; -import { PARAMS_PROVIDER } from '../geography.di-tokens'; +import { GEODESIC, PARAMS_PROVIDER } from '../geography.di-tokens'; import { catchError, lastValueFrom, map } from 'rxjs'; import { AxiosError, AxiosResponse } from 'axios'; import { GeorouterUnavailableException, RouteNotFoundException, } from '../core/domain/route.errors'; +import { GeodesicPort } from '../core/application/ports/geodesic.port'; @Injectable() export class GraphhopperGeorouter implements GeorouterPort { @@ -21,8 +27,12 @@ export class GraphhopperGeorouter implements GeorouterPort { private readonly httpService: HttpService, @Inject(PARAMS_PROVIDER) private readonly defaultParamsProvider: DefaultParamsProviderPort, + @Inject(GEODESIC) private readonly geodesic: GeodesicPort, ) { - this.url = defaultParamsProvider.getParams().GEOROUTER_URL; + this.url = [ + defaultParamsProvider.getParams().GEOROUTER_URL, + '/route?', + ].join(''); } routes = async ( @@ -31,17 +41,7 @@ export class GraphhopperGeorouter implements GeorouterPort { ): Promise => { this.setDefaultUrlArgs(); this.setSettings(settings); - return [ - { - type: PathType.DRIVER, - distance: 1000, - duration: 1000, - fwdAzimuth: 280, - backAzimuth: 100, - distanceAzimuth: 900, - points: [], - }, - ]; + return this.getRoutes(paths); }; private setDefaultUrlArgs = (): void => { @@ -99,7 +99,197 @@ export class GraphhopperGeorouter implements GeorouterPort { private createRoute = ( response: AxiosResponse, type: PathType, - ): Route => undefined; + ): Route => { + const route = {} as Route; + route.type = type; + if (response.data.paths && response.data.paths[0]) { + const shortestPath = response.data.paths[0]; + route.distance = shortestPath.distance ?? 0; + route.duration = shortestPath.time ? shortestPath.time / 1000 : 0; + if (shortestPath.points && shortestPath.points.coordinates) { + route.points = shortestPath.points.coordinates.map((coordinate) => ({ + lon: coordinate[0], + lat: coordinate[1], + })); + const inverse = this.geodesic.inverse( + route.points[0].lon, + route.points[0].lat, + route.points[route.points.length - 1].lon, + route.points[route.points.length - 1].lat, + ); + route.fwdAzimuth = + inverse.azimuth >= 0 + ? inverse.azimuth + : 360 - Math.abs(inverse.azimuth); + route.backAzimuth = + route.fwdAzimuth > 180 + ? route.fwdAzimuth - 180 + : route.fwdAzimuth + 180; + route.distanceAzimuth = inverse.distance; + if ( + shortestPath.details && + shortestPath.details.time && + shortestPath.snapped_waypoints && + shortestPath.snapped_waypoints.coordinates + ) { + let instructions: GraphhopperInstruction[] = []; + if (shortestPath.instructions) + instructions = shortestPath.instructions; + route.spacetimeWaypoints = this.generateSpacetimePoints( + shortestPath.points.coordinates, + shortestPath.snapped_waypoints.coordinates, + shortestPath.details.time, + instructions, + ); + } + } + } + return route; + }; + + private generateSpacetimePoints = ( + points: [[number, number]], + snappedWaypoints: [[number, number]], + durations: [[number, number, number]], + instructions: GraphhopperInstruction[], + ): SpacetimePoint[] => { + const indices = this.getIndices(points, snappedWaypoints); + const times = this.getTimes(durations, indices); + const distances = this.getDistances(instructions, indices); + return indices.map((index) => ({ + lon: points[index][1], + lat: points[index][0], + distance: distances.find((distance) => distance.index == index)?.distance, + duration: times.find((time) => time.index == index)?.duration, + })); + }; + + private getIndices = ( + points: [[number, number]], + snappedWaypoints: [[number, number]], + ): number[] => { + const indices = snappedWaypoints.map((waypoint) => + points.findIndex( + (point) => point[0] == waypoint[0] && point[1] == waypoint[1], + ), + ); + if (indices.find((index) => index == -1) === undefined) return indices; + const missedWaypoints = indices + .map( + (value, index) => + < + { + index: number; + originIndex: number; + waypoint: number[]; + nearest: number; + distance: number; + } + >{ + index: value, + originIndex: index, + waypoint: snappedWaypoints[index], + nearest: undefined, + distance: 999999999, + }, + ) + .filter((element) => element.index == -1); + for (const index in points) { + for (const missedWaypoint of missedWaypoints) { + const inverse = this.geodesic.inverse( + missedWaypoint.waypoint[0], + missedWaypoint.waypoint[1], + points[index][0], + points[index][1], + ); + if (inverse.distance < missedWaypoint.distance) { + missedWaypoint.distance = inverse.distance; + missedWaypoint.nearest = parseInt(index); + } + } + } + for (const missedWaypoint of missedWaypoints) { + indices[missedWaypoint.originIndex] = missedWaypoint.nearest; + } + return indices; + }; + + private getTimes = ( + durations: [[number, number, number]], + indices: number[], + ): Array<{ index: number; duration: number }> => { + const times: Array<{ index: number; duration: number }> = []; + let duration = 0; + for (const [origin, destination, stepDuration] of durations) { + let indexFound = false; + const indexAsOrigin = indices.find((index) => index == origin); + if ( + indexAsOrigin !== undefined && + times.find((time) => origin == time.index) == undefined + ) { + times.push({ + index: indexAsOrigin, + duration: Math.round(stepDuration / 1000), + }); + indexFound = true; + } + if (!indexFound) { + const indexAsDestination = indices.find( + (index) => index == destination, + ); + if ( + indexAsDestination !== undefined && + times.find((time) => destination == time.index) == undefined + ) { + times.push({ + index: indexAsDestination, + duration: Math.round((duration + stepDuration) / 1000), + }); + indexFound = true; + } + } + if (!indexFound) { + const indexInBetween = indices.find( + (index) => origin < index && index < destination, + ); + if (indexInBetween !== undefined) { + times.push({ + index: indexInBetween, + duration: Math.round((duration + stepDuration / 2) / 1000), + }); + } + } + duration += stepDuration; + } + return times; + }; + + private getDistances = ( + instructions: GraphhopperInstruction[], + indices: number[], + ): Array<{ index: number; distance: number }> => { + let distance = 0; + const distances: Array<{ index: number; distance: number }> = [ + { + index: 0, + distance, + }, + ]; + for (const instruction of instructions) { + distance += instruction.distance; + if ( + (instruction.sign == GraphhopperSign.SIGN_WAYPOINT || + instruction.sign == GraphhopperSign.SIGN_FINISH) && + indices.find((index) => index == instruction.interval[0]) !== undefined + ) { + distances.push({ + index: instruction.interval[0], + distance: Math.round(distance), + }); + } + } + return distances; + }; } type GraphhopperResponse = { @@ -113,7 +303,7 @@ type GraphhopperResponse = { points: GraphhopperCoordinates; snapped_waypoints: GraphhopperCoordinates; details: { - time: number[]; + time: [[number, number, number]]; }; instructions: GraphhopperInstruction[]; }, @@ -121,14 +311,14 @@ type GraphhopperResponse = { }; type GraphhopperCoordinates = { - coordinates: number[]; + coordinates: [[number, number]]; }; type GraphhopperInstruction = { distance: number; heading: number; sign: GraphhopperSign; - interval: number[]; + interval: [number, number]; text: string; }; diff --git a/src/modules/geography/tests/unit/infrastructure/geodesic.spec.ts b/src/modules/geography/tests/unit/infrastructure/geodesic.spec.ts new file mode 100644 index 0000000..a71df2e --- /dev/null +++ b/src/modules/geography/tests/unit/infrastructure/geodesic.spec.ts @@ -0,0 +1,14 @@ +import { Geodesic } from '@modules/geography/infrastructure/geodesic'; + +describe('Matcher geodesic', () => { + it('should be defined', () => { + const geodesic: Geodesic = new Geodesic(); + expect(geodesic).toBeDefined(); + }); + it('should get inverse values', () => { + const geodesic: Geodesic = new Geodesic(); + const inv = geodesic.inverse(0, 0, 1, 1); + expect(Math.round(inv.azimuth)).toBe(45); + expect(Math.round(inv.distance)).toBe(156900); + }); +}); diff --git a/src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts b/src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts index adda4e8..c167240 100644 --- a/src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts +++ b/src/modules/geography/tests/unit/infrastructure/graphhopper-georouter.spec.ts @@ -1,33 +1,259 @@ import { DefaultParamsProviderPort } from '@modules/geography/core/application/ports/default-params-provider.port'; +import { GeodesicPort } from '@modules/geography/core/application/ports/geodesic.port'; import { - Path, - PathType, - Route, -} from '@modules/geography/core/domain/route.types'; -import { PARAMS_PROVIDER } from '@modules/geography/geography.di-tokens'; + GeorouterUnavailableException, + RouteNotFoundException, +} from '@modules/geography/core/domain/route.errors'; +import { PathType, Route } from '@modules/geography/core/domain/route.types'; +import { + GEODESIC, + PARAMS_PROVIDER, +} from '@modules/geography/geography.di-tokens'; import { GraphhopperGeorouter } from '@modules/geography/infrastructure/graphhopper-georouter'; import { HttpService } from '@nestjs/axios'; import { Test, TestingModule } from '@nestjs/testing'; +import { AxiosError } from 'axios'; +import { of, throwError } from 'rxjs'; -const driverPath: Path = { - type: PathType.DRIVER, - points: [ - { - lon: 6, - lat: 47, - }, - { - lon: 6.1, - lat: 47.1, - }, - { - lon: 6.2, - lat: 47.2, - }, - ], +const mockHttpService = { + get: jest + .fn() + .mockImplementationOnce(() => { + return throwError( + () => new AxiosError('Axios error', AxiosError.ERR_BAD_REQUEST), + ); + }) + .mockImplementationOnce(() => { + return throwError(() => 'Router unavailable'); + }) + .mockImplementationOnce(() => { + return of({ + status: 200, + data: { + paths: [ + { + distance: 50000, + time: 1800000, + snapped_waypoints: { + coordinates: [ + [0, 0], + [10, 10], + ], + }, + }, + ], + }, + }); + }) + .mockImplementationOnce(() => { + return of({ + status: 200, + data: { + paths: [ + { + distance: 50000, + time: 1800000, + points: { + coordinates: [ + [0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5], + [6, 6], + [7, 7], + [8, 8], + [9, 9], + [10, 10], + ], + }, + snapped_waypoints: { + coordinates: [ + [0, 0], + [10, 10], + ], + }, + }, + ], + }, + }); + }) + .mockImplementationOnce(() => { + return of({ + status: 200, + data: { + paths: [ + { + distance: 50000, + time: 1800000, + points: { + coordinates: [ + [0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5], + [6, 6], + [7, 7], + [8, 8], + [9, 9], + [10, 10], + ], + }, + details: { + time: [ + [0, 1, 180000], + [1, 2, 180000], + [2, 3, 180000], + [3, 4, 180000], + [4, 5, 180000], + [5, 6, 180000], + [6, 7, 180000], + [7, 9, 360000], + [9, 10, 180000], + ], + }, + snapped_waypoints: { + coordinates: [ + [0, 0], + [10, 10], + ], + }, + }, + ], + }, + }); + }) + .mockImplementationOnce(() => { + return of({ + status: 200, + data: { + paths: [ + { + distance: 50000, + time: 1800000, + points: { + coordinates: [ + [0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [7, 7], + [8, 8], + [9, 9], + [10, 10], + ], + }, + snapped_waypoints: { + coordinates: [ + [0, 0], + [5, 5], + [10, 10], + ], + }, + details: { + time: [ + [0, 1, 180000], + [1, 2, 180000], + [2, 3, 180000], + [3, 4, 180000], + [4, 7, 540000], + [7, 9, 360000], + [9, 10, 180000], + ], + }, + }, + ], + }, + }); + }) + .mockImplementationOnce(() => { + return of({ + status: 200, + data: { + paths: [ + { + distance: 50000, + time: 1800000, + points: { + coordinates: [ + [0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5], + [6, 6], + [7, 7], + [8, 8], + [9, 9], + [10, 10], + ], + }, + snapped_waypoints: { + coordinates: [ + [0, 0], + [5, 5], + [10, 10], + ], + }, + details: { + time: [ + [0, 1, 180000], + [1, 2, 180000], + [2, 3, 180000], + [3, 4, 180000], + [4, 7, 540000], + [7, 9, 360000], + [9, 10, 180000], + ], + }, + instructions: [ + { + distance: 25000, + sign: 0, + interval: [0, 5], + text: 'Some instructions', + time: 900000, + }, + { + distance: 0, + sign: 5, + interval: [5, 5], + text: 'Waypoint 1', + time: 0, + }, + { + distance: 25000, + sign: 2, + interval: [5, 10], + text: 'Some instructions', + time: 900000, + }, + { + distance: 0.0, + sign: 4, + interval: [10, 10], + text: 'Arrive at destination', + time: 0, + }, + ], + }, + ], + }, + }); + }), }; -const mockHttpService = {}; +const mockGeodesic: GeodesicPort = { + inverse: jest.fn().mockImplementation(() => ({ + azimuth: 45, + distance: 50000, + })), +}; const mockDefaultParamsProvider: DefaultParamsProviderPort = { getParams: jest.fn().mockImplementation(() => ({ @@ -51,6 +277,10 @@ describe('Graphhopper Georouter', () => { provide: PARAMS_PROVIDER, useValue: mockDefaultParamsProvider, }, + { + provide: GEODESIC, + useValue: mockGeodesic, + }, ], }).compile(); @@ -62,13 +292,209 @@ describe('Graphhopper Georouter', () => { expect(graphhopperGeorouter).toBeDefined(); }); - it('should return basic driver routes', async () => { - const paths: Path[] = [driverPath]; - const driverRoutes: Route[] = await graphhopperGeorouter.routes(paths, { - detailedDistance: false, - detailedDuration: false, - points: true, - }); - expect(driverRoutes.length).toBe(1); + it('should fail if route is not found', async () => { + await expect( + graphhopperGeorouter.routes( + [ + { + type: PathType.DRIVER, + points: [ + { + lon: 0, + lat: 0, + }, + { + lon: 1, + lat: 1, + }, + ], + }, + ], + { + detailedDistance: false, + detailedDuration: false, + points: false, + }, + ), + ).rejects.toBeInstanceOf(RouteNotFoundException); + }); + + it('should fail if georouter is unavailable', async () => { + await expect( + graphhopperGeorouter.routes( + [ + { + type: PathType.DRIVER, + points: [ + { + lon: 0, + lat: 0, + }, + { + lon: 1, + lat: 1, + }, + ], + }, + ], + { + detailedDistance: false, + detailedDuration: false, + points: false, + }, + ), + ).rejects.toBeInstanceOf(GeorouterUnavailableException); + }); + + it('should create a basic route', async () => { + const routes: Route[] = await graphhopperGeorouter.routes( + [ + { + type: PathType.DRIVER, + points: [ + { + lon: 0, + lat: 0, + }, + { + lon: 10, + lat: 10, + }, + ], + }, + ], + { + detailedDistance: false, + detailedDuration: false, + points: false, + }, + ); + expect(routes).toHaveLength(1); + expect(routes[0].distance).toBe(50000); + }); + + it('should create one route with points', async () => { + const routes = await graphhopperGeorouter.routes( + [ + { + type: PathType.DRIVER, + points: [ + { + lat: 0, + lon: 0, + }, + { + lat: 10, + lon: 10, + }, + ], + }, + ], + { + detailedDistance: false, + detailedDuration: false, + points: true, + }, + ); + expect(routes).toHaveLength(1); + expect(routes[0].distance).toBe(50000); + expect(routes[0].duration).toBe(1800); + expect(routes[0].fwdAzimuth).toBe(45); + expect(routes[0].backAzimuth).toBe(225); + expect(routes[0].points).toHaveLength(11); + }); + + it('should create one route with points and time', async () => { + const routes = await graphhopperGeorouter.routes( + [ + { + type: PathType.DRIVER, + points: [ + { + lat: 0, + lon: 0, + }, + { + lat: 10, + lon: 10, + }, + ], + }, + ], + { + detailedDistance: false, + detailedDuration: true, + points: true, + }, + ); + expect(routes).toHaveLength(1); + expect(routes[0].spacetimeWaypoints).toHaveLength(2); + expect(routes[0].spacetimeWaypoints[1].duration).toBe(1800); + expect(routes[0].spacetimeWaypoints[1].distance).toBeUndefined(); + }); + + it('should create one route with points and missed waypoints extrapolations', async () => { + const routes = await graphhopperGeorouter.routes( + [ + { + type: PathType.DRIVER, + points: [ + { + lat: 0, + lon: 0, + }, + { + lat: 5, + lon: 5, + }, + { + lat: 10, + lon: 10, + }, + ], + }, + ], + { + detailedDistance: false, + detailedDuration: true, + points: true, + }, + ); + expect(routes).toHaveLength(1); + expect(routes[0].spacetimeWaypoints).toHaveLength(3); + expect(routes[0].distance).toBe(50000); + expect(routes[0].duration).toBe(1800); + expect(routes[0].fwdAzimuth).toBe(45); + expect(routes[0].backAzimuth).toBe(225); + expect(routes[0].points.length).toBe(9); + }); + + it('should create one route with points, time and distance', async () => { + const routes = await graphhopperGeorouter.routes( + [ + { + type: PathType.DRIVER, + points: [ + { + lat: 0, + lon: 0, + }, + { + lat: 10, + lon: 10, + }, + ], + }, + ], + { + detailedDistance: true, + detailedDuration: true, + points: true, + }, + ); + expect(routes).toHaveLength(1); + expect(routes[0].spacetimeWaypoints.length).toBe(3); + expect(routes[0].spacetimeWaypoints[1].duration).toBe(990); + expect(routes[0].spacetimeWaypoints[1].distance).toBe(25000); }); }); From 39cebda0b9c5f628d23684d6897844e9162c5acf Mon Sep 17 00:00:00 2001 From: sbriat Date: Wed, 23 Aug 2023 14:37:25 +0200 Subject: [PATCH 20/24] fix module --- .../geography/core/application/ports/georouter.port.ts | 3 +-- src/modules/geography/geography.module.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/modules/geography/core/application/ports/georouter.port.ts b/src/modules/geography/core/application/ports/georouter.port.ts index 51e56f7..1990e99 100644 --- a/src/modules/geography/core/application/ports/georouter.port.ts +++ b/src/modules/geography/core/application/ports/georouter.port.ts @@ -1,6 +1,5 @@ +import { Path, Route } from '../../domain/route.types'; import { GeorouterSettings } from '../types/georouter-settings.type'; -import { Path } from '../types/path.type'; -import { Route } from '../types/route.type'; export interface GeorouterPort { routes(paths: Path[], settings: GeorouterSettings): Promise; diff --git a/src/modules/geography/geography.module.ts b/src/modules/geography/geography.module.ts index 8c2df42..992869f 100644 --- a/src/modules/geography/geography.module.ts +++ b/src/modules/geography/geography.module.ts @@ -3,6 +3,7 @@ import { CqrsModule } from '@nestjs/cqrs'; import { DIRECTION_ENCODER, GEODESIC, + GEOROUTER, PARAMS_PROVIDER, } from './geography.di-tokens'; import { DefaultParamsProvider } from './infrastructure/default-params-provider'; @@ -10,6 +11,8 @@ import { PostgresDirectionEncoder } from './infrastructure/postgres-direction-en import { GetBasicRouteController } from './interface/controllers/get-basic-route.controller'; import { RouteMapper } from './route.mapper'; import { Geodesic } from './infrastructure/geodesic'; +import { GraphhopperGeorouter } from './infrastructure/graphhopper-georouter'; +import { HttpModule } from '@nestjs/axios'; const mappers: Provider[] = [RouteMapper]; @@ -22,6 +25,10 @@ const adapters: Provider[] = [ provide: DIRECTION_ENCODER, useClass: PostgresDirectionEncoder, }, + { + provide: GEOROUTER, + useClass: GraphhopperGeorouter, + }, { provide: GEODESIC, useClass: Geodesic, @@ -30,7 +37,7 @@ const adapters: Provider[] = [ ]; @Module({ - imports: [CqrsModule], + imports: [CqrsModule, HttpModule], providers: [...mappers, ...adapters], exports: [RouteMapper, DIRECTION_ENCODER, GetBasicRouteController], }) From 9799f78bd2a5f3368707650154d28ccc4dde269d Mon Sep 17 00:00:00 2001 From: sbriat Date: Thu, 24 Aug 2023 14:08:49 +0200 Subject: [PATCH 21/24] functional ad insert --- package-lock.json | 3159 ++++++----------- package.json | 2 +- .../20230823125530_init/migration.sql | 68 + prisma/migrations/migration_lock.toml | 3 + prisma/schema.prisma | 1 - src/modules/ad/ad.mapper.ts | 19 +- src/modules/ad/ad.module.ts | 4 + .../commands/create-ad/create-ad.service.ts | 2 +- .../application/ports/ad.repository.port.ts | 4 +- .../ad/infrastructure/ad.repository.ts | 23 +- .../ad-created.message-handler.ts | 2 +- src/modules/ad/tests/unit/ad.mapper.spec.ts | 10 +- .../ad/tests/unit/core/ad.entity.spec.ts | 8 +- .../tests/unit/core/create-ad.service.spec.ts | 10 +- .../unit/core/point.value-object.spec.ts | 24 +- .../unit/core/waypoint.value-object.spec.ts | 28 +- src/modules/geography/geography.module.ts | 5 +- src/modules/geography/route.mapper.ts | 18 +- .../core/coordinates.value-object.spec.ts | 24 +- .../unit/core/get-route.query-handler.spec.ts | 8 +- .../tests/unit/core/route.entity.spec.ts | 8 +- .../core/spacetime-point.value-object.spec.ts | 32 +- .../unit/core/waypoint.value-object.spec.ts | 28 +- .../get-basic-route.controller.spec.ts | 8 +- 24 files changed, 1390 insertions(+), 2108 deletions(-) create mode 100644 prisma/migrations/20230823125530_init/migration.sql create mode 100644 prisma/migrations/migration_lock.toml diff --git a/package-lock.json b/package-lock.json index b798ee2..27bd203 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@grpc/proto-loader": "^0.7.6", "@liaoliaots/nestjs-redis": "^9.0.5", "@mobicoop/configuration-module": "^1.2.0", - "@mobicoop/ddd-library": "^1.0.0", + "@mobicoop/ddd-library": "^1.1.0", "@mobicoop/health-module": "^2.0.0", "@mobicoop/message-broker-module": "^1.2.0", "@nestjs/axios": "^2.0.0", @@ -70,17 +70,15 @@ }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/@acuminous/bitsyntax": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", - "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", + "license": "MIT", "dependencies": { "buffer-more-ints": "~1.0.0", "debug": "^4.3.4", @@ -92,9 +90,8 @@ }, "node_modules/@ampproject/remapping": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -105,9 +102,8 @@ }, "node_modules/@angular-devkit/core": { "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.0.1.tgz", - "integrity": "sha512-2uz98IqkKJlgnHbWQ7VeL4pb+snGAZXIama2KXi+k9GsRntdcw+udX8rL3G9SdUGUF+m6+147Y1oRBMHsO/v4w==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", @@ -131,9 +127,8 @@ }, "node_modules/@angular-devkit/schematics": { "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.0.1.tgz", - "integrity": "sha512-A9D0LTYmiqiBa90GKcSuWb7hUouGIbm/AHbJbjL85WLLRbQA2PwKl7P5Mpd6nS/ZC0kfG4VQY3VOaDvb3qpI9g==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.0.1", "jsonc-parser": "3.2.0", @@ -149,9 +144,8 @@ }, "node_modules/@angular-devkit/schematics-cli": { "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-16.0.1.tgz", - "integrity": "sha512-6KLA125dpgd6oJGtiO2JpZAb92uOG3njQGIt7NFcuQGW/5GO7J41vMXH9cBAfdtbV8SIggSmR/cIEE9ijfj6YQ==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.0.1", "@angular-devkit/schematics": "16.0.1", @@ -171,9 +165,8 @@ }, "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -197,9 +190,8 @@ }, "node_modules/@babel/code-frame": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/highlight": "^7.22.10", "chalk": "^2.4.2" @@ -210,9 +202,8 @@ }, "node_modules/@babel/code-frame/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -222,9 +213,8 @@ }, "node_modules/@babel/code-frame/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -236,42 +226,37 @@ }, "node_modules/@babel/code-frame/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/code-frame/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/code-frame/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -281,18 +266,16 @@ }, "node_modules/@babel/compat-data": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.10", @@ -320,24 +303,21 @@ }, "node_modules/@babel/core/node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.10", "@jridgewell/gen-mapping": "^0.3.2", @@ -350,9 +330,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.9", "@babel/helper-validator-option": "^7.22.5", @@ -366,36 +345,32 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.22.5", "@babel/types": "^7.22.5" @@ -406,9 +381,8 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -418,9 +392,8 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -430,9 +403,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-module-imports": "^7.22.5", @@ -449,18 +421,16 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -470,9 +440,8 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -482,36 +451,32 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.22.5", "@babel/traverse": "^7.22.10", @@ -523,9 +488,8 @@ }, "node_modules/@babel/highlight": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.4.2", @@ -537,9 +501,8 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -549,9 +512,8 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -563,42 +525,37 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -608,9 +565,8 @@ }, "node_modules/@babel/parser": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -620,9 +576,8 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -632,9 +587,8 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -644,9 +598,8 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -656,9 +609,8 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -668,9 +620,8 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -680,9 +631,8 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -695,9 +645,8 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -707,9 +656,8 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -719,9 +667,8 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -731,9 +678,8 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -743,9 +689,8 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -755,9 +700,8 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -767,9 +711,8 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -782,9 +725,8 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", - "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -797,9 +739,8 @@ }, "node_modules/@babel/template": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.5", "@babel/parser": "^7.22.5", @@ -811,9 +752,8 @@ }, "node_modules/@babel/traverse": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.10", "@babel/generator": "^7.22.10", @@ -832,18 +772,16 @@ }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5", @@ -855,15 +793,13 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@colors/colors": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.1.90" @@ -871,9 +807,8 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -883,9 +818,8 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -893,9 +827,8 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -908,18 +841,16 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -940,9 +871,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -956,23 +886,20 @@ }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@eslint/js": { "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@golevelup/nestjs-common": { "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.5.tgz", - "integrity": "sha512-WqxGAP4KZjvUea/lYCEfFXB8fS3NwxEWgrQpz2H8jusbz11OSrLECv5TNU9RIRKFnUPbGevy45dvKHF2JTQfJw==", + "license": "MIT", "dependencies": { "lodash": "^4.17.21", "nanoid": "^3.2.0" @@ -983,8 +910,7 @@ }, "node_modules/@golevelup/nestjs-discovery": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.1.tgz", - "integrity": "sha512-kK/GBYVxb8XGlwXgtCWAkPOwDVh7dXyLRaoZuk2bBYntV3DZkYGAIbLKOFTGz+MGz71vEeQ9bGLP7cHKtCee4g==", + "license": "MIT", "dependencies": { "lodash": "^4.17.15" }, @@ -995,8 +921,7 @@ }, "node_modules/@golevelup/nestjs-modules": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.6.1.tgz", - "integrity": "sha512-E0STg8In8fhIivnGDJAA70+XLPHzK5bMTkCnif9FbZ8waTYDQ3T/QQL0h73k+CUFeznn1hmuEW14sNaE+8cd7w==", + "license": "MIT", "dependencies": { "lodash": "^4.17.21" }, @@ -1007,8 +932,7 @@ }, "node_modules/@golevelup/nestjs-rabbitmq": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@golevelup/nestjs-rabbitmq/-/nestjs-rabbitmq-3.7.0.tgz", - "integrity": "sha512-wV6SA8oCTu8v66U5i3vu/k6DEvlHKM+LTb9JY7Iz8C0nUUuf6pufgvAalusAi4iJJ7/7p3Q44LF38SB4buszWw==", + "license": "MIT", "dependencies": { "@golevelup/nestjs-common": "^1.4.5", "@golevelup/nestjs-discovery": "^3.0.1", @@ -1026,8 +950,7 @@ }, "node_modules/@golevelup/nestjs-rabbitmq/node_modules/amqplib": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", - "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "license": "MIT", "dependencies": { "bitsyntax": "~0.1.0", "bluebird": "^3.7.2", @@ -1042,8 +965,6 @@ }, "node_modules/@golevelup/nestjs-rabbitmq/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -1057,12 +978,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/@grpc/grpc-js": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.0.tgz", - "integrity": "sha512-H8+iZh+kCE6VR/Krj6W28Y/ZlxoZ1fOzsNt77nrdE3knkbSelW1Uus192xOFCxHyeszLj8i4APQkSIXjAoOxXg==", + "license": "Apache-2.0", "dependencies": { "@grpc/proto-loader": "^0.7.0", "@types/node": ">=12.12.47" @@ -1073,8 +994,7 @@ }, "node_modules/@grpc/proto-loader": { "version": "0.7.8", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.8.tgz", - "integrity": "sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA==", + "license": "Apache-2.0", "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", @@ -1091,9 +1011,8 @@ }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", @@ -1105,9 +1024,8 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1118,20 +1036,17 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@ioredis/commands": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" + "license": "MIT" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -1145,27 +1060,24 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -1176,9 +1088,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1189,9 +1100,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -1201,9 +1111,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -1216,9 +1125,8 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -1228,27 +1136,24 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.2.tgz", - "integrity": "sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.1", "@types/node": "*", @@ -1263,9 +1168,8 @@ }, "node_modules/@jest/core": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.2.tgz", - "integrity": "sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.6.2", "@jest/reporters": "^29.6.2", @@ -1310,9 +1214,8 @@ }, "node_modules/@jest/environment": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.2.tgz", - "integrity": "sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q==", "dev": true, + "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.6.2", "@jest/types": "^29.6.1", @@ -1325,9 +1228,8 @@ }, "node_modules/@jest/expect": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.2.tgz", - "integrity": "sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.6.2", "jest-snapshot": "^29.6.2" @@ -1338,9 +1240,8 @@ }, "node_modules/@jest/expect-utils": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.2.tgz", - "integrity": "sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.4.3" }, @@ -1350,9 +1251,8 @@ }, "node_modules/@jest/fake-timers": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.2.tgz", - "integrity": "sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.1", "@sinonjs/fake-timers": "^10.0.2", @@ -1367,9 +1267,8 @@ }, "node_modules/@jest/globals": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.2.tgz", - "integrity": "sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.6.2", "@jest/expect": "^29.6.2", @@ -1382,9 +1281,8 @@ }, "node_modules/@jest/reporters": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.2.tgz", - "integrity": "sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^29.6.2", @@ -1425,9 +1323,8 @@ }, "node_modules/@jest/schemas": { "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", - "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", "dev": true, + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -1437,9 +1334,8 @@ }, "node_modules/@jest/source-map": { "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.0.tgz", - "integrity": "sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", @@ -1451,9 +1347,8 @@ }, "node_modules/@jest/test-result": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.2.tgz", - "integrity": "sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.6.2", "@jest/types": "^29.6.1", @@ -1466,9 +1361,8 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.2.tgz", - "integrity": "sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.6.2", "graceful-fs": "^4.2.9", @@ -1481,9 +1375,8 @@ }, "node_modules/@jest/transform": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.2.tgz", - "integrity": "sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.1", @@ -1507,9 +1400,8 @@ }, "node_modules/@jest/types": { "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", - "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.0", "@types/istanbul-lib-coverage": "^2.0.0", @@ -1524,9 +1416,8 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1538,27 +1429,24 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -1566,15 +1454,13 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1582,8 +1468,7 @@ }, "node_modules/@liaoliaots/nestjs-redis": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@liaoliaots/nestjs-redis/-/nestjs-redis-9.0.5.tgz", - "integrity": "sha512-nPcGLj0zW4mEsYtQYfWx3o7PmrMjuzFk6+t/g2IRopAeWWUZZ/5nIJ4KTKiz/3DJEUkbX8PZqB+dOhklGF0SVA==", + "license": "MIT", "dependencies": { "tslib": "2.4.1" }, @@ -1598,16 +1483,14 @@ }, "node_modules/@lukeed/csprng": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", - "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@mobicoop/configuration-module": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@mobicoop/configuration-module/-/configuration-module-1.2.0.tgz", - "integrity": "sha512-l0iDae7SgVVmjnCa2MBqAr3Er0yn4E7yiG8e7cs4XtNGUKrC1N0Ju56TEAraEYK9aZAZ36TCs06m1fep+rgwFA==", + "license": "AGPL", "dependencies": { "@golevelup/nestjs-rabbitmq": "^3.6.0", "@liaoliaots/nestjs-redis": "^9.0.5", @@ -1622,9 +1505,9 @@ } }, "node_modules/@mobicoop/ddd-library": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@mobicoop/ddd-library/-/ddd-library-1.0.0.tgz", - "integrity": "sha512-uOF2n2VqgfVP4QldEPGMuR3VPn0U5+XXQw5CK1E/9IHXIgiqdmAnKHX5qUpcr29mKbU5QvQbBuIyMeQqCFVu+w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mobicoop/ddd-library/-/ddd-library-1.1.0.tgz", + "integrity": "sha512-x4X7j2CJYZQPDZgLuZP5TFk59fle1wTPdX++Z2YyD7VwwV+yOmVvMIRfTyLRFUTzLObrd6FKs8mh+g59n9jUlA==", "dependencies": { "@nestjs/event-emitter": "^1.4.2", "@nestjs/microservices": "^9.4.0", @@ -1638,8 +1521,7 @@ }, "node_modules/@mobicoop/health-module": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@mobicoop/health-module/-/health-module-2.0.0.tgz", - "integrity": "sha512-r/7zrHJKVRTIiZ50ILy3lEUC/9vi6k0TRcYPMS8zcnUssQg+MPcT5DQS9B9tTB2gkKwcCyxOQlZZIppIybFX3A==", + "license": "AGPL", "dependencies": { "@grpc/grpc-js": "^1.8.14", "@grpc/proto-loader": "^0.7.7", @@ -1656,8 +1538,7 @@ }, "node_modules/@mobicoop/health-module/node_modules/@mobicoop/ddd-library": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@mobicoop/ddd-library/-/ddd-library-0.3.0.tgz", - "integrity": "sha512-MoUDqlrDmJkumCFSyW9FY2DLbguT4rytFrmBt9tVNCr2Es6nlz4Ml3HVBwJTZrlJFU79XmiUQ5WAO0MHJt+nAg==", + "license": "AGPL", "dependencies": { "@nestjs/event-emitter": "^1.4.2", "@nestjs/microservices": "^9.4.0", @@ -1671,8 +1552,7 @@ }, "node_modules/@mobicoop/health-module/node_modules/@nestjs/axios": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.0.tgz", - "integrity": "sha512-ULdH03jDWkS5dy9X69XbUVbhC+0pVnrRcj7bIK/ytTZ76w7CgvTZDJqsIyisg3kNOiljRW/4NIjSf3j6YGvl+g==", + "license": "MIT", "peerDependencies": { "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", "axios": "^1.3.1", @@ -1682,8 +1562,7 @@ }, "node_modules/@mobicoop/message-broker-module": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@mobicoop/message-broker-module/-/message-broker-module-1.2.0.tgz", - "integrity": "sha512-RoSHHK1GyQ/QVDmm3JS/wBfh171oChvyEp6YWmJd12krFLrPVn9MoEvZdyT3I5J31oBiUabMPle5Kdpw+Nrmww==", + "license": "AGPL", "dependencies": { "@golevelup/nestjs-rabbitmq": "^3.6.0", "@types/amqplib": "^0.10.1", @@ -1695,8 +1574,7 @@ }, "node_modules/@nestjs/axios": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-2.0.0.tgz", - "integrity": "sha512-F6oceoQLEn031uun8NiommeMkRIojQqVryxQy/mK7fx0CI0KbgkJL3SloCQcsOD+agoEnqKJKXZpEvL6FNswJg==", + "license": "MIT", "peerDependencies": { "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0", "axios": "^1.3.1", @@ -1706,8 +1584,7 @@ }, "node_modules/@nestjs/cache-manager": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-1.0.0.tgz", - "integrity": "sha512-XMNdgsj3H+Ng/SYwFl13vRGNFA3e5Obk8LNwIuHLVSocnK2exReAWtscxEjQhoBc4FW4jAYOgU/U+mt18Q9T0g==", + "license": "MIT", "peerDependencies": { "@nestjs/common": "^9.0.0", "cache-manager": "<=5", @@ -1717,9 +1594,8 @@ }, "node_modules/@nestjs/cli": { "version": "9.5.0", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.5.0.tgz", - "integrity": "sha512-Z7q+3vNsQSG2d2r2Hl/OOj5EpfjVx3OfnJ9+KuAsOdw1sKLm7+Zc6KbhMFTd/eIvfx82ww3Nk72xdmfPYCulWA==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.0.1", "@angular-devkit/schematics": "16.0.1", @@ -1753,9 +1629,8 @@ }, "node_modules/@nestjs/cli/node_modules/webpack": { "version": "5.82.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.1.tgz", - "integrity": "sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -1800,8 +1675,7 @@ }, "node_modules/@nestjs/common": { "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-9.4.3.tgz", - "integrity": "sha512-Gd6D4IaYj01o14Bwv81ukidn4w3bPHCblMUq+SmUmWLyosK+XQmInCS09SbDDZyL8jy86PngtBLTdhJ2bXSUig==", + "license": "MIT", "dependencies": { "iterare": "1.2.1", "tslib": "2.5.3", @@ -1832,13 +1706,11 @@ }, "node_modules/@nestjs/common/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "license": "0BSD" }, "node_modules/@nestjs/config": { "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-2.3.4.tgz", - "integrity": "sha512-IGdSF+0F9MJO6dCRTEahdxPz4iVijjtolcFBxnY+2QYM3bXYQvAgzskGZi+WkAFJN/VzR3TEp60gN5sI74GxPA==", + "license": "MIT", "dependencies": { "dotenv": "16.1.4", "dotenv-expand": "10.0.0", @@ -1853,9 +1725,8 @@ }, "node_modules/@nestjs/core": { "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-9.4.3.tgz", - "integrity": "sha512-Qi63+wi55Jh4sDyaj5Hhx2jOpKqT386aeo+VOKsxnd+Ql9VvkO/FjmuwBGUyzkJt29ENYc+P0Sx/k5LtstNpPQ==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", @@ -1890,13 +1761,11 @@ }, "node_modules/@nestjs/core/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "license": "0BSD" }, "node_modules/@nestjs/cqrs": { "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@nestjs/cqrs/-/cqrs-9.0.4.tgz", - "integrity": "sha512-nWDF+xs4jqs6OjxFg/wVSd0NiIV9+EFCJrJNTo4VRWe78CcAaitbp56CBspUh4gKyfkci95i+EhHdEqRXKFptg==", + "license": "MIT", "dependencies": { "uuid": "9.0.0" }, @@ -1909,8 +1778,7 @@ }, "node_modules/@nestjs/event-emitter": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@nestjs/event-emitter/-/event-emitter-1.4.2.tgz", - "integrity": "sha512-5mskPMS4KVH6LghC+NynfdmGiMCOOv9CdgVpuWGipLrJECv5KWc7vaW5o/9BYrcqPkN7Ted6CJ+O4AfsTiRlgw==", + "license": "MIT", "dependencies": { "eventemitter2": "6.4.9" }, @@ -1922,8 +1790,7 @@ }, "node_modules/@nestjs/microservices": { "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-9.4.3.tgz", - "integrity": "sha512-piMw8d3C4ppc5St5AhQEtecMhyeBK2Q1VYk4AL3NKtG6U0fzz/6KLiETpWdKXmazeI/m7qac2upOvwmRzle0aA==", + "license": "MIT", "dependencies": { "iterare": "1.2.1", "tslib": "2.5.3" @@ -1979,13 +1846,11 @@ }, "node_modules/@nestjs/microservices/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "license": "0BSD" }, "node_modules/@nestjs/platform-express": { "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-9.4.3.tgz", - "integrity": "sha512-FpdczWoRSC0zz2dNL9u2AQLXKXRVtq4HgHklAhbL59X0uy+mcxhlSThG7DHzDMkoSnuuHY8ojDVf7mDxk+GtCw==", + "license": "MIT", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", @@ -2004,14 +1869,12 @@ }, "node_modules/@nestjs/platform-express/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "license": "0BSD" }, "node_modules/@nestjs/schematics": { "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-9.2.0.tgz", - "integrity": "sha512-wHpNJDPzM6XtZUOB3gW0J6mkFCSJilzCM3XrHI1o0C8vZmFE1snbmkIXNyoi1eV0Nxh1BMymcgz5vIMJgQtTqw==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.0.1", "@angular-devkit/schematics": "16.0.1", @@ -2024,8 +1887,7 @@ }, "node_modules/@nestjs/terminus": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/@nestjs/terminus/-/terminus-9.2.2.tgz", - "integrity": "sha512-AWUA8XLcgxWUjUFYHDqi42M7CZn2e+DEWxP+MqNAbMzz4ybB5jGcFK5Fy8qwaNBoWg6KMF1JiXOOygGXgk9ydg==", + "license": "MIT", "dependencies": { "boxen": "5.1.2", "check-disk-space": "3.3.1" @@ -2089,9 +1951,8 @@ }, "node_modules/@nestjs/testing": { "version": "9.4.3", - "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-9.4.3.tgz", - "integrity": "sha512-LDT8Ai2eKnTzvnPaJwWOK03qTaFap5uHHsJCv6dL0uKWk6hyF9jms8DjyVaGsaujCaXDG8izl1mDEER0OmxaZA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "2.5.3" }, @@ -2116,15 +1977,13 @@ }, "node_modules/@nestjs/testing/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2135,18 +1994,16 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2157,8 +2014,7 @@ }, "node_modules/@nuxtjs/opencollective": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", - "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==", + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "consola": "^2.15.0", @@ -2174,9 +2030,8 @@ }, "node_modules/@prisma/client": { "version": "4.16.2", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.16.2.tgz", - "integrity": "sha512-qCoEyxv1ZrQ4bKy39GnylE8Zq31IRmm8bNhNbZx7bF2cU5aiCCnSa93J2imF88MBjn7J9eUQneNxUQVJdl/rPQ==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@prisma/engines-version": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81" }, @@ -2194,40 +2049,33 @@ }, "node_modules/@prisma/engines": { "version": "4.16.2", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.16.2.tgz", - "integrity": "sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==", "devOptional": true, - "hasInstallScript": true + "hasInstallScript": true, + "license": "Apache-2.0" }, "node_modules/@prisma/engines-version": { "version": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81.tgz", - "integrity": "sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==" + "license": "Apache-2.0" }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -2235,39 +2083,32 @@ }, "node_modules/@protobufjs/float": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "license": "BSD-3-Clause" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -2277,26 +2118,23 @@ }, "node_modules/@sinonjs/commons": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.0" }, @@ -2306,32 +2144,27 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@turf/boolean-point-in-polygon": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-6.5.0.tgz", - "integrity": "sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A==", + "license": "MIT", "dependencies": { "@turf/helpers": "^6.5.0", "@turf/invariant": "^6.5.0" @@ -2342,16 +2175,14 @@ }, "node_modules/@turf/helpers": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", - "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", + "license": "MIT", "funding": { "url": "https://opencollective.com/turf" } }, "node_modules/@turf/invariant": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", - "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", + "license": "MIT", "dependencies": { "@turf/helpers": "^6.5.0" }, @@ -2361,17 +2192,15 @@ }, "node_modules/@types/amqplib": { "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.10.1.tgz", - "integrity": "sha512-j6ANKT79ncUDnAs/+9r9eDujxbeJoTjoVu33gHHcaPfmLQaMhvfbH2GqSe8KUM444epAp1Vl3peVOQfZk3UIqA==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/babel__core": { "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", - "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -2382,18 +2211,16 @@ }, "node_modules/@types/babel__generator": { "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" @@ -2401,18 +2228,16 @@ }, "node_modules/@types/babel__traverse": { "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", - "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" } }, "node_modules/@types/body-parser": { "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dev": true, + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -2420,8 +2245,7 @@ }, "node_modules/@types/cacheable-request": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "license": "MIT", "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", @@ -2431,24 +2255,21 @@ }, "node_modules/@types/connect": { "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/cookiejar": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/eslint": { "version": "8.44.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", - "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -2456,9 +2277,8 @@ }, "node_modules/@types/eslint-scope": { "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -2466,15 +2286,13 @@ }, "node_modules/@types/estree": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/express": { "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2484,9 +2302,8 @@ }, "node_modules/@types/express-serve-static-core": { "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2496,53 +2313,46 @@ }, "node_modules/@types/graceful-fs": { "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", - "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/http-cache-semantics": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + "license": "MIT" }, "node_modules/@types/http-errors": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/jest": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" @@ -2550,71 +2360,60 @@ }, "node_modules/@types/json-schema": { "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/keyv": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/long": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" + "license": "MIT" }, "node_modules/@types/parse-json": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/qs": { "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/responselike": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/semver": { "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/send": { "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -2622,9 +2421,8 @@ }, "node_modules/@types/serve-static": { "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", - "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", "dev": true, + "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -2633,15 +2431,13 @@ }, "node_modules/@types/stack-utils": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/superagent": { "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.18.tgz", - "integrity": "sha512-LOWgpacIV8GHhrsQU+QMZuomfqXiqzz3ILLkCtKx3Us6AmomFViuzKT9D693QTKgyut2oCytMG8/efOop+DB+w==", "dev": true, + "license": "MIT", "dependencies": { "@types/cookiejar": "*", "@types/node": "*" @@ -2649,44 +2445,38 @@ }, "node_modules/@types/supertest": { "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz", - "integrity": "sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/superagent": "*" } }, "node_modules/@types/uuid": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", - "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/validator": { "version": "13.11.1", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz", - "integrity": "sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A==" + "license": "MIT" }, "node_modules/@types/yargs": { "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -2718,9 +2508,8 @@ }, "node_modules/@typescript-eslint/parser": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -2745,9 +2534,8 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0" @@ -2762,9 +2550,8 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", @@ -2789,9 +2576,8 @@ }, "node_modules/@typescript-eslint/types": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2802,9 +2588,8 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0", @@ -2829,9 +2614,8 @@ }, "node_modules/@typescript-eslint/utils": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -2855,9 +2639,8 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" @@ -2872,9 +2655,8 @@ }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -2882,27 +2664,23 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -2911,15 +2689,13 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -2929,33 +2705,29 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -2969,9 +2741,8 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -2982,9 +2753,8 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -2994,9 +2764,8 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3008,9 +2777,8 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" @@ -3018,20 +2786,17 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/accepts": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -3042,9 +2807,8 @@ }, "node_modules/acorn": { "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3054,36 +2818,32 @@ }, "node_modules/acorn-import-assertions": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^8" } }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/ajv": { "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -3097,9 +2857,8 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -3114,8 +2873,7 @@ }, "node_modules/amqp-connection-manager": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.9.0.tgz", - "integrity": "sha512-ZKw9ckJKz40Lc2pC7DY0NVocpzPalMaCgv0sBn+N4er2QFAJul9pIiMOm/FsPHeCzB+FulV7PckOpmZvWvewGQ==", + "license": "MIT", "dependencies": { "promise-breaker": "^5.0.0" }, @@ -3129,8 +2887,7 @@ }, "node_modules/amqplib": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", - "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "license": "MIT", "dependencies": { "@acuminous/bitsyntax": "^0.1.2", "buffer-more-ints": "~1.0.0", @@ -3143,26 +2900,23 @@ }, "node_modules/ansi-align": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", "dependencies": { "string-width": "^4.1.0" } }, "node_modules/ansi-colors": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -3175,9 +2929,8 @@ }, "node_modules/ansi-escapes/node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3187,16 +2940,14 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -3209,9 +2960,8 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3222,55 +2972,46 @@ }, "node_modules/append-field": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + "license": "MIT" }, "node_modules/arg": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "license": "MIT" }, "node_modules/array-source": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/array-source/-/array-source-0.0.4.tgz", - "integrity": "sha512-frNdc+zBn80vipY+GdcJkLEbMWj3xmzArYApmUGxoiV8uAu/ygcs9icPdsGdA26h0MkHUMW6EN2piIvVx+M5Mw==" + "license": "BSD-3-Clause" }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asap": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "license": "MIT" }, "node_modules/axios": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -3279,9 +3020,8 @@ }, "node_modules/babel-jest": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", - "integrity": "sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==", "dev": true, + "license": "MIT", "dependencies": { "@jest/transform": "^29.6.2", "@types/babel__core": "^7.1.14", @@ -3300,9 +3040,8 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -3316,9 +3055,8 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -3331,9 +3069,8 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -3354,9 +3091,8 @@ }, "node_modules/babel-preset-jest": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" @@ -3370,14 +3106,11 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { @@ -3392,21 +3125,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/bitsyntax": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", - "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "license": "MIT", "dependencies": { "buffer-more-ints": "~1.0.0", "debug": "~2.6.9", @@ -3418,22 +3150,19 @@ }, "node_modules/bitsyntax/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/bitsyntax/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -3442,9 +3171,8 @@ }, "node_modules/bl/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3456,8 +3184,6 @@ }, "node_modules/bl/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -3472,26 +3198,24 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/bl/node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/bluebird": { "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -3513,21 +3237,18 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/boxen": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "license": "MIT", "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^6.2.0", @@ -3547,9 +3268,8 @@ }, "node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3557,9 +3277,8 @@ }, "node_modules/braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -3569,8 +3288,6 @@ }, "node_modules/browserslist": { "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -3586,6 +3303,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001517", "electron-to-chromium": "^1.4.477", @@ -3601,9 +3319,8 @@ }, "node_modules/bs-logger": { "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -3613,17 +3330,14 @@ }, "node_modules/bser": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "dev": true, "funding": [ { @@ -3639,6 +3353,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -3646,18 +3361,14 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "license": "MIT" }, "node_modules/buffer-more-ints": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", - "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + "license": "MIT" }, "node_modules/busboy": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dependencies": { "streamsearch": "^1.1.0" }, @@ -3667,16 +3378,14 @@ }, "node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/cache-manager": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.2.3.tgz", - "integrity": "sha512-9OErI8fksFkxAMJ8Mco0aiZSdphyd90HcKiOMJQncSlU1yq/9lHHxrT8PDayxrmr9IIIZPOAEfXuGSD7g29uog==", + "license": "MIT", "dependencies": { "lodash.clonedeep": "^4.5.0", "lru-cache": "^9.1.2" @@ -3684,8 +3393,7 @@ }, "node_modules/cache-manager-ioredis-yet": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cache-manager-ioredis-yet/-/cache-manager-ioredis-yet-1.2.2.tgz", - "integrity": "sha512-o03N/tQxfFONZ1XLGgIxOFHuQQpjpRdnSAL1THG1YWZIVp1JMUfjU3ElSAjFN1LjbJXa55IpC8waG+VEoLUCUw==", + "license": "MIT", "dependencies": { "cache-manager": "^5.2.3", "ioredis": "^5.3.2" @@ -3696,16 +3404,14 @@ }, "node_modules/cacheable-lookup": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "license": "MIT", "engines": { "node": ">=10.6.0" } }, "node_modules/cacheable-request": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "license": "MIT", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -3721,8 +3427,7 @@ }, "node_modules/call-bind": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -3733,17 +3438,15 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3753,8 +3456,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001521", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001521.tgz", - "integrity": "sha512-fnx1grfpEOvDGH+V17eccmNjucGUnCbP6KL+l5KqBIerp26WK/+RQ7CIDE37KGJjaPyqWXXlFUyKiWmvdNNKmQ==", "dev": true, "funding": [ { @@ -3769,12 +3470,12 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3788,31 +3489,26 @@ }, "node_modules/char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/chardet": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/check-disk-space": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.3.1.tgz", - "integrity": "sha512-iOrT8yCZjSnyNZ43476FE2rnssvgw5hnuwOM0hm8Nj1qa0v4ieUUEbCyxxsEliaoDUb/75yCOL71zkDiDBLbMQ==", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/chokidar": { "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { @@ -3820,6 +3516,7 @@ "url": "https://paulmillr.com/funding/" } ], + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -3838,17 +3535,14 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true, "funding": [ { @@ -3856,25 +3550,23 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/class-transformer": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", - "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==" + "license": "MIT" }, "node_modules/class-validator": { "version": "0.14.0", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.0.tgz", - "integrity": "sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A==", + "license": "MIT", "dependencies": { "@types/validator": "^13.7.10", "libphonenumber-js": "^1.10.14", @@ -3883,8 +3575,7 @@ }, "node_modules/cli-boxes": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -3894,9 +3585,8 @@ }, "node_modules/cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -3906,9 +3596,8 @@ }, "node_modules/cli-spinners": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -3918,9 +3607,8 @@ }, "node_modules/cli-table3": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, + "license": "MIT", "dependencies": { "string-width": "^4.2.0" }, @@ -3933,17 +3621,15 @@ }, "node_modules/cli-width": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, + "license": "ISC", "engines": { "node": ">= 10" } }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -3955,17 +3641,15 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/clone-response": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "license": "MIT", "dependencies": { "mimic-response": "^1.0.0" }, @@ -3975,17 +3659,15 @@ }, "node_modules/cluster-key-slot": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", "engines": { "node": ">=0.10.0" } }, "node_modules/co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -3993,14 +3675,12 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4010,13 +3690,11 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4026,32 +3704,28 @@ }, "node_modules/commander": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/component-emitter": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "engines": [ "node >= 6.0" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -4061,8 +3735,7 @@ }, "node_modules/concat-stream/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -4074,8 +3747,6 @@ }, "node_modules/concat-stream/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4089,25 +3760,23 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/concat-stream/node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/consola": { "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -4117,8 +3786,6 @@ }, "node_modules/content-disposition/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4132,50 +3799,44 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/content-type": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "license": "MIT" }, "node_modules/cookiejar": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "license": "MIT" }, "node_modules/cors": { "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -4186,9 +3847,8 @@ }, "node_modules/cosmiconfig": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -4202,15 +3862,13 @@ }, "node_modules/create-require": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4222,8 +3880,7 @@ }, "node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -4238,8 +3895,7 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" }, @@ -4252,8 +3908,7 @@ }, "node_modules/decompress-response/node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -4263,9 +3918,8 @@ }, "node_modules/dedent": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", "dev": true, + "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -4277,24 +3931,21 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -4304,40 +3955,35 @@ }, "node_modules/defer-to-connect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/denque": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", "engines": { "node": ">=0.10" } }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -4345,18 +3991,16 @@ }, "node_modules/detect-newline": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/dezalgo": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", "dev": true, + "license": "ISC", "dependencies": { "asap": "^2.0.0", "wrappy": "1" @@ -4364,27 +4008,24 @@ }, "node_modules/diff": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -4394,9 +4035,8 @@ }, "node_modules/doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -4406,8 +4046,7 @@ }, "node_modules/dotenv": { "version": "16.1.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", - "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -4417,9 +4056,8 @@ }, "node_modules/dotenv-cli": { "version": "7.2.1", - "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.2.1.tgz", - "integrity": "sha512-ODHbGTskqRtXAzZapDPvgNuDVQApu4oKX8lZW7Y0+9hKA6le1ZJlyRS687oU9FXjOVEDU/VFV6zI125HzhM1UQ==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "dotenv": "^16.0.0", @@ -4432,28 +4070,24 @@ }, "node_modules/dotenv-expand": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", - "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" } }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.4.492", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.492.tgz", - "integrity": "sha512-36K9b/6skMVwAIEsC7GiQ8I8N3soCALVSHqWHzNDtGemAcI9Xu8hP02cywWM0A794rTHm0b0zHPeLJHtgFVamQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4463,30 +4097,26 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "license": "MIT" }, "node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/end-of-stream": { "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", "dependencies": { "once": "^1.4.0" } }, "node_modules/enhanced-resolve": { "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -4497,37 +4127,32 @@ }, "node_modules/error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-module-lexer": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", - "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4537,9 +4162,8 @@ }, "node_modules/eslint": { "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4591,9 +4215,8 @@ }, "node_modules/eslint-config-prettier": { "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -4603,9 +4226,8 @@ }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", "dev": true, + "license": "MIT", "dependencies": { "prettier-linter-helpers": "^1.0.0" }, @@ -4624,9 +4246,8 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -4637,9 +4258,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4649,9 +4269,8 @@ }, "node_modules/eslint/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4665,9 +4284,8 @@ }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -4681,18 +4299,16 @@ }, "node_modules/eslint/node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -4702,15 +4318,13 @@ }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/espree": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -4725,9 +4339,8 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -4738,9 +4351,8 @@ }, "node_modules/esquery": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -4750,18 +4362,16 @@ }, "node_modules/esquery/node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -4771,58 +4381,51 @@ }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/eventemitter2": { "version": "6.4.9", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", - "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==" + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -4843,9 +4446,8 @@ }, "node_modules/execa/node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4855,8 +4457,6 @@ }, "node_modules/exit": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" @@ -4864,9 +4464,8 @@ }, "node_modules/expect": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.2.tgz", - "integrity": "sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.6.2", "@types/node": "*", @@ -4881,8 +4480,7 @@ }, "node_modules/express": { "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -4922,8 +4520,7 @@ }, "node_modules/express/node_modules/body-parser": { "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -4945,26 +4542,22 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "license": "MIT" }, "node_modules/express/node_modules/raw-body": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -4977,8 +4570,6 @@ }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4992,13 +4583,13 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/external-editor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, + "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -5010,21 +4601,18 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-diff": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/fast-glob": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -5038,44 +4626,38 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + "license": "MIT" }, "node_modules/fastq": { "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fb-watchman": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, "node_modules/figures": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -5088,18 +4670,16 @@ }, "node_modules/figures/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/file-entry-cache": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -5109,17 +4689,15 @@ }, "node_modules/file-source": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/file-source/-/file-source-0.6.1.tgz", - "integrity": "sha512-1R1KneL7eTXmXfKxC10V/9NeGOdbsAXJ+lQ//fvvcHUgtaZcZDWNJNblxAoVOyV1cj45pOtUrR3vZTBwqcW8XA==", + "license": "BSD-3-Clause", "dependencies": { "stream-source": "0.3" } }, "node_modules/fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5129,8 +4707,7 @@ }, "node_modules/finalhandler": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -5146,22 +4723,19 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -5175,9 +4749,8 @@ }, "node_modules/flat-cache": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -5188,9 +4761,8 @@ }, "node_modules/flat-cache/node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -5203,20 +4775,18 @@ }, "node_modules/flatted": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -5228,9 +4798,8 @@ }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", - "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.7", "chalk": "^4.1.2", @@ -5256,8 +4825,7 @@ }, "node_modules/form-data": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5269,9 +4837,8 @@ }, "node_modules/formidable": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", - "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", "dev": true, + "license": "MIT", "dependencies": { "dezalgo": "^1.0.4", "hexoid": "^1.0.0", @@ -5284,25 +4851,22 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fs-extra": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5314,48 +4878,29 @@ }, "node_modules/fs-monkey": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", - "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==", - "dev": true + "dev": true, + "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "license": "ISC" }, "node_modules/function-bind": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "license": "MIT" }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/geo-tz": { "version": "7.0.7", - "resolved": "https://registry.npmjs.org/geo-tz/-/geo-tz-7.0.7.tgz", - "integrity": "sha512-Aq0sRSO1y4w62D5muRqzDmN4SWfFYnt703BLiqiHAvunlwsJs4qd3Fkl1pKSUa0bwuBmPFxIA8M1E+ilg2PSjw==", + "license": "MIT", "dependencies": { "@turf/boolean-point-in-polygon": "^6.5.0", "@turf/helpers": "^6.5.0", @@ -5368,8 +4913,7 @@ }, "node_modules/geobuf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/geobuf/-/geobuf-3.0.2.tgz", - "integrity": "sha512-ASgKwEAQQRnyNFHNvpd5uAwstbVYmiTW0Caw3fBb509tNTqXyAAPMyFs5NNihsLZhLxU1j/kjFhkhLWA9djuVg==", + "license": "ISC", "dependencies": { "concat-stream": "^2.0.0", "pbf": "^3.2.1", @@ -5383,21 +4927,18 @@ }, "node_modules/geographiclib-geodesic": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/geographiclib-geodesic/-/geographiclib-geodesic-2.0.0.tgz", - "integrity": "sha512-qRE11UEF3Zn9VwDFf+Q1ZNn4VW2xwZWeAPiFRrKVSKn2K5lds1jOxhxgFJwbKh5YV58ME6+LGiRtm4A0CjFyiQ==" + "license": "MIT" }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -5410,17 +4951,15 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/get-stream": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -5433,9 +4972,8 @@ }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5453,9 +4991,8 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -5465,15 +5002,13 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/globals": { "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -5486,9 +5021,8 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -5506,8 +5040,7 @@ }, "node_modules/got": { "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -5530,20 +5063,17 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.1" }, @@ -5553,16 +5083,14 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5572,8 +5100,7 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5583,28 +5110,24 @@ }, "node_modules/hexoid": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", - "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-cache-semantics": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + "license": "BSD-2-Clause" }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5618,8 +5141,7 @@ }, "node_modules/http2-wrapper": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" @@ -5630,17 +5152,15 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5650,8 +5170,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -5665,22 +5183,21 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5694,9 +5211,8 @@ }, "node_modules/import-local": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -5713,18 +5229,16 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5732,14 +5246,12 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "license": "ISC" }, "node_modules/inquirer": { "version": "8.2.5", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", - "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -5763,17 +5275,15 @@ }, "node_modules/interpret": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/ioredis": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz", - "integrity": "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==", + "license": "MIT", "dependencies": { "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", @@ -5795,23 +5305,20 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -5821,9 +5328,8 @@ }, "node_modules/is-core-module": { "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, + "license": "MIT", "dependencies": { "has": "^1.0.3" }, @@ -5833,35 +5339,31 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -5871,36 +5373,32 @@ }, "node_modules/is-interactive": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -5910,9 +5408,8 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5922,29 +5419,25 @@ }, "node_modules/isarray": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -5958,18 +5451,16 @@ }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/istanbul-lib-report": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -5981,9 +5472,8 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -5995,18 +5485,16 @@ }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-reports": { "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -6017,17 +5505,15 @@ }, "node_modules/iterare": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", - "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "license": "ISC", "engines": { "node": ">=6" } }, "node_modules/jest": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.5.0", "@jest/types": "^29.5.0", @@ -6051,9 +5537,8 @@ }, "node_modules/jest-changed-files": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", "p-limit": "^3.1.0" @@ -6064,9 +5549,8 @@ }, "node_modules/jest-circus": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.2.tgz", - "integrity": "sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.6.2", "@jest/expect": "^29.6.2", @@ -6095,9 +5579,8 @@ }, "node_modules/jest-cli": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.2.tgz", - "integrity": "sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.6.2", "@jest/test-result": "^29.6.2", @@ -6129,9 +5612,8 @@ }, "node_modules/jest-config": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.2.tgz", - "integrity": "sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^29.6.2", @@ -6174,9 +5656,8 @@ }, "node_modules/jest-diff": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.2.tgz", - "integrity": "sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.4.3", @@ -6189,9 +5670,8 @@ }, "node_modules/jest-docblock": { "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -6201,9 +5681,8 @@ }, "node_modules/jest-each": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.2.tgz", - "integrity": "sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.1", "chalk": "^4.0.0", @@ -6217,9 +5696,8 @@ }, "node_modules/jest-environment-node": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.2.tgz", - "integrity": "sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.6.2", "@jest/fake-timers": "^29.6.2", @@ -6234,18 +5712,16 @@ }, "node_modules/jest-get-type": { "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.2.tgz", - "integrity": "sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.1", "@types/graceful-fs": "^4.1.3", @@ -6268,9 +5744,8 @@ }, "node_modules/jest-leak-detector": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.2.tgz", - "integrity": "sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.4.3", "pretty-format": "^29.6.2" @@ -6281,9 +5756,8 @@ }, "node_modules/jest-matcher-utils": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz", - "integrity": "sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.6.2", @@ -6296,9 +5770,8 @@ }, "node_modules/jest-message-util": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.2.tgz", - "integrity": "sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.1", @@ -6316,9 +5789,8 @@ }, "node_modules/jest-mock": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.2.tgz", - "integrity": "sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.1", "@types/node": "*", @@ -6330,9 +5802,8 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -6347,18 +5818,16 @@ }, "node_modules/jest-regex-util": { "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.2.tgz", - "integrity": "sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", @@ -6376,9 +5845,8 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.2.tgz", - "integrity": "sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w==", "dev": true, + "license": "MIT", "dependencies": { "jest-regex-util": "^29.4.3", "jest-snapshot": "^29.6.2" @@ -6389,9 +5857,8 @@ }, "node_modules/jest-runner": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.2.tgz", - "integrity": "sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.6.2", "@jest/environment": "^29.6.2", @@ -6421,18 +5888,16 @@ }, "node_modules/jest-runner/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/jest-runner/node_modules/source-map-support": { "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -6440,9 +5905,8 @@ }, "node_modules/jest-runtime": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.2.tgz", - "integrity": "sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.6.2", "@jest/fake-timers": "^29.6.2", @@ -6473,9 +5937,8 @@ }, "node_modules/jest-snapshot": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.2.tgz", - "integrity": "sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", @@ -6504,9 +5967,8 @@ }, "node_modules/jest-util": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.2.tgz", - "integrity": "sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.1", "@types/node": "*", @@ -6521,9 +5983,8 @@ }, "node_modules/jest-validate": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.2.tgz", - "integrity": "sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.1", "camelcase": "^6.2.0", @@ -6538,9 +5999,8 @@ }, "node_modules/jest-watcher": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.2.tgz", - "integrity": "sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.6.2", "@jest/types": "^29.6.1", @@ -6557,9 +6017,8 @@ }, "node_modules/jest-worker": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.2.tgz", - "integrity": "sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.6.2", @@ -6572,9 +6031,8 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -6587,15 +6045,13 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6605,9 +6061,8 @@ }, "node_modules/jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -6617,32 +6072,27 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -6652,15 +6102,13 @@ }, "node_modules/jsonc-parser": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -6670,35 +6118,31 @@ }, "node_modules/keyv": { "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/kleur": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -6709,29 +6153,25 @@ }, "node_modules/libphonenumber-js": { "version": "1.10.41", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.41.tgz", - "integrity": "sha512-4rmmF4u4vD3eGNuuCGjCPwRwO+fIuu1WWcS7VwbPTiMFkJd8F02v8o5pY5tlYuMR+xOvJ88mtOHpkm0Tnu2LcQ==" + "license": "MIT" }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.11.5" } }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -6744,46 +6184,38 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "license": "MIT" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + "license": "MIT" }, "node_modules/lodash.defaults": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + "license": "MIT" }, "node_modules/lodash.isarguments": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -6797,30 +6229,26 @@ }, "node_modules/long": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "license": "Apache-2.0" }, "node_modules/lowercase-keys": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/lru-cache": { "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "license": "ISC", "engines": { "node": "14 || >=16.14" } }, "node_modules/macos-release": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", - "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -6830,9 +6258,8 @@ }, "node_modules/magic-string": { "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" }, @@ -6842,9 +6269,8 @@ }, "node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -6857,32 +6283,28 @@ }, "node_modules/make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/makeerror": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } }, "node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memfs": { "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, + "license": "Unlicense", "dependencies": { "fs-monkey": "^1.0.4" }, @@ -6892,37 +6314,32 @@ }, "node_modules/merge-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -6933,8 +6350,7 @@ }, "node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -6944,16 +6360,14 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -6963,26 +6377,23 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mimic-response": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6992,25 +6403,22 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minipass": { "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=8" } }, "node_modules/mkdirp": { "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -7020,13 +6428,11 @@ }, "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "license": "MIT" }, "node_modules/multer": { "version": "1.4.4-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4-lts.1.tgz", - "integrity": "sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==", + "license": "MIT", "dependencies": { "append-field": "^1.0.0", "busboy": "^1.0.0", @@ -7042,11 +6448,10 @@ }, "node_modules/multer/node_modules/concat-stream": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "engines": [ "node >= 0.8" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -7056,13 +6461,11 @@ }, "node_modules/multer/node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "license": "MIT" }, "node_modules/multer/node_modules/readable-stream": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7075,28 +6478,25 @@ }, "node_modules/multer/node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/mute-stream": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/nanoid": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7106,57 +6506,49 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/natural-compare-lite": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/neo-async": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nestjs-request-context": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nestjs-request-context/-/nestjs-request-context-2.1.0.tgz", - "integrity": "sha512-XSZ4CGjgVetyP0q6TSgu+urpUhS8hlY4UxDenPioqEhwpiLCjYFnWrp8NSJctn6NdON5d45LLKz/TN/5ZppL9w==", + "license": "ISC", "peerDependencies": { "@nestjs/common": "^9.0.5" } }, "node_modules/node-abort-controller": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-emoji": { "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.21" } }, "node_modules/node-fetch": { "version": "2.6.12", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7174,29 +6566,25 @@ }, "node_modules/node-int64": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-url": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -7206,9 +6594,8 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -7218,24 +6605,21 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -7245,17 +6629,15 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -7268,9 +6650,8 @@ }, "node_modules/optionator": { "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, + "license": "MIT", "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -7285,9 +6666,8 @@ }, "node_modules/ora": { "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -7308,9 +6688,8 @@ }, "node_modules/os-name": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", - "integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==", "dev": true, + "license": "MIT", "dependencies": { "macos-release": "^2.5.0", "windows-release": "^4.0.0" @@ -7324,26 +6703,23 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/p-cancelable": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7356,9 +6732,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -7371,18 +6746,16 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -7392,9 +6765,8 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -7410,50 +6782,44 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -7467,17 +6833,15 @@ }, "node_modules/path-scurry/node_modules/minipass": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/path-source": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/path-source/-/path-source-0.1.3.tgz", - "integrity": "sha512-dWRHm5mIw5kw0cs3QZLNmpUWty48f5+5v9nWD2dw3Y0Hf+s01Ag8iJEWV0Sm0kocE8kK27DrIowha03e1YR+Qw==", + "license": "BSD-3-Clause", "dependencies": { "array-source": "0.0", "file-source": "0.6" @@ -7485,22 +6849,19 @@ }, "node_modules/path-to-regexp": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.2.0.tgz", - "integrity": "sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==" + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pbf": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "license": "BSD-3-Clause", "dependencies": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" @@ -7511,15 +6872,13 @@ }, "node_modules/picocolors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -7529,18 +6888,16 @@ }, "node_modules/pirates": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -7550,9 +6907,8 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -7563,9 +6919,8 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -7575,9 +6930,8 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -7590,9 +6944,8 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -7602,27 +6955,24 @@ }, "node_modules/pluralize": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -7635,9 +6985,8 @@ }, "node_modules/prettier-linter-helpers": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, + "license": "MIT", "dependencies": { "fast-diff": "^1.1.2" }, @@ -7647,9 +6996,8 @@ }, "node_modules/pretty-format": { "version": "29.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", - "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.0", "ansi-styles": "^5.0.0", @@ -7661,9 +7009,8 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -7673,10 +7020,9 @@ }, "node_modules/prisma": { "version": "4.16.2", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.16.2.tgz", - "integrity": "sha512-SYCsBvDf0/7XSJyf2cHTLjLeTLVXYfqp7pG5eEVafFLeT0u/hLFz/9W196nDRGUOo1JfPatAEb+uEnTQImQC1g==", "devOptional": true, "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@prisma/engines": "4.16.2" }, @@ -7690,19 +7036,16 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "license": "MIT" }, "node_modules/promise-breaker": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz", - "integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA==" + "license": "MIT" }, "node_modules/prompts": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -7713,9 +7056,8 @@ }, "node_modules/protobufjs": { "version": "7.2.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", - "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -7736,18 +7078,15 @@ }, "node_modules/protobufjs/node_modules/long": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "license": "Apache-2.0" }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", - "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + "license": "MIT" }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -7758,13 +7097,11 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "license": "MIT" }, "node_modules/pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -7772,17 +7109,14 @@ }, "node_modules/punycode": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pure-rand": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", - "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", "dev": true, "funding": [ { @@ -7793,12 +7127,12 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/qs": { "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -7811,334 +7145,10 @@ }, "node_modules/querystringify": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/redis-errors": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/redis-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "dependencies": { - "redis-errors": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-protobuf-schema": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", - "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", - "dependencies": { - "protocol-buffers-schema": "^3.3.1" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "dev": true, - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -8154,33 +7164,320 @@ "url": "https://feross.org/support" } ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "license": "Apache-2.0" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.4", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "4.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/rxjs": { "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "license": "MIT" }, "node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -8196,9 +7493,8 @@ }, "node_modules/schema-utils/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -8212,24 +7508,21 @@ }, "node_modules/schema-utils/node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/schema-utils/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -8242,9 +7535,8 @@ }, "node_modules/semver/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -8254,14 +7546,12 @@ }, "node_modules/semver/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/send": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -8283,35 +7573,30 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "license": "MIT" }, "node_modules/serialize-javascript": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-static": { "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -8324,13 +7609,11 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "license": "ISC" }, "node_modules/shapefile": { "version": "0.6.6", - "resolved": "https://registry.npmjs.org/shapefile/-/shapefile-0.6.6.tgz", - "integrity": "sha512-rLGSWeK2ufzCVx05wYd+xrWnOOdSV7xNUW5/XFgx3Bc02hBkpMlrd2F1dDII7/jhWzv0MSyBFh5uJIy9hLdfuw==", + "license": "BSD-3-Clause", "dependencies": { "array-source": "0.0", "commander": "2", @@ -8346,14 +7629,12 @@ }, "node_modules/shapefile/node_modules/commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -8363,18 +7644,16 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shelljs": { "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "glob": "^7.0.0", "interpret": "^1.0.0", @@ -8389,8 +7668,7 @@ }, "node_modules/side-channel": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -8402,44 +7680,38 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/sisteransi": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/slice-source": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/slice-source/-/slice-source-0.4.1.tgz", - "integrity": "sha512-YiuPbxpCj4hD9Qs06hGAz/OZhQ0eDuALN0lRWJez0eD/RevzKqGdUx1IOMUnXgpr+sXZLq3g8ERwbAH0bCb8vg==" + "license": "BSD-3-Clause" }, "node_modules/source-map": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, "node_modules/source-map-support": { "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -8447,24 +7719,21 @@ }, "node_modules/source-map-support/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stack-utils": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -8474,49 +7743,41 @@ }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/standard-as-callback": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/stream-source": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/stream-source/-/stream-source-0.3.5.tgz", - "integrity": "sha512-ZuEDP9sgjiAwUVoDModftG0JtYiLUV8K4ljYD1VyUMRWtbVf92474o4kuuul43iZ8t/hRuiDAx1dIJSvirrK/g==" + "license": "BSD-3-Clause" }, "node_modules/streamsearch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "engines": { "node": ">=10.0.0" } }, "node_modules/string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "license": "MIT" }, "node_modules/string-length": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -8527,8 +7788,7 @@ }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8540,8 +7800,7 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -8551,27 +7810,24 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -8581,9 +7837,8 @@ }, "node_modules/superagent": { "version": "8.1.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz", - "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", "dev": true, + "license": "MIT", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", @@ -8602,9 +7857,8 @@ }, "node_modules/superagent/node_modules/mime": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -8614,9 +7868,8 @@ }, "node_modules/supertest": { "version": "6.3.3", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz", - "integrity": "sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==", "dev": true, + "license": "MIT", "dependencies": { "methods": "^1.1.2", "superagent": "^8.0.5" @@ -8627,8 +7880,7 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -8638,9 +7890,8 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8650,27 +7901,24 @@ }, "node_modules/symbol-observable": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/tapable": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/terser": { "version": "5.19.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", - "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -8686,9 +7934,8 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", @@ -8720,9 +7967,8 @@ }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -8734,9 +7980,8 @@ }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -8749,15 +7994,13 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -8769,35 +8012,29 @@ }, "node_modules/text-encoding": { "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha512-hJnc6Qg3dWoOMkqP53F0dzRIgtmsAge09kxUIqGrEUS4qr5rWLckGYaQAVr+opBrIMRErGgy6f5aPnyPpyGRfg==", - "deprecated": "no longer maintained" + "license": "Unlicense" }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/timezonecomplete": { "version": "5.12.4", - "resolved": "https://registry.npmjs.org/timezonecomplete/-/timezonecomplete-5.12.4.tgz", - "integrity": "sha512-K+ocagBAl5wu9Ifh5oHKhRRLb0wP7j0VjAzjboZsT6bnVmtJNRe3Wnk2IPp0C4Uc8HpLly3gbfUrTlJ3M7vCPA==", + "license": "MIT", "dependencies": { "tzdata": "^1.0.25" } }, "node_modules/tmp": { "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, + "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -8807,24 +8044,21 @@ }, "node_modules/tmpl": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -8834,31 +8068,27 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "license": "MIT" }, "node_modules/tree-kill": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, + "license": "MIT", "bin": { "tree-kill": "cli.js" } }, "node_modules/ts-jest": { "version": "29.0.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", - "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==", "dev": true, + "license": "MIT", "dependencies": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", @@ -8899,9 +8129,8 @@ }, "node_modules/ts-loader": { "version": "9.4.4", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", - "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -8918,9 +8147,8 @@ }, "node_modules/ts-node": { "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -8961,9 +8189,8 @@ }, "node_modules/tsconfig-paths": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, + "license": "MIT", "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -8975,9 +8202,8 @@ }, "node_modules/tsconfig-paths-webpack-plugin": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.1.tgz", - "integrity": "sha512-m5//KzLoKmqu2MVix+dgLKq70MnFi8YL8sdzQZ6DblmCdfuq/y3OqvJd5vMndg2KEVCOeNz8Es4WVZhYInteLw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.7.0", @@ -8989,23 +8215,20 @@ }, "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/tslib": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -9018,15 +8241,13 @@ }, "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -9036,17 +8257,15 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -9056,8 +8275,7 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -9068,14 +8286,12 @@ }, "node_modules/typedarray": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + "license": "MIT" }, "node_modules/typescript": { "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9086,13 +8302,11 @@ }, "node_modules/tzdata": { "version": "1.0.38", - "resolved": "https://registry.npmjs.org/tzdata/-/tzdata-1.0.38.tgz", - "integrity": "sha512-KIgVvZTLt+DWzr3MOENNLCLdsNB+usedRYYHCVfVbA7TDewj8mfjlWmj3Mv6FfdrvfeE6Oprt+qE47YiL90duQ==" + "license": "MIT" }, "node_modules/uid": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", - "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", + "license": "MIT", "dependencies": { "@lukeed/csprng": "^1.0.0" }, @@ -9102,25 +8316,21 @@ }, "node_modules/universalify": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "funding": [ { @@ -9136,6 +8346,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -9149,17 +8360,15 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/url-parse": { "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -9167,36 +8376,31 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -9208,40 +8412,35 @@ }, "node_modules/v8-to-istanbul/node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/validator": { "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/walker": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } }, "node_modules/watchpack": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -9252,23 +8451,20 @@ }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "license": "BSD-2-Clause" }, "node_modules/webpack": { "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -9314,26 +8510,23 @@ }, "node_modules/webpack-node-externals": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", - "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/webpack-sources": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -9341,9 +8534,8 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -9356,8 +8548,7 @@ }, "node_modules/widest-line": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "license": "MIT", "dependencies": { "string-width": "^4.0.0" }, @@ -9367,9 +8558,8 @@ }, "node_modules/windows-release": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", - "integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^4.0.2" }, @@ -9382,9 +8572,8 @@ }, "node_modules/windows-release/node_modules/execa": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -9405,17 +8594,15 @@ }, "node_modules/windows-release/node_modules/human-signals": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=8.12.0" } }, "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9430,14 +8617,12 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -9448,39 +8633,34 @@ }, "node_modules/xtend": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", "engines": { "node": ">=0.4" } }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 6" } }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9496,26 +8676,23 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/yn": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 64b005d..ed61f84 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@grpc/proto-loader": "^0.7.6", "@liaoliaots/nestjs-redis": "^9.0.5", "@mobicoop/configuration-module": "^1.2.0", - "@mobicoop/ddd-library": "^1.0.0", + "@mobicoop/ddd-library": "^1.1.0", "@mobicoop/health-module": "^2.0.0", "@mobicoop/message-broker-module": "^1.2.0", "@nestjs/axios": "^2.0.0", diff --git a/prisma/migrations/20230823125530_init/migration.sql b/prisma/migrations/20230823125530_init/migration.sql new file mode 100644 index 0000000..063fe20 --- /dev/null +++ b/prisma/migrations/20230823125530_init/migration.sql @@ -0,0 +1,68 @@ +-- CreateExtension +CREATE EXTENSION IF NOT EXISTS "postgis"; + +-- Required to use postgis extension : +-- set the search_path to both public (where is postgis) AND the current schema +SET search_path TO matcher, public; + +-- CreateEnum +CREATE TYPE "Frequency" AS ENUM ('PUNCTUAL', 'RECURRENT'); + +-- CreateTable +CREATE TABLE "ad" ( + "uuid" UUID NOT NULL, + "driver" BOOLEAN NOT NULL, + "passenger" BOOLEAN NOT NULL, + "frequency" "Frequency" NOT NULL, + "fromDate" DATE NOT NULL, + "toDate" DATE NOT NULL, + "seatsProposed" SMALLINT NOT NULL, + "seatsRequested" SMALLINT NOT NULL, + "strict" BOOLEAN NOT NULL, + "driverDuration" INTEGER, + "driverDistance" INTEGER, + "passengerDuration" INTEGER, + "passengerDistance" INTEGER, + "waypoints" geography(LINESTRING), + "direction" geography(LINESTRING), + "fwdAzimuth" INTEGER NOT NULL, + "backAzimuth" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "ad_pkey" PRIMARY KEY ("uuid") +); + +-- CreateTable +CREATE TABLE "schedule_item" ( + "uuid" UUID NOT NULL, + "adUuid" UUID NOT NULL, + "day" INTEGER NOT NULL, + "time" TIME(4) NOT NULL, + "margin" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "schedule_item_pkey" PRIMARY KEY ("uuid") +); + +-- CreateIndex +CREATE INDEX "ad_driver_idx" ON "ad"("driver"); + +-- CreateIndex +CREATE INDEX "ad_passenger_idx" ON "ad"("passenger"); + +-- CreateIndex +CREATE INDEX "ad_fromDate_idx" ON "ad"("fromDate"); + +-- CreateIndex +CREATE INDEX "ad_toDate_idx" ON "ad"("toDate"); + +-- CreateIndex +CREATE INDEX "ad_fwdAzimuth_idx" ON "ad"("fwdAzimuth"); + +-- CreateIndex +CREATE INDEX "direction_idx" ON "ad" USING GIST ("direction"); + +-- AddForeignKey +ALTER TABLE "schedule_item" ADD CONSTRAINT "schedule_item_adUuid_fkey" FOREIGN KEY ("adUuid") REFERENCES "ad"("uuid") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..fbffa92 --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 17ea1a0..9c5060c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -23,7 +23,6 @@ model Ad { schedule ScheduleItem[] seatsProposed Int @db.SmallInt seatsRequested Int @db.SmallInt - seatsUsed Int @db.SmallInt strict Boolean driverDuration Int? driverDistance Int? diff --git a/src/modules/ad/ad.mapper.ts b/src/modules/ad/ad.mapper.ts index bb5d25c..81a94c1 100644 --- a/src/modules/ad/ad.mapper.ts +++ b/src/modules/ad/ad.mapper.ts @@ -1,16 +1,17 @@ -import { Mapper } from '@mobicoop/ddd-library'; import { Inject, Injectable } from '@nestjs/common'; import { AdEntity } from './core/domain/ad.entity'; import { AdWriteModel, AdReadModel, ScheduleItemModel, + AdUnsupportedWriteModel, } from './infrastructure/ad.repository'; import { Frequency } from './core/domain/ad.types'; import { v4 } from 'uuid'; import { ScheduleItemProps } from './core/domain/value-objects/schedule-item.value-object'; import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; import { AD_DIRECTION_ENCODER } from './ad.di-tokens'; +import { ExtendedMapper } from '@mobicoop/ddd-library'; /** * Mapper constructs objects that are used in different layers: @@ -21,7 +22,14 @@ import { AD_DIRECTION_ENCODER } from './ad.di-tokens'; @Injectable() export class AdMapper - implements Mapper + implements + ExtendedMapper< + AdEntity, + AdReadModel, + AdWriteModel, + AdUnsupportedWriteModel, + undefined + > { constructor( @Inject(AD_DIRECTION_ENCODER) @@ -61,8 +69,6 @@ export class AdMapper driverDistance: copy.driverDistance, passengerDuration: copy.passengerDuration, passengerDistance: copy.passengerDistance, - waypoints: this.directionEncoder.encode(copy.waypoints), - direction: this.directionEncoder.encode(copy.points), fwdAzimuth: copy.fwdAzimuth, backAzimuth: copy.backAzimuth, createdAt: copy.createdAt, @@ -118,4 +124,9 @@ export class AdMapper toResponse = (entity: AdEntity): undefined => { return undefined; }; + + toUnsupportedPersistence = (entity: AdEntity): AdUnsupportedWriteModel => ({ + waypoints: this.directionEncoder.encode(entity.getProps().waypoints), + direction: this.directionEncoder.encode(entity.getProps().points), + }); } diff --git a/src/modules/ad/ad.module.ts b/src/modules/ad/ad.module.ts index 3bfdd2e..53788ec 100644 --- a/src/modules/ad/ad.module.ts +++ b/src/modules/ad/ad.module.ts @@ -16,9 +16,12 @@ import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/post import { GetBasicRouteController } from '@modules/geography/interface/controllers/get-basic-route.controller'; import { RouteProvider } from './infrastructure/route-provider'; import { GeographyModule } from '@modules/geography/geography.module'; +import { CreateAdService } from './core/application/commands/create-ad/create-ad.service'; const messageHandlers = [AdCreatedMessageHandler]; +const commandHandlers: Provider[] = [CreateAdService]; + const mappers: Provider[] = [AdMapper]; const repositories: Provider[] = [ @@ -56,6 +59,7 @@ const adapters: Provider[] = [ imports: [CqrsModule, GeographyModule], providers: [ ...messageHandlers, + ...commandHandlers, ...mappers, ...repositories, ...messagePublishers, diff --git a/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts b/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts index 47d367f..2ec8f5a 100644 --- a/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts +++ b/src/modules/ad/core/application/commands/create-ad/create-ad.service.ts @@ -49,7 +49,7 @@ export class CreateAdService implements ICommandHandler { }); try { - await this.repository.insert(ad); + await this.repository.insertWithUnsupportedFields(ad, 'ad'); return ad.id; } catch (error: any) { if (error instanceof ConflictException) { diff --git a/src/modules/ad/core/application/ports/ad.repository.port.ts b/src/modules/ad/core/application/ports/ad.repository.port.ts index 5b9fe49..91b5294 100644 --- a/src/modules/ad/core/application/ports/ad.repository.port.ts +++ b/src/modules/ad/core/application/ports/ad.repository.port.ts @@ -1,4 +1,4 @@ -import { RepositoryPort } from '@mobicoop/ddd-library'; +import { ExtendedRepositoryPort } from '@mobicoop/ddd-library'; import { AdEntity } from '../../domain/ad.entity'; -export type AdRepositoryPort = RepositoryPort; +export type AdRepositoryPort = ExtendedRepositoryPort; diff --git a/src/modules/ad/infrastructure/ad.repository.ts b/src/modules/ad/infrastructure/ad.repository.ts index afa5d7e..ae07fd7 100644 --- a/src/modules/ad/infrastructure/ad.repository.ts +++ b/src/modules/ad/infrastructure/ad.repository.ts @@ -1,15 +1,12 @@ import { Inject, Injectable, Logger } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { AdRepositoryPort } from '../core/application/ports/ad.repository.port'; -import { - LoggerBase, - MessagePublisherPort, - PrismaRepositoryBase, -} from '@mobicoop/ddd-library'; +import { LoggerBase, MessagePublisherPort } from '@mobicoop/ddd-library'; import { PrismaService } from './prisma.service'; import { AD_MESSAGE_PUBLISHER } from '../ad.di-tokens'; import { AdEntity } from '../core/domain/ad.entity'; import { AdMapper } from '../ad.mapper'; +import { ExtendedPrismaRepositoryBase } from '@mobicoop/ddd-library/dist/db/prisma-repository.base'; export type AdBaseModel = { uuid: string; @@ -25,8 +22,6 @@ export type AdBaseModel = { driverDistance: number; passengerDuration: number; passengerDistance: number; - waypoints: string; - direction: string; fwdAzimuth: number; backAzimuth: number; createdAt: Date; @@ -34,6 +29,8 @@ export type AdBaseModel = { }; export type AdReadModel = AdBaseModel & { + waypoints: string; + direction: string; schedule: ScheduleItemModel[]; }; @@ -43,6 +40,11 @@ export type AdWriteModel = AdBaseModel & { }; }; +export type AdUnsupportedWriteModel = { + waypoints: string; + direction: string; +}; + export type ScheduleItemModel = { uuid: string; day: number; @@ -57,7 +59,12 @@ export type ScheduleItemModel = { * */ @Injectable() export class AdRepository - extends PrismaRepositoryBase + extends ExtendedPrismaRepositoryBase< + AdEntity, + AdReadModel, + AdWriteModel, + AdUnsupportedWriteModel + > implements AdRepositoryPort { constructor( diff --git a/src/modules/ad/interface/message-handlers/ad-created.message-handler.ts b/src/modules/ad/interface/message-handlers/ad-created.message-handler.ts index ed5dc61..621c6a1 100644 --- a/src/modules/ad/interface/message-handlers/ad-created.message-handler.ts +++ b/src/modules/ad/interface/message-handlers/ad-created.message-handler.ts @@ -12,8 +12,8 @@ export class AdCreatedMessageHandler { name: 'adCreated', }) public async adCreated(message: string) { - const createdAd: Ad = JSON.parse(message); try { + const createdAd: Ad = JSON.parse(message); await this.commandBus.execute( new CreateAdCommand({ id: createdAd.id, diff --git a/src/modules/ad/tests/unit/ad.mapper.spec.ts b/src/modules/ad/tests/unit/ad.mapper.spec.ts index 0099653..ae0bb6d 100644 --- a/src/modules/ad/tests/unit/ad.mapper.spec.ts +++ b/src/modules/ad/tests/unit/ad.mapper.spec.ts @@ -4,6 +4,7 @@ import { AdEntity } from '@modules/ad/core/domain/ad.entity'; import { Frequency } from '@modules/ad/core/domain/ad.types'; import { AdReadModel, + AdUnsupportedWriteModel, AdWriteModel, } from '@modules/ad/infrastructure/ad.repository'; import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port'; @@ -143,14 +144,19 @@ describe('Ad Mapper', () => { it('should map domain entity to persistence data', async () => { const mapped: AdWriteModel = adMapper.toPersistence(adEntity); expect(mapped.schedule.create.length).toBe(1); + expect(mapped.driverDuration).toBe(14422); + expect(mapped.fwdAzimuth).toBe(273); + }); + + it('should map domain entity to unsupported db persistence data', async () => { + const mapped: AdUnsupportedWriteModel = + adMapper.toUnsupportedPersistence(adEntity); expect(mapped.waypoints).toBe( "'LINESTRING(6.1765102 48.689445,2.3522 48.8566)'", ); expect(mapped.direction).toBe( "'LINESTRING(6.1765102 48.689445,4.984578 48.725687,2.3522 48.8566)'", ); - expect(mapped.driverDuration).toBe(14422); - expect(mapped.fwdAzimuth).toBe(273); }); it('should map persisted data to domain entity', async () => { diff --git a/src/modules/ad/tests/unit/core/ad.entity.spec.ts b/src/modules/ad/tests/unit/core/ad.entity.spec.ts index 90077ac..8b04836 100644 --- a/src/modules/ad/tests/unit/core/ad.entity.spec.ts +++ b/src/modules/ad/tests/unit/core/ad.entity.spec.ts @@ -4,13 +4,13 @@ import { WaypointProps } from '@modules/ad/core/domain/value-objects/waypoint.va const originWaypointProps: WaypointProps = { position: 0, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }; const destinationWaypointProps: WaypointProps = { position: 1, - lon: 48.8566, - lat: 2.3522, + lat: 48.8566, + lon: 2.3522, }; const createAdProps: CreateAdProps = { diff --git a/src/modules/ad/tests/unit/core/create-ad.service.spec.ts b/src/modules/ad/tests/unit/core/create-ad.service.spec.ts index d78729c..29f7e2c 100644 --- a/src/modules/ad/tests/unit/core/create-ad.service.spec.ts +++ b/src/modules/ad/tests/unit/core/create-ad.service.spec.ts @@ -12,13 +12,13 @@ import { RouteProviderPort } from '@modules/ad/core/application/ports/route-prov const originWaypoint: WaypointProps = { position: 0, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }; const destinationWaypoint: WaypointProps = { position: 1, - lon: 48.8566, - lat: 2.3522, + lat: 48.8566, + lon: 2.3522, }; const createAdProps: CreateAdProps = { id: '4eb6a6af-ecfd-41c3-9118-473a507014d4', @@ -48,7 +48,7 @@ const createAdProps: CreateAdProps = { }; const mockAdRepository = { - insert: jest + insertWithUnsupportedFields: jest .fn() .mockImplementationOnce(() => ({})) .mockImplementationOnce(() => { diff --git a/src/modules/ad/tests/unit/core/point.value-object.spec.ts b/src/modules/ad/tests/unit/core/point.value-object.spec.ts index eb09cd8..b6980e2 100644 --- a/src/modules/ad/tests/unit/core/point.value-object.spec.ts +++ b/src/modules/ad/tests/unit/core/point.value-object.spec.ts @@ -4,25 +4,25 @@ import { Point } from '@modules/ad/core/domain/value-objects/point.value-object' describe('Point value object', () => { it('should create a point value object', () => { const pointVO = new Point({ - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }); - expect(pointVO.lon).toBe(48.689445); - expect(pointVO.lat).toBe(6.17651); + expect(pointVO.lat).toBe(48.689445); + expect(pointVO.lon).toBe(6.17651); }); it('should throw an exception if longitude is invalid', () => { try { new Point({ - lon: 348.689445, - lat: 6.17651, + lat: 48.689445, + lon: 186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); } try { new Point({ - lon: -348.689445, - lat: 6.17651, + lat: 48.689445, + lon: -186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -31,16 +31,16 @@ describe('Point value object', () => { it('should throw an exception if latitude is invalid', () => { try { new Point({ - lon: 48.689445, - lat: 96.17651, + lat: 148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); } try { new Point({ - lon: 48.689445, - lat: -96.17651, + lat: -148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); diff --git a/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts index 4191313..da67658 100644 --- a/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts +++ b/src/modules/ad/tests/unit/core/waypoint.value-object.spec.ts @@ -8,19 +8,19 @@ describe('Waypoint value object', () => { it('should create a waypoint value object', () => { const waypointVO = new Waypoint({ position: 0, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }); expect(waypointVO.position).toBe(0); - expect(waypointVO.lon).toBe(48.689445); - expect(waypointVO.lat).toBe(6.17651); + expect(waypointVO.lat).toBe(48.689445); + expect(waypointVO.lon).toBe(6.17651); }); it('should throw an exception if position is invalid', () => { try { new Waypoint({ position: -1, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentInvalidException); @@ -30,8 +30,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: 348.689445, - lat: 6.17651, + lat: 48.689445, + lon: 186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -39,8 +39,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: -348.689445, - lat: 6.17651, + lat: 48.689445, + lon: -186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -50,8 +50,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: 48.689445, - lat: 96.17651, + lat: 148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -59,8 +59,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: 48.689445, - lat: -96.17651, + lat: -148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); diff --git a/src/modules/geography/geography.module.ts b/src/modules/geography/geography.module.ts index 992869f..6c04e79 100644 --- a/src/modules/geography/geography.module.ts +++ b/src/modules/geography/geography.module.ts @@ -13,6 +13,9 @@ import { RouteMapper } from './route.mapper'; import { Geodesic } from './infrastructure/geodesic'; import { GraphhopperGeorouter } from './infrastructure/graphhopper-georouter'; import { HttpModule } from '@nestjs/axios'; +import { GetRouteQueryHandler } from './core/application/queries/get-route/get-route.query-handler'; + +const queryHandlers: Provider[] = [GetRouteQueryHandler]; const mappers: Provider[] = [RouteMapper]; @@ -38,7 +41,7 @@ const adapters: Provider[] = [ @Module({ imports: [CqrsModule, HttpModule], - providers: [...mappers, ...adapters], + providers: [...queryHandlers, ...mappers, ...adapters], exports: [RouteMapper, DIRECTION_ENCODER, GetBasicRouteController], }) export class GeographyModule {} diff --git a/src/modules/geography/route.mapper.ts b/src/modules/geography/route.mapper.ts index 98fc10c..4f5d63c 100644 --- a/src/modules/geography/route.mapper.ts +++ b/src/modules/geography/route.mapper.ts @@ -26,13 +26,17 @@ export class RouteMapper // eslint-disable-next-line @typescript-eslint/no-unused-vars toResponse = (entity: RouteEntity): RouteResponseDto => { const response = new RouteResponseDto(); - response.driverDistance = entity.getProps().driverDistance; - response.driverDuration = entity.getProps().driverDuration; - response.passengerDistance = entity.getProps().passengerDistance; - response.passengerDuration = entity.getProps().passengerDuration; - response.fwdAzimuth = entity.getProps().fwdAzimuth; - response.backAzimuth = entity.getProps().backAzimuth; - response.distanceAzimuth = entity.getProps().distanceAzimuth; + response.driverDistance = Math.round(entity.getProps().driverDistance); + response.driverDuration = Math.round(entity.getProps().driverDuration); + response.passengerDistance = Math.round( + entity.getProps().passengerDistance, + ); + response.passengerDuration = Math.round( + entity.getProps().passengerDuration, + ); + response.fwdAzimuth = Math.round(entity.getProps().fwdAzimuth); + response.backAzimuth = Math.round(entity.getProps().backAzimuth); + response.distanceAzimuth = Math.round(entity.getProps().distanceAzimuth); response.points = entity.getProps().points; return response; }; diff --git a/src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts b/src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts index da2cf7e..4c7b1f7 100644 --- a/src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts +++ b/src/modules/geography/tests/unit/core/coordinates.value-object.spec.ts @@ -4,25 +4,25 @@ import { Coordinates } from '@modules/geography/core/domain/value-objects/coordi describe('Waypoint value object', () => { it('should create a waypoint value object', () => { const coordinatesVO = new Coordinates({ - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }); - expect(coordinatesVO.lon).toBe(48.689445); - expect(coordinatesVO.lat).toBe(6.17651); + expect(coordinatesVO.lat).toBe(48.689445); + expect(coordinatesVO.lon).toBe(6.17651); }); it('should throw an exception if longitude is invalid', () => { try { new Coordinates({ - lon: 348.689445, - lat: 6.17651, + lat: 48.689445, + lon: 186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); } try { new Coordinates({ - lon: -348.689445, - lat: 6.17651, + lat: 48.689445, + lon: -186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -31,16 +31,16 @@ describe('Waypoint value object', () => { it('should throw an exception if latitude is invalid', () => { try { new Coordinates({ - lon: 48.689445, - lat: 96.17651, + lat: 148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); } try { new Coordinates({ - lon: 48.689445, - lat: -96.17651, + lat: -148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); diff --git a/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts b/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts index d8df206..948ed0e 100644 --- a/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts +++ b/src/modules/geography/tests/unit/core/get-route.query-handler.spec.ts @@ -8,13 +8,13 @@ import { Test, TestingModule } from '@nestjs/testing'; const originWaypoint: Waypoint = { position: 0, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }; const destinationWaypoint: Waypoint = { position: 1, - lon: 48.8566, - lat: 2.3522, + lat: 48.8566, + lon: 2.3522, }; const mockGeorouter: GeorouterPort = { diff --git a/src/modules/geography/tests/unit/core/route.entity.spec.ts b/src/modules/geography/tests/unit/core/route.entity.spec.ts index edbe7a9..7cf810a 100644 --- a/src/modules/geography/tests/unit/core/route.entity.spec.ts +++ b/src/modules/geography/tests/unit/core/route.entity.spec.ts @@ -9,12 +9,12 @@ import { } from '@modules/geography/core/domain/route.types'; const originCoordinates: Coordinates = { - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }; const destinationCoordinates: Coordinates = { - lon: 48.8566, - lat: 2.3522, + lat: 48.8566, + lon: 2.3522, }; const additionalCoordinates: Coordinates = { lon: 48.7566, diff --git a/src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts b/src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts index bf18bd5..405190c 100644 --- a/src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts +++ b/src/modules/geography/tests/unit/core/spacetime-point.value-object.spec.ts @@ -7,21 +7,21 @@ import { SpacetimePoint } from '@modules/geography/core/domain/value-objects/spa describe('Timepoint value object', () => { it('should create a timepoint value object', () => { const timepointVO = new SpacetimePoint({ - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, duration: 150, distance: 12000, }); expect(timepointVO.duration).toBe(150); expect(timepointVO.distance).toBe(12000); - expect(timepointVO.lon).toBe(48.689445); - expect(timepointVO.lat).toBe(6.17651); + expect(timepointVO.lat).toBe(48.689445); + expect(timepointVO.lon).toBe(6.17651); }); it('should throw an exception if longitude is invalid', () => { try { new SpacetimePoint({ - lon: 348.689445, - lat: 6.17651, + lat: 48.689445, + lon: 186.17651, duration: 150, distance: 12000, }); @@ -30,8 +30,8 @@ describe('Timepoint value object', () => { } try { new SpacetimePoint({ - lon: -348.689445, - lat: 6.17651, + lon: 48.689445, + lat: -186.17651, duration: 150, distance: 12000, }); @@ -42,8 +42,8 @@ describe('Timepoint value object', () => { it('should throw an exception if latitude is invalid', () => { try { new SpacetimePoint({ - lon: 48.689445, - lat: 96.17651, + lat: 248.689445, + lon: 6.17651, duration: 150, distance: 12000, }); @@ -52,8 +52,8 @@ describe('Timepoint value object', () => { } try { new SpacetimePoint({ - lon: 48.689445, - lat: -96.17651, + lon: -148.689445, + lat: 6.17651, duration: 150, distance: 12000, }); @@ -64,8 +64,8 @@ describe('Timepoint value object', () => { it('should throw an exception if distance is invalid', () => { try { new SpacetimePoint({ - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, duration: 150, distance: -12000, }); @@ -76,8 +76,8 @@ describe('Timepoint value object', () => { it('should throw an exception if duration is invalid', () => { try { new SpacetimePoint({ - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, duration: -150, distance: 12000, }); diff --git a/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts b/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts index 8c44dd5..3723338 100644 --- a/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts +++ b/src/modules/geography/tests/unit/core/waypoint.value-object.spec.ts @@ -8,19 +8,19 @@ describe('Waypoint value object', () => { it('should create a waypoint value object', () => { const waypointVO = new Waypoint({ position: 0, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }); expect(waypointVO.position).toBe(0); - expect(waypointVO.lon).toBe(48.689445); - expect(waypointVO.lat).toBe(6.17651); + expect(waypointVO.lat).toBe(48.689445); + expect(waypointVO.lon).toBe(6.17651); }); it('should throw an exception if position is invalid', () => { try { new Waypoint({ position: -1, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentInvalidException); @@ -30,8 +30,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: 348.689445, - lat: 6.17651, + lat: 48.689445, + lon: 186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -39,8 +39,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: -348.689445, - lat: 6.17651, + lat: 48.689445, + lon: -186.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -50,8 +50,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: 48.689445, - lat: 96.17651, + lat: 148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); @@ -59,8 +59,8 @@ describe('Waypoint value object', () => { try { new Waypoint({ position: 0, - lon: 48.689445, - lat: -96.17651, + lat: -148.689445, + lon: 6.17651, }); } catch (e: any) { expect(e).toBeInstanceOf(ArgumentOutOfRangeException); diff --git a/src/modules/geography/tests/unit/interface/get-basic-route.controller.spec.ts b/src/modules/geography/tests/unit/interface/get-basic-route.controller.spec.ts index 2aeaf75..7e2de20 100644 --- a/src/modules/geography/tests/unit/interface/get-basic-route.controller.spec.ts +++ b/src/modules/geography/tests/unit/interface/get-basic-route.controller.spec.ts @@ -52,13 +52,13 @@ describe('Get Basic Route Controller', () => { waypoints: [ { position: 0, - lon: 48.689445, - lat: 6.17651, + lat: 48.689445, + lon: 6.17651, }, { position: 1, - lon: 48.8566, - lat: 2.3522, + lat: 48.8566, + lon: 2.3522, }, ], }); From f79f5bc2a02e885fc4b8dfed6e0e52a5ab2cf670 Mon Sep 17 00:00:00 2001 From: sbriat Date: Thu, 24 Aug 2023 15:09:12 +0200 Subject: [PATCH 22/24] add integration tests --check --- ci/.env.ci | 30 +-- .../tests/integration/ad.repository.spec.ts | 222 ++++++++++++++++++ 2 files changed, 234 insertions(+), 18 deletions(-) create mode 100644 src/modules/ad/tests/integration/ad.repository.spec.ts diff --git a/ci/.env.ci b/ci/.env.ci index fce2397..c216f49 100644 --- a/ci/.env.ci +++ b/ci/.env.ci @@ -2,12 +2,22 @@ SERVICE_URL=0.0.0.0 SERVICE_PORT=5005 +# PRISMA +DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=public" + +# MESSAGE BROKER +MESSAGE_BROKER_URI=amqp://v3-broker:5672 +MESSAGE_BROKER_EXCHANGE=mobicoop + +# REDIS +REDIS_HOST=v3-redis +REDIS_PASSWORD=redis +REDIS_PORT=6379 + # DEFAULT CONFIGURATION # default identifier used for match requests DEFAULT_UUID=00000000-0000-0000-0000-000000000000 -# default timezone -DEFAULT_TIMEZONE=Europe/Paris # default number of seats proposed as driver DEFAULT_SEATS=3 # algorithm type @@ -41,20 +51,4 @@ GEOROUTER_TYPE=graphhopper GEOROUTER_URL=http://localhost:8989 -# PRISMA -DATABASE_URL="postgresql://mobicoop:mobicoop@v3-db:5432/mobicoop?schema=public" -# MESSAGE BROKER -MESSAGE_BROKER_URI=amqp://v3-broker:5672 -MESSAGE_BROKER_EXCHANGE=mobicoop - -# REDIS -REDIS_IMAGE=redis:7.0-alpine -REDIS_HOST=v3-redis -REDIS_PASSWORD=redis - -# MESSAGE BROKER -BROKER_IMAGE=rabbitmq:3-alpine - -# POSTGRES -POSTGRES_IMAGE=postgis/postgis:15-3.3 diff --git a/src/modules/ad/tests/integration/ad.repository.spec.ts b/src/modules/ad/tests/integration/ad.repository.spec.ts new file mode 100644 index 0000000..c74557c --- /dev/null +++ b/src/modules/ad/tests/integration/ad.repository.spec.ts @@ -0,0 +1,222 @@ +import { + AD_DIRECTION_ENCODER, + AD_MESSAGE_PUBLISHER, + AD_REPOSITORY, +} from '@modules/ad/ad.di-tokens'; +import { AdMapper } from '@modules/ad/ad.mapper'; +import { AdEntity } from '@modules/ad/core/domain/ad.entity'; +import { CreateAdProps, Frequency } from '@modules/ad/core/domain/ad.types'; +import { AdRepository } from '@modules/ad/infrastructure/ad.repository'; +import { PrismaService } from '@modules/ad/infrastructure/prisma.service'; +import { PostgresDirectionEncoder } from '@modules/geography/infrastructure/postgres-direction-encoder'; +import { ConfigModule } from '@nestjs/config'; +import { EventEmitterModule } from '@nestjs/event-emitter'; +import { Test } from '@nestjs/testing'; + +describe('Ad Repository', () => { + let prismaService: PrismaService; + let adRepository: AdRepository; + + const mockMessagePublisher = { + publish: jest.fn().mockImplementation(), + }; + + const mockLogger = { + log: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }; + + beforeAll(async () => { + const module = await Test.createTestingModule({ + imports: [ + EventEmitterModule.forRoot(), + ConfigModule.forRoot({ isGlobal: true }), + ], + providers: [ + PrismaService, + AdMapper, + { + provide: AD_REPOSITORY, + useClass: AdRepository, + }, + { + provide: AD_MESSAGE_PUBLISHER, + useValue: mockMessagePublisher, + }, + { + provide: AD_DIRECTION_ENCODER, + useClass: PostgresDirectionEncoder, + }, + ], + }) + // disable logging + .setLogger(mockLogger) + .compile(); + + prismaService = module.get(PrismaService); + adRepository = module.get(AD_REPOSITORY); + }); + + afterAll(async () => { + await prismaService.$disconnect(); + }); + + beforeEach(async () => { + await prismaService.ad.deleteMany(); + }); + + describe('create', () => { + it('should create a punctual ad', async () => { + const beforeCount = await prismaService.ad.count(); + + const createAdProps: CreateAdProps = { + id: 'b4b56444-f8d3-4110-917c-e37bba77f383', + driver: true, + passenger: false, + frequency: Frequency.PUNCTUAL, + fromDate: '2023-02-01', + toDate: '2023-02-01', + schedule: [ + { + day: 3, + time: '12:05', + margin: 900, + }, + ], + seatsProposed: 3, + seatsRequested: 1, + strict: false, + waypoints: [ + { + position: 0, + lon: 43.7102, + lat: 7.262, + }, + { + position: 1, + lon: 43.2965, + lat: 5.3698, + }, + ], + points: [ + { + lon: 7.262, + lat: 43.7102, + }, + { + lon: 6.797838, + lat: 43.547031, + }, + { + lon: 6.18535, + lat: 43.407517, + }, + { + lon: 5.3698, + lat: 43.2965, + }, + ], + driverDuration: 7668, + driverDistance: 199000, + passengerDuration: 7668, + passengerDistance: 199000, + fwdAzimuth: 273, + backAzimuth: 93, + }; + + const adToCreate: AdEntity = AdEntity.create(createAdProps); + await adRepository.insertWithUnsupportedFields(adToCreate, 'ad'); + + const afterCount = await prismaService.ad.count(); + + expect(afterCount - beforeCount).toBe(1); + }); + + it('should create a recurrent ad', async () => { + const beforeCount = await prismaService.ad.count(); + + const createAdProps: CreateAdProps = { + id: 'b4b56444-f8d3-4110-917c-e37bba77f383', + driver: true, + passenger: false, + frequency: Frequency.RECURRENT, + fromDate: '2023-02-01', + toDate: '2024-01-31', + schedule: [ + { + day: 1, + time: '08:00', + margin: 900, + }, + { + day: 2, + time: '08:00', + margin: 900, + }, + { + day: 3, + time: '09:00', + margin: 900, + }, + { + day: 4, + time: '08:00', + margin: 900, + }, + { + day: 5, + time: '08:00', + margin: 900, + }, + ], + seatsProposed: 3, + seatsRequested: 1, + strict: false, + waypoints: [ + { + position: 0, + lon: 43.7102, + lat: 7.262, + }, + { + position: 1, + lon: 43.2965, + lat: 5.3698, + }, + ], + points: [ + { + lon: 7.262, + lat: 43.7102, + }, + { + lon: 6.797838, + lat: 43.547031, + }, + { + lon: 6.18535, + lat: 43.407517, + }, + { + lon: 5.3698, + lat: 43.2965, + }, + ], + driverDuration: 7668, + driverDistance: 199000, + passengerDuration: 7668, + passengerDistance: 199000, + fwdAzimuth: 273, + backAzimuth: 93, + }; + + const adToCreate: AdEntity = AdEntity.create(createAdProps); + await adRepository.insertWithUnsupportedFields(adToCreate, 'ad'); + + const afterCount = await prismaService.ad.count(); + + expect(afterCount - beforeCount).toBe(1); + }); + }); +}); From ae8d5a32600e7a097a6b48f7d7f37e1f19438be3 Mon Sep 17 00:00:00 2001 From: sbriat Date: Thu, 24 Aug 2023 15:12:58 +0200 Subject: [PATCH 23/24] add integration tests --check --- ci/.env.ci | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci/.env.ci b/ci/.env.ci index c216f49..c2f25f0 100644 --- a/ci/.env.ci +++ b/ci/.env.ci @@ -14,6 +14,11 @@ REDIS_HOST=v3-redis REDIS_PASSWORD=redis REDIS_PORT=6379 +# IMAGES +BROKER_IMAGE=rabbitmq:3-alpine +REDIS_IMAGE=redis:7.0-alpine +POSTGRES_IMAGE=postgres:15.0 + # DEFAULT CONFIGURATION # default identifier used for match requests From 10a8a75923cbc17383485f4de1edfeef3f3951ce Mon Sep 17 00:00:00 2001 From: sbriat Date: Thu, 24 Aug 2023 15:17:30 +0200 Subject: [PATCH 24/24] add integration tests --check --- ci/.env.ci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/.env.ci b/ci/.env.ci index c2f25f0..011adf5 100644 --- a/ci/.env.ci +++ b/ci/.env.ci @@ -17,7 +17,7 @@ REDIS_PORT=6379 # IMAGES BROKER_IMAGE=rabbitmq:3-alpine REDIS_IMAGE=redis:7.0-alpine -POSTGRES_IMAGE=postgres:15.0 +POSTGRES_IMAGE=postgis/postgis:15-3.3 # DEFAULT CONFIGURATION