diff --git a/projects/lnsp-mediator/package.json b/projects/lnsp-mediator/package.json index c24f051a..29d92eca 100644 --- a/projects/lnsp-mediator/package.json +++ b/projects/lnsp-mediator/package.json @@ -65,6 +65,7 @@ "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", + "mongodb-memory-server": "^11.0.1", "prettier": "^3.0.0", "source-map-support": "^0.5.21", "supertest": "^7.0.0", diff --git a/projects/lnsp-mediator/scripts/README.md b/projects/lnsp-mediator/scripts/README.md new file mode 100644 index 00000000..c9aebc1b --- /dev/null +++ b/projects/lnsp-mediator/scripts/README.md @@ -0,0 +1,35 @@ +# lnsp-mediator scripts + +Small operator scripts that talk to a running `lnsp-mediator` over its HTTP API. + +## Requirements + +- `curl` and `jq` on `$PATH` +- A reachable `lnsp-mediator` — by default `http://localhost:3000`, overridable via + a third positional arg or the `LNSP_MEDIATOR_URL` env var. + +## `set-subscription.sh` + +Repoint a subscription at a new target URL. Deletes the subscription whose +`targetAddress` matches `OLD_URL` (if any) and then creates one with `NEW_URL`. + +```sh +./set-subscription.sh [BASE_URL] +``` + +Examples: + +```sh +# Against a local dev mediator +./set-subscription.sh http://old.example/cb http://new.example/cb + +# Against a staging host +./set-subscription.sh http://old.example/cb http://new.example/cb https://staging.example + +# Using LNSP_MEDIATOR_URL +export LNSP_MEDIATOR_URL=https://staging.example +./set-subscription.sh http://old.example/cb http://new.example/cb +``` + +The script uses only the modern JSON CRUD endpoints (`GET /subscription`, +`DELETE /subscription/:id`, `POST /subscription`), not the legacy SOAP path. diff --git a/projects/lnsp-mediator/scripts/set-subscription.sh b/projects/lnsp-mediator/scripts/set-subscription.sh new file mode 100755 index 00000000..46478ca0 --- /dev/null +++ b/projects/lnsp-mediator/scripts/set-subscription.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# set-subscription.sh +# +# Repoint a subscription at a new target URL by deleting the existing +# subscription whose targetAddress == OLD_URL and creating a new one with NEW_URL. +# +# Usage: +# set-subscription.sh [BASE_URL] +# +# BASE_URL defaults to $LNSP_MEDIATOR_URL or http://localhost:3000 +# +# Requires: curl, jq + +set -euo pipefail + +OLD_URL="${1:-}" +NEW_URL="${2:-}" +BASE_URL="${3:-${LNSP_MEDIATOR_URL:-http://localhost:3000}}" + +if [[ -z "$OLD_URL" || -z "$NEW_URL" ]]; then + echo "Usage: $0 [BASE_URL]" >&2 + echo " BASE_URL defaults to \$LNSP_MEDIATOR_URL or http://localhost:3000" >&2 + exit 2 +fi + +command -v curl >/dev/null || { echo "curl is required" >&2; exit 127; } +command -v jq >/dev/null || { echo "jq is required" >&2; exit 127; } + +echo "Looking up subscription where targetAddress=${OLD_URL} at ${BASE_URL} ..." +OLD_ID=$(curl -fsS "${BASE_URL}/subscription" \ + | jq -r --arg url "$OLD_URL" '.[] | select(.targetAddress == $url) | ._id' \ + | head -n 1) + +if [[ -n "$OLD_ID" ]]; then + echo "Deleting subscription ${OLD_ID} (${OLD_URL}) ..." + curl -fsS -X DELETE "${BASE_URL}/subscription/${OLD_ID}" >/dev/null +else + echo "No existing subscription for ${OLD_URL} -- skipping delete." +fi + +echo "Creating subscription for ${NEW_URL} ..." +curl -fsS -X POST "${BASE_URL}/subscription" \ + -H 'Content-Type: application/json' \ + -d "{\"targetAddress\":\"${NEW_URL}\"}" \ + | jq . + +echo "Done." diff --git a/projects/lnsp-mediator/src/features/subscription/dto/update-subscription.dto.ts b/projects/lnsp-mediator/src/features/subscription/dto/update-subscription.dto.ts new file mode 100644 index 00000000..ca5a5918 --- /dev/null +++ b/projects/lnsp-mediator/src/features/subscription/dto/update-subscription.dto.ts @@ -0,0 +1,7 @@ +import { IsOptional, IsString } from 'class-validator'; + +export class UpdateSubscriptionDto { + @IsOptional() + @IsString() + targetAddress?: string; +} diff --git a/projects/lnsp-mediator/src/features/subscription/subscription.controller.spec.ts b/projects/lnsp-mediator/src/features/subscription/subscription.controller.spec.ts index a7748254..d23db43a 100644 --- a/projects/lnsp-mediator/src/features/subscription/subscription.controller.spec.ts +++ b/projects/lnsp-mediator/src/features/subscription/subscription.controller.spec.ts @@ -4,13 +4,31 @@ import { SubscriptionService } from './subscription.service'; describe('SubscriptionController', () => { let controller: SubscriptionController; + let service: jest.Mocked< + Pick< + SubscriptionService, + | 'handleSubscription' + | 'createFromDto' + | 'getAll' + | 'getById' + | 'update' + | 'delete' + > + >; beforeEach(async () => { + service = { + handleSubscription: jest.fn(), + createFromDto: jest.fn(), + getAll: jest.fn(), + getById: jest.fn(), + update: jest.fn(), + delete: jest.fn(), + }; + const module: TestingModule = await Test.createTestingModule({ controllers: [SubscriptionController], - providers: [ - { provide: SubscriptionService, useValue: { handleSubscription: jest.fn(), getAll: jest.fn() } }, - ], + providers: [{ provide: SubscriptionService, useValue: service }], }).compile(); controller = module.get(SubscriptionController); @@ -19,4 +37,91 @@ describe('SubscriptionController', () => { it('should be defined', () => { expect(controller).toBeDefined(); }); + + describe('POST /subscription', () => { + it('dispatches to handleSubscription when body is parsed SOAP XML', async () => { + const xmlBody = { 'soap:envelope': { 'soap:body': [{}] } }; + const xmlResp = { + contentType: 'application/json', + responseBody: 'Subscription created successfully', + status: 200, + }; + service.handleSubscription.mockResolvedValue(xmlResp); + + const result = await controller.create(xmlBody); + + expect(service.handleSubscription).toHaveBeenCalledWith(xmlBody); + expect(service.createFromDto).not.toHaveBeenCalled(); + expect(result).toEqual(xmlResp); + }); + + it('dispatches to createFromDto when body is JSON', async () => { + const jsonBody = { targetAddress: 'http://x' }; + const created = { + _id: '507f1f77bcf86cd799439011', + targetAddress: 'http://x', + }; + service.createFromDto.mockResolvedValue(created as any); + + const result = await controller.create(jsonBody); + + expect(service.createFromDto).toHaveBeenCalledWith(jsonBody); + expect(service.handleSubscription).not.toHaveBeenCalled(); + expect(result).toEqual(created); + }); + }); + + describe('GET /subscription', () => { + it('delegates to getAll', async () => { + const rows = [{ _id: 'a', targetAddress: 'http://a' }]; + service.getAll.mockResolvedValue(rows as any); + await expect(controller.getAll()).resolves.toEqual(rows); + }); + }); + + describe('GET /subscription/:id', () => { + it('delegates to getById with the id param', async () => { + const doc = { + _id: '507f1f77bcf86cd799439011', + targetAddress: 'http://x', + }; + service.getById.mockResolvedValue(doc as any); + await expect( + controller.getById('507f1f77bcf86cd799439011'), + ).resolves.toEqual(doc); + expect(service.getById).toHaveBeenCalledWith('507f1f77bcf86cd799439011'); + }); + }); + + describe('PATCH /subscription/:id', () => { + it('delegates to update with id and dto', async () => { + const updated = { + _id: '507f1f77bcf86cd799439011', + targetAddress: 'http://y', + }; + service.update.mockResolvedValue(updated as any); + const dto = { targetAddress: 'http://y' }; + await expect( + controller.update('507f1f77bcf86cd799439011', dto), + ).resolves.toEqual(updated); + expect(service.update).toHaveBeenCalledWith( + '507f1f77bcf86cd799439011', + dto, + ); + }); + }); + + describe('DELETE /subscription/:id', () => { + it('delegates to delete with id', async () => { + const deleted = { + _id: '507f1f77bcf86cd799439011', + targetAddress: 'http://x', + }; + service.delete.mockResolvedValue(deleted as any); + await expect( + controller.delete('507f1f77bcf86cd799439011'), + ).resolves.toEqual(deleted); + expect(service.delete).toHaveBeenCalledWith('507f1f77bcf86cd799439011'); + }); + }); }); diff --git a/projects/lnsp-mediator/src/features/subscription/subscription.controller.ts b/projects/lnsp-mediator/src/features/subscription/subscription.controller.ts index ab718520..36532132 100644 --- a/projects/lnsp-mediator/src/features/subscription/subscription.controller.ts +++ b/projects/lnsp-mediator/src/features/subscription/subscription.controller.ts @@ -1,6 +1,15 @@ -import { Controller, Post, Body, Get } from '@nestjs/common'; -import { SubscriptionService } from './subscription.service'; +import { + Body, + Controller, + Delete, + Get, + Param, + Patch, + Post, +} from '@nestjs/common'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { SubscriptionService } from './subscription.service'; +import { UpdateSubscriptionDto } from './dto/update-subscription.dto'; @Controller('subscription') @ApiTags('subscription') @@ -8,17 +17,38 @@ export class SubscriptionController { constructor(private readonly subscriptionService: SubscriptionService) {} @Post() - @ApiOperation({ summary: 'Create a new subscription' }) - async create(@Body() xmlPayload: any) { - const r = this.subscriptionService.handleSubscription(xmlPayload); - - // TODO: Return valid subscription response - return r; + @ApiOperation({ + summary: + 'Create a subscription (JSON body) or accept a legacy SOAP XML subscribe envelope', + }) + async create(@Body() body: any) { + if (body && typeof body === 'object' && 'soap:envelope' in body) { + return this.subscriptionService.handleSubscription(body); + } + return this.subscriptionService.createFromDto(body); } @Get() - @ApiOperation({ summary: 'Get all subscriptions' }) + @ApiOperation({ summary: 'List all subscriptions' }) async getAll() { return this.subscriptionService.getAll(); } + + @Get(':id') + @ApiOperation({ summary: 'Get a subscription by id' }) + async getById(@Param('id') id: string) { + return this.subscriptionService.getById(id); + } + + @Patch(':id') + @ApiOperation({ summary: 'Update a subscription by id' }) + async update(@Param('id') id: string, @Body() dto: UpdateSubscriptionDto) { + return this.subscriptionService.update(id, dto); + } + + @Delete(':id') + @ApiOperation({ summary: 'Delete a subscription by id' }) + async delete(@Param('id') id: string) { + return this.subscriptionService.delete(id); + } } diff --git a/projects/lnsp-mediator/src/features/subscription/subscription.integration.spec.ts b/projects/lnsp-mediator/src/features/subscription/subscription.integration.spec.ts new file mode 100644 index 00000000..2b9c0559 --- /dev/null +++ b/projects/lnsp-mediator/src/features/subscription/subscription.integration.spec.ts @@ -0,0 +1,99 @@ +import { INestApplication } from '@nestjs/common'; +import { MongooseModule } from '@nestjs/mongoose'; +import { Test, TestingModule } from '@nestjs/testing'; +import { MongoMemoryServer } from 'mongodb-memory-server'; +import request from 'supertest'; +import { SubscriptionModule } from './subscription.module'; + +// Allow extra time for the first-run mongodb-memory-server binary download. +jest.setTimeout(60_000); + +describe('Subscription CRUD (integration)', () => { + let app: INestApplication; + let mongod: MongoMemoryServer; + + beforeAll(async () => { + mongod = await MongoMemoryServer.create(); + + const moduleRef: TestingModule = await Test.createTestingModule({ + imports: [MongooseModule.forRoot(mongod.getUri()), SubscriptionModule], + }).compile(); + + app = moduleRef.createNestApplication(); + await app.init(); + }); + + afterAll(async () => { + if (app) await app.close(); + if (mongod) await mongod.stop(); + }); + + it('round-trips a subscription through POST / GET list / GET:id / PATCH / DELETE', async () => { + const http = request(app.getHttpServer()); + + // Create + const createRes = await http + .post('/subscription') + .send({ targetAddress: 'http://a.example/cb' }) + .expect(201); + expect(createRes.body.targetAddress).toBe('http://a.example/cb'); + const id = createRes.body._id; + expect(typeof id).toBe('string'); + + // List contains it + const listRes = await http.get('/subscription').expect(200); + expect(Array.isArray(listRes.body)).toBe(true); + expect(listRes.body.map((s: any) => s._id)).toContain(id); + + // Read by id + const getRes = await http.get(`/subscription/${id}`).expect(200); + expect(getRes.body.targetAddress).toBe('http://a.example/cb'); + + // Patch + const patchRes = await http + .patch(`/subscription/${id}`) + .send({ targetAddress: 'http://b.example/cb' }) + .expect(200); + expect(patchRes.body.targetAddress).toBe('http://b.example/cb'); + + // Delete + await http.delete(`/subscription/${id}`).expect(200); + + // Now missing + await http.get(`/subscription/${id}`).expect(404); + }); + + it('returns 400 on invalid ObjectId', async () => { + await request(app.getHttpServer()) + .get('/subscription/not-an-id') + .expect(400); + await request(app.getHttpServer()) + .delete('/subscription/not-an-id') + .expect(400); + await request(app.getHttpServer()) + .patch('/subscription/not-an-id') + .send({ targetAddress: 'http://c' }) + .expect(400); + }); + + it('returns 404 on valid-but-missing id', async () => { + const unknown = '507f1f77bcf86cd799439011'; + await request(app.getHttpServer()) + .get(`/subscription/${unknown}`) + .expect(404); + await request(app.getHttpServer()) + .delete(`/subscription/${unknown}`) + .expect(404); + await request(app.getHttpServer()) + .patch(`/subscription/${unknown}`) + .send({ targetAddress: 'http://c' }) + .expect(404); + }); + + it('rejects POST without targetAddress with 400', async () => { + await request(app.getHttpServer()) + .post('/subscription') + .send({}) + .expect(400); + }); +}); diff --git a/projects/lnsp-mediator/src/features/subscription/subscription.service.spec.ts b/projects/lnsp-mediator/src/features/subscription/subscription.service.spec.ts index dfe85cbc..2e69f52f 100644 --- a/projects/lnsp-mediator/src/features/subscription/subscription.service.spec.ts +++ b/projects/lnsp-mediator/src/features/subscription/subscription.service.spec.ts @@ -1,15 +1,34 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { BadRequestException, NotFoundException } from '@nestjs/common'; import { SubscriptionService } from './subscription.service'; import { SubscriptionDAO } from './subscription.dao'; describe('SubscriptionService', () => { let service: SubscriptionService; + let dao: jest.Mocked< + Pick< + SubscriptionDAO, + 'createUnique' | 'find' | 'findOne' | 'updateOne' | 'deleteOne' + > + >; + + const VALID_ID = '507f1f77bcf86cd799439011'; + const MISSING_ID = '507f1f77bcf86cd799439099'; + const INVALID_ID = 'not-an-id'; beforeEach(async () => { + dao = { + createUnique: jest.fn(), + find: jest.fn(), + findOne: jest.fn(), + updateOne: jest.fn(), + deleteOne: jest.fn(), + }; + const module: TestingModule = await Test.createTestingModule({ providers: [ SubscriptionService, - { provide: SubscriptionDAO, useValue: { createUnique: jest.fn(), find: jest.fn() } }, + { provide: SubscriptionDAO, useValue: dao }, ], }).compile(); @@ -19,4 +38,171 @@ describe('SubscriptionService', () => { it('should be defined', () => { expect(service).toBeDefined(); }); + + describe('getAll', () => { + it('delegates to dao.find', async () => { + const rows = [{ _id: VALID_ID, targetAddress: 'http://a' }]; + dao.find.mockResolvedValue(rows as any); + await expect(service.getAll()).resolves.toEqual(rows); + expect(dao.find).toHaveBeenCalledTimes(1); + }); + }); + + describe('createFromDto', () => { + it('calls dao.createUnique with the targetAddress', async () => { + const doc = { _id: VALID_ID, targetAddress: 'http://x' }; + dao.createUnique.mockResolvedValue(doc as any); + const result = await service.createFromDto({ targetAddress: 'http://x' }); + expect(dao.createUnique).toHaveBeenCalledWith({ + targetAddress: 'http://x', + }); + expect(result).toEqual(doc); + }); + + it('throws BadRequestException when targetAddress is missing', async () => { + await expect(service.createFromDto({} as any)).rejects.toBeInstanceOf( + BadRequestException, + ); + expect(dao.createUnique).not.toHaveBeenCalled(); + }); + + it('throws BadRequestException when targetAddress is not a string', async () => { + await expect( + service.createFromDto({ targetAddress: 42 as any }), + ).rejects.toBeInstanceOf(BadRequestException); + await expect( + service.createFromDto({ targetAddress: '' }), + ).rejects.toBeInstanceOf(BadRequestException); + expect(dao.createUnique).not.toHaveBeenCalled(); + }); + + it('throws BadRequestException when dto is null/undefined', async () => { + await expect(service.createFromDto(null as any)).rejects.toBeInstanceOf( + BadRequestException, + ); + await expect( + service.createFromDto(undefined as any), + ).rejects.toBeInstanceOf(BadRequestException); + }); + }); + + describe('getById', () => { + it('returns doc when found', async () => { + const doc = { _id: VALID_ID, targetAddress: 'http://x' }; + dao.findOne.mockResolvedValue(doc as any); + await expect(service.getById(VALID_ID)).resolves.toEqual(doc); + expect(dao.findOne).toHaveBeenCalledWith({ _id: VALID_ID }); + }); + + it('throws NotFoundException when dao returns null', async () => { + dao.findOne.mockResolvedValue(null); + await expect(service.getById(MISSING_ID)).rejects.toBeInstanceOf( + NotFoundException, + ); + }); + + it('throws BadRequestException on invalid ObjectId without hitting dao', async () => { + await expect(service.getById(INVALID_ID)).rejects.toBeInstanceOf( + BadRequestException, + ); + expect(dao.findOne).not.toHaveBeenCalled(); + }); + }); + + describe('update', () => { + it('calls dao.updateOne with $set and returns updated doc', async () => { + const updated = { _id: VALID_ID, targetAddress: 'http://y' }; + dao.updateOne.mockResolvedValue(updated as any); + const result = await service.update(VALID_ID, { + targetAddress: 'http://y', + }); + expect(dao.updateOne).toHaveBeenCalledWith( + { _id: VALID_ID }, + { $set: { targetAddress: 'http://y' } }, + ); + expect(result).toEqual(updated); + }); + + it('throws NotFoundException when dao returns null', async () => { + dao.updateOne.mockResolvedValue(null); + await expect( + service.update(MISSING_ID, { targetAddress: 'http://y' }), + ).rejects.toBeInstanceOf(NotFoundException); + }); + + it('throws BadRequestException on invalid ObjectId', async () => { + await expect( + service.update(INVALID_ID, { targetAddress: 'http://y' }), + ).rejects.toBeInstanceOf(BadRequestException); + expect(dao.updateOne).not.toHaveBeenCalled(); + }); + }); + + describe('delete', () => { + it('calls dao.deleteOne and returns deleted doc', async () => { + const deleted = { _id: VALID_ID, targetAddress: 'http://x' }; + dao.deleteOne.mockResolvedValue(deleted as any); + const result = await service.delete(VALID_ID); + expect(dao.deleteOne).toHaveBeenCalledWith({ _id: VALID_ID }); + expect(result).toEqual(deleted); + }); + + it('throws NotFoundException when dao returns null', async () => { + dao.deleteOne.mockResolvedValue(null); + await expect(service.delete(MISSING_ID)).rejects.toBeInstanceOf( + NotFoundException, + ); + }); + + it('throws BadRequestException on invalid ObjectId', async () => { + await expect(service.delete(INVALID_ID)).rejects.toBeInstanceOf( + BadRequestException, + ); + expect(dao.deleteOne).not.toHaveBeenCalled(); + }); + }); + + describe('handleSubscription (legacy XML)', () => { + const xmlBody = { + 'soap:envelope': { + 'soap:body': [ + { + 'wsnt:subscribe': [ + { + 'wsnt:consumerreference': [ + { 'wsa:address': ['http://subscriber.example/cb'] }, + ], + }, + ], + }, + ], + }, + }; + + it('returns success shape when DAO write succeeds', async () => { + dao.createUnique.mockResolvedValue({ + _id: VALID_ID, + targetAddress: 'http://subscriber.example/cb', + } as any); + const r = await service.handleSubscription(xmlBody); + expect(dao.createUnique).toHaveBeenCalledWith({ + targetAddress: 'http://subscriber.example/cb', + }); + expect(r).toEqual({ + contentType: 'application/json', + responseBody: 'Subscription created successfully', + status: 200, + }); + }); + + it('returns failure shape when DAO write rejects (regression for missing-await bug)', async () => { + dao.createUnique.mockRejectedValue(new Error('db down')); + const r = await service.handleSubscription(xmlBody); + expect(r).toEqual({ + contentType: 'application/json', + responseBody: 'Subscription failed', + status: 500, + }); + }); + }); }); diff --git a/projects/lnsp-mediator/src/features/subscription/subscription.service.ts b/projects/lnsp-mediator/src/features/subscription/subscription.service.ts index 22f2e86e..7ed5037d 100644 --- a/projects/lnsp-mediator/src/features/subscription/subscription.service.ts +++ b/projects/lnsp-mediator/src/features/subscription/subscription.service.ts @@ -1,6 +1,13 @@ -import { Injectable } from '@nestjs/common'; +import { + BadRequestException, + Injectable, + NotFoundException, +} from '@nestjs/common'; +import { isValidObjectId } from 'mongoose'; import { Subscription } from './subscription.schema'; import { SubscriptionDAO } from './subscription.dao'; +import { CreateSubscriptionDto } from './dto/create-subscription.dto'; +import { UpdateSubscriptionDto } from './dto/update-subscription.dto'; const contentType = 'application/json'; @@ -8,36 +15,74 @@ const contentType = 'application/json'; export class SubscriptionService { constructor(private readonly subscriptionDAO: SubscriptionDAO) {} - handleSubscription(xmlPayload: any) { + async handleSubscription(xmlPayload: any) { const targetAddress = xmlPayload['soap:envelope']['soap:body'][0]['wsnt:subscribe'][0][ 'wsnt:consumerreference' ][0]['wsa:address'][0]; - const subscriptionData: Subscription = { - targetAddress: targetAddress, - }; - - let responseBody; - let status; - try { - this.create(subscriptionData); - responseBody = 'Subscription created successfully'; - status = 200; - } catch (error) { - responseBody = 'Subscription failed'; - status = 500; + await this.create({ targetAddress }); + return { + contentType, + responseBody: 'Subscription created successfully', + status: 200, + }; + } catch { + return { contentType, responseBody: 'Subscription failed', status: 500 }; } - - return { contentType: contentType, responseBody, status }; } create(subscription: Subscription) { return this.subscriptionDAO.createUnique(subscription); } + async createFromDto(dto: CreateSubscriptionDto) { + if ( + !dto || + typeof dto.targetAddress !== 'string' || + dto.targetAddress.length === 0 + ) { + throw new BadRequestException( + 'targetAddress (non-empty string) is required', + ); + } + return this.subscriptionDAO.createUnique({ + targetAddress: dto.targetAddress, + }); + } + getAll() { return this.subscriptionDAO.find(); } + + async getById(id: string) { + this.assertValidId(id); + const doc = await this.subscriptionDAO.findOne({ _id: id }); + if (!doc) throw new NotFoundException(`Subscription ${id} not found`); + return doc; + } + + async update(id: string, dto: UpdateSubscriptionDto) { + this.assertValidId(id); + const updated = await this.subscriptionDAO.updateOne( + { _id: id }, + { $set: dto }, + ); + if (!updated) throw new NotFoundException(`Subscription ${id} not found`); + return updated; + } + + async delete(id: string) { + this.assertValidId(id); + const deleted = await this.subscriptionDAO.deleteOne({ _id: id }); + if (!deleted) throw new NotFoundException(`Subscription ${id} not found`); + return deleted; + } + + private assertValidId(id: string) { + if (!isValidObjectId(id)) { + throw new BadRequestException(`Invalid id: ${id}`); + } + } } diff --git a/projects/lnsp-mediator/yarn.lock b/projects/lnsp-mediator/yarn.lock index d23273a4..d45647bf 100644 --- a/projects/lnsp-mediator/yarn.lock +++ b/projects/lnsp-mediator/yarn.lock @@ -1145,6 +1145,13 @@ dependencies: sparse-bitfield "^3.0.3" +"@mongodb-js/saslprep@^1.3.0": + version "1.4.6" + resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz#2edf5819fa0e69d86059f44d1fe57ae9d7817c12" + integrity sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g== + dependencies: + sparse-bitfield "^3.0.3" + "@nestjs/axios@^3.0.3": version "3.1.2" resolved "https://registry.yarnpkg.com/@nestjs/axios/-/axios-3.1.2.tgz#e55c39cfd2e0ed24304b9aa31d1854ecbfe760c7" @@ -1994,6 +2001,13 @@ dependencies: "@types/webidl-conversions" "*" +"@types/whatwg-url@^13.0.0": + version "13.0.0" + resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-13.0.0.tgz#2b11e32772fd321c0dedf4d655953ea8ce587b2a" + integrity sha512-N8WXpbE6Wgri7KUSvrmQcqrMllKZ9uxkYWMt+mCSGwNc0Hsw9VQTW7ApqI4XNrx6/SaM2QQJCzMPDEXE058s+Q== + dependencies: + "@types/webidl-conversions" "*" + "@types/whatwg-url@^8.2.1": version "8.2.2" resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-8.2.2.tgz#749d5b3873e845897ada99be4448041d4cc39e63" @@ -2275,6 +2289,11 @@ agenda@^5.0.0: moment-timezone "~0.5.37" mongodb "^4.11.0" +agent-base@^7.1.2: + version "7.1.4" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== + ajv-formats@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -2406,6 +2425,13 @@ asap@^2.0.0: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +async-mutex@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.5.0.tgz#353c69a0b9e75250971a64ac203b0ebfddd75482" + integrity sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA== + dependencies: + tslib "^2.4.0" + async@^3.2.3: version "3.2.6" resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" @@ -2425,6 +2451,11 @@ axios@^1.12.0: form-data "^4.0.4" proxy-from-env "^1.1.0" +b4a@^1.6.4: + version "1.8.0" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.8.0.tgz#1ca3ba0edc9469aaabef5647e769a83d50180b1a" + integrity sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg== + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -2493,6 +2524,49 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +bare-events@^2.5.4, bare-events@^2.7.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.8.2.tgz#7b3e10bd8e1fc80daf38bb516921678f566ab89f" + integrity sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ== + +bare-fs@^4.5.5: + version "4.7.1" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-4.7.1.tgz#6e81f784761102867c13f0823aa48c942d160f00" + integrity sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw== + dependencies: + bare-events "^2.5.4" + bare-path "^3.0.0" + bare-stream "^2.6.4" + bare-url "^2.2.2" + fast-fifo "^1.3.2" + +bare-os@^3.0.1: + version "3.8.7" + resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-3.8.7.tgz#09c7c4e8c817de750b0b69b65c929513f69ede65" + integrity sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w== + +bare-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-3.0.0.tgz#b59d18130ba52a6af9276db3e96a2e3d3ea52178" + integrity sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw== + dependencies: + bare-os "^3.0.1" + +bare-stream@^2.6.4: + version "2.13.0" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.13.0.tgz#dea59458dcf2689e9387134efccec015dfdbe3cf" + integrity sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA== + dependencies: + streamx "^2.25.0" + teex "^1.0.1" + +bare-url@^2.2.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bare-url/-/bare-url-2.4.0.tgz#1546d63057917189cab9b24629e946e1e8f7af31" + integrity sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA== + dependencies: + bare-path "^3.0.0" + base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -2600,6 +2674,16 @@ bson@^6.10.1: resolved "https://registry.yarnpkg.com/bson/-/bson-6.10.1.tgz#dcd04703178f5ecf5b25de04edd2a95ec79385d3" integrity sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA== +bson@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/bson/-/bson-7.2.0.tgz#1a496a42d9ff130b9f3ab8efd465459c758c747f" + integrity sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ== + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -2654,7 +2738,7 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.2.0: +camelcase@^6.2.0, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -2826,6 +2910,11 @@ comment-json@4.2.5: has-own-prop "^2.0.0" repeat-string "^1.6.1" +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + component-emitter@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" @@ -2962,6 +3051,13 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + debug@4.x, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.4: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" @@ -3346,6 +3442,13 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +events-universal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/events-universal/-/events-universal-1.0.1.tgz#b56a84fd611b6610e0a2d0f09f80fdf931e2dfe6" + integrity sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw== + dependencies: + bare-events "^2.7.0" + events@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -3445,6 +3548,11 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== +fast-fifo@^1.2.0, fast-fifo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + fast-glob@^3.2.9: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" @@ -3545,6 +3653,15 @@ finalhandler@1.3.1: statuses "2.0.1" unpipe "~1.0.0" +find-cache-dir@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -3575,6 +3692,11 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== +follow-redirects@^1.15.11: + version "1.16.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc" + integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== + follow-redirects@^1.15.6: version "1.15.9" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" @@ -3876,6 +3998,14 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +https-proxy-agent@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== + dependencies: + agent-base "^7.1.2" + debug "4" + human-interval@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/human-interval/-/human-interval-2.0.1.tgz#655baf606c7067bb26042dcae14ec777b099af15" @@ -4714,6 +4844,13 @@ magic-string@0.30.8: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -4876,6 +5013,40 @@ mongodb-connection-string-url@^3.0.0: "@types/whatwg-url" "^11.0.2" whatwg-url "^13.0.0" +mongodb-connection-string-url@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.1.tgz#347b664cd9e6ddff10d5c1c6010d6d8dbfe9272d" + integrity sha512-h0AZ9A7IDVwwHyMxmdMXKy+9oNlF0zFoahHiX3vQ8e3KFcSP3VmsmfvtRSuLPxmyv2vjIDxqty8smTgie/SNRQ== + dependencies: + "@types/whatwg-url" "^13.0.0" + whatwg-url "^14.1.0" + +mongodb-memory-server-core@11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/mongodb-memory-server-core/-/mongodb-memory-server-core-11.0.1.tgz#952709a231acad192c3cd8b9795b15cdf2a04ff6" + integrity sha512-IcIb2S9Xf7Lmz43Z1ZujMqNg7PU5Q7yn+4wOnu7l6pfeGPkEmlqzV1hIbroVx8s4vXhPB1oMGC1u8clW7aj3Xw== + dependencies: + async-mutex "^0.5.0" + camelcase "^6.3.0" + debug "^4.4.3" + find-cache-dir "^3.3.2" + follow-redirects "^1.15.11" + https-proxy-agent "^7.0.6" + mongodb "^7.0.0" + new-find-package-json "^2.0.0" + semver "^7.7.3" + tar-stream "^3.1.7" + tslib "^2.8.1" + yauzl "^3.2.0" + +mongodb-memory-server@^11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/mongodb-memory-server/-/mongodb-memory-server-11.0.1.tgz#6d2848f41460989ef7253d86e2632f387ac4d62a" + integrity sha512-nUlKovSJZBh7q5hPsewFRam9H66D08Ne18nyknkNalfXMPtK1Og3kOcuqQhcX88x/pghSZPIJHrLbxNFW3OWiw== + dependencies: + mongodb-memory-server-core "11.0.1" + tslib "^2.8.1" + mongodb@^4.11.0: version "4.17.2" resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-4.17.2.tgz#237c0534e36a3449bd74c6bf6d32f87a1ca7200c" @@ -4888,6 +5059,15 @@ mongodb@^4.11.0: "@aws-sdk/credential-providers" "^3.186.0" "@mongodb-js/saslprep" "^1.1.0" +mongodb@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-7.1.1.tgz#d08479221b81ba66f1f4a858af621edaaa598d95" + integrity sha512-067DXiMjcpYQl6bGjWQoTUEE9UoRViTtKFcoqX7z08I+iDZv/emH1g8XEFiO3qiDfXAheT5ozl1VffDTKhIW/w== + dependencies: + "@mongodb-js/saslprep" "^1.3.0" + bson "^7.1.1" + mongodb-connection-string-url "^7.0.0" + mongodb@~6.12.0: version "6.12.0" resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.12.0.tgz#8b0bda1b18cbb3f0aec8ab4119c5dc535a43c444" @@ -4970,6 +5150,13 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +new-find-package-json@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/new-find-package-json/-/new-find-package-json-2.0.0.tgz#96553638781db35061f351e8ccb4d07126b6407d" + integrity sha512-lDcBsjBSMlj3LXH2v/FW3txlh2pYTjmbOXPYJD93HI5EwuLzI11tdHSIpUMmfq/IOsldj4Ps8M8flhm+pCK4Ew== + dependencies: + debug "^4.3.4" + node-abort-controller@^3.0.1: version "3.1.1" resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" @@ -5194,6 +5381,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + picocolors@^1.0.0, picocolors@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -5214,7 +5406,7 @@ pirates@^4.0.4: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== -pkg-dir@^4.2.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -5278,7 +5470,7 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0: +punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0, punycode@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== @@ -5480,7 +5672,7 @@ schema-utils@^3.1.1, schema-utils@^3.2.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -semver@^6.3.0, semver@^6.3.1: +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -5490,6 +5682,11 @@ semver@^7.3.4, semver@^7.3.5, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semve resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +semver@^7.7.3: + version "7.7.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" + integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== + send@0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" @@ -5663,6 +5860,15 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +streamx@^2.12.5, streamx@^2.15.0, streamx@^2.25.0: + version "2.25.0" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.25.0.tgz#cc967e99390fda8b918b1eeaf3bc437637c8c7af" + integrity sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg== + dependencies: + events-universal "^1.0.0" + fast-fifo "^1.3.2" + text-decoder "^1.1.0" + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -5837,6 +6043,23 @@ tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar-stream@^3.1.7: + version "3.1.8" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.8.tgz#a26f5b26c34dfd4936a4f8a9e694a8f5102af13d" + integrity sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ== + dependencies: + b4a "^1.6.4" + bare-fs "^4.5.5" + fast-fifo "^1.2.0" + streamx "^2.15.0" + +teex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/teex/-/teex-1.0.1.tgz#b8fa7245ef8e8effa8078281946c85ab780a0b12" + integrity sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg== + dependencies: + streamx "^2.12.5" + terser-webpack-plugin@^5.3.10: version "5.3.10" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" @@ -5867,6 +6090,13 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-decoder@^1.1.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/text-decoder/-/text-decoder-1.2.7.tgz#5d073a9a74b9c0a9d28dfadcab96b604af57d8ba" + integrity sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ== + dependencies: + b4a "^1.6.4" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -5915,6 +6145,13 @@ tr46@^4.1.1: dependencies: punycode "^2.3.0" +tr46@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.1.1.tgz#96ae867cddb8fdb64a49cc3059a8d428bcf238ca" + integrity sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw== + dependencies: + punycode "^2.3.1" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -5998,7 +6235,7 @@ tslib@2.7.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== -tslib@2.8.1, tslib@^2.1.0, tslib@^2.6.2: +tslib@2.8.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -6206,6 +6443,14 @@ whatwg-url@^13.0.0: tr46 "^4.1.1" webidl-conversions "^7.0.0" +whatwg-url@^14.1.0: + version "14.2.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.2.0.tgz#4ee02d5d725155dae004f6ae95c73e7ef5d95663" + integrity sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw== + dependencies: + tr46 "^5.1.0" + webidl-conversions "^7.0.0" + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -6344,6 +6589,14 @@ yargs@^17.3.1: y18n "^5.0.5" yargs-parser "^21.1.1" +yauzl@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-3.3.0.tgz#5be5e287b9a8112941c177734a34bf61a3e11bb4" + integrity sha512-PtGEvEP30p7sbIBJKUBjUnqgTVOyMURc4dLo9iNyAJnNIEz9pm88cCXF21w94Kg3k6RXkeZh5DHOGS0qEONvNQ== + dependencies: + buffer-crc32 "~0.2.3" + pend "~1.2.0" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"