diff --git a/apps/backend/src/allocations/allocations.entity.ts b/apps/backend/src/allocations/allocations.entity.ts index 269852837..cf723df2f 100644 --- a/apps/backend/src/allocations/allocations.entity.ts +++ b/apps/backend/src/allocations/allocations.entity.ts @@ -11,28 +11,28 @@ import { Order } from '../orders/order.entity'; @Entity('allocations') export class Allocation { @PrimaryGeneratedColumn({ name: 'allocation_id' }) - allocationId: number; + allocationId!: number; @Column({ name: 'order_id', type: 'int', nullable: false }) - orderId: number; + orderId!: number; @ManyToOne(() => Order, (order) => order.allocations) @JoinColumn({ name: 'order_id' }) - order: Order; + order!: Order; @Column({ name: 'item_id', type: 'int', nullable: false }) - itemId: number; + itemId!: number; @ManyToOne(() => DonationItem, (item) => item.allocations) @JoinColumn({ name: 'item_id' }) - item: DonationItem; + item!: DonationItem; @Column({ name: 'allocated_quantity', type: 'int' }) - allocatedQuantity: number; + allocatedQuantity!: number; @Column({ name: 'reserved_at', type: 'timestamp' }) - reservedAt: Date; + reservedAt!: Date; - @Column({ name: 'fulfilled_at', type: 'timestamp' }) - fulfilledAt: Date; + @Column({ name: 'fulfilled_at', type: 'timestamp', nullable: true }) + fulfilledAt!: Date | null; } diff --git a/apps/backend/src/app.module.ts b/apps/backend/src/app.module.ts index 7fe3ff82e..880c102c3 100644 --- a/apps/backend/src/app.module.ts +++ b/apps/backend/src/app.module.ts @@ -31,7 +31,7 @@ import { ScheduleModule } from '@nestjs/schedule'; TypeOrmModule.forRootAsync({ inject: [ConfigService], useFactory: async (configService: ConfigService) => - configService.get('typeorm'), + configService.getOrThrow('typeorm'), }), ScheduleModule.forRoot(), UsersModule, diff --git a/apps/backend/src/auth/auth.controller.ts b/apps/backend/src/auth/auth.controller.ts index ec7410085..c083b9b93 100644 --- a/apps/backend/src/auth/auth.controller.ts +++ b/apps/backend/src/auth/auth.controller.ts @@ -25,8 +25,12 @@ export class AuthController { // By default, creates a standard user try { await this.authService.signup(signUpDto); - } catch (e) { - throw new BadRequestException(e.message); + } catch (e: unknown) { + const message = + e instanceof Error + ? e.message + : 'Unexpected error occurred when signing up user'; + throw new BadRequestException(message); } const user = await this.usersService.create( @@ -45,8 +49,12 @@ export class AuthController { verifyUser(@Body() body: VerifyUserDto): void { try { this.authService.verifyUser(body.email, body.verificationCode); - } catch (e) { - throw new BadRequestException(e.message); + } catch (e: unknown) { + const message = + e instanceof Error + ? e.message + : 'Unexpected error occurred when verifying user'; + throw new BadRequestException(message); } } @@ -76,8 +84,12 @@ export class AuthController { try { await this.authService.deleteUser(user.email); - } catch (e) { - throw new BadRequestException(e.message); + } catch (e: unknown) { + const message = + e instanceof Error + ? e.message + : 'Unexpected error occurred when deleting user'; + throw new BadRequestException(message); } this.usersService.remove(user.id); diff --git a/apps/backend/src/auth/auth.service.spec.ts b/apps/backend/src/auth/auth.service.spec.ts index 800ab6626..248f642d7 100644 --- a/apps/backend/src/auth/auth.service.spec.ts +++ b/apps/backend/src/auth/auth.service.spec.ts @@ -5,6 +5,11 @@ describe('AuthService', () => { let service: AuthService; beforeEach(async () => { + process.env.AWS_ACCESS_KEY_ID = 'test'; + process.env.AWS_SECRET_ACCESS_KEY = 'test'; + process.env.COGNITO_CLIENT_SECRET = 'test'; + process.env.AWS_REGION = 'us-east-1'; + const module: TestingModule = await Test.createTestingModule({ providers: [AuthService], }).compile(); diff --git a/apps/backend/src/auth/auth.service.ts b/apps/backend/src/auth/auth.service.ts index 8c38f366e..84f89e351 100644 --- a/apps/backend/src/auth/auth.service.ts +++ b/apps/backend/src/auth/auth.service.ts @@ -1,12 +1,18 @@ -import { Injectable } from '@nestjs/common'; +import { + Injectable, + InternalServerErrorException, + NotFoundException, +} from '@nestjs/common'; import { AdminDeleteUserCommand, AdminInitiateAuthCommand, + AdminInitiateAuthCommandOutput, CognitoIdentityProviderClient, ConfirmForgotPasswordCommand, ConfirmSignUpCommand, ForgotPasswordCommand, SignUpCommand, + AuthenticationResultType, } from '@aws-sdk/client-cognito-identity-provider'; import CognitoAuthConfig from './aws-exports'; @@ -17,6 +23,18 @@ import { createHmac } from 'crypto'; import { RefreshTokenDto } from './dtos/refresh-token.dto'; import { Role } from '../users/types'; import { ConfirmPasswordDto } from './dtos/confirm-password.dto'; +import { validateEnv } from '../utils/validation.utils'; + +type SignInAuthResult = AuthenticationResultType & { + AccessToken: string; + RefreshToken: string; + IdToken: string; +}; + +type RefreshAuthResult = AuthenticationResultType & { + AccessToken: string; + IdToken: string; +}; @Injectable() export class AuthService { @@ -27,12 +45,12 @@ export class AuthService { this.providerClient = new CognitoIdentityProviderClient({ region: CognitoAuthConfig.region, credentials: { - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + accessKeyId: validateEnv('AWS_ACCESS_KEY_ID'), + secretAccessKey: validateEnv('AWS_SECRET_ACCESS_KEY'), }, }); - this.clientSecret = process.env.COGNITO_CLIENT_SECRET; + this.clientSecret = validateEnv('COGNITO_CLIENT_SECRET'); } // Computes secret hash to authenticate this backend to Cognito @@ -69,8 +87,19 @@ export class AuthService { ], }); - const response = await this.providerClient.send(signUpCommand); - return response.UserConfirmed; + try { + const response = await this.providerClient.send(signUpCommand); + + if (response.UserConfirmed == null) { + throw new InternalServerErrorException( + 'Missing UserConfirmed from Cognito', + ); + } + + return response.UserConfirmed; + } catch (err: unknown) { + throw new InternalServerErrorException('Failed to sign up user'); + } } async verifyUser(email: string, verificationCode: string): Promise { @@ -98,10 +127,13 @@ export class AuthService { const response = await this.providerClient.send(signInCommand); + const authResult = + this.validateAuthenticationResultTokensForSignIn(response); + return { - accessToken: response.AuthenticationResult.AccessToken, - refreshToken: response.AuthenticationResult.RefreshToken, - idToken: response.AuthenticationResult.IdToken, + accessToken: authResult.AccessToken, + refreshToken: authResult.RefreshToken, + idToken: authResult.IdToken, }; } @@ -122,10 +154,13 @@ export class AuthService { const response = await this.providerClient.send(refreshCommand); + const authResult = + this.validateAuthenticationResultTokensForRefresh(response); + return { - accessToken: response.AuthenticationResult.AccessToken, + accessToken: authResult.AccessToken, refreshToken: refreshToken, - idToken: response.AuthenticationResult.IdToken, + idToken: authResult.IdToken, }; } @@ -163,4 +198,48 @@ export class AuthService { await this.providerClient.send(adminDeleteUserCommand); } + + private validateAuthenticationResultTokensForSignIn( + commandOutput: AdminInitiateAuthCommandOutput, + ): SignInAuthResult { + const result = commandOutput.AuthenticationResult; + + if (result == null) { + throw new NotFoundException( + 'No associated authentication result for sign in', + ); + } + + if ( + result.AccessToken == null || + result.RefreshToken == null || + result.IdToken == null + ) { + throw new NotFoundException( + 'Necessary Authentication Result tokens not found for sign in ', + ); + } + + return result as SignInAuthResult; + } + + private validateAuthenticationResultTokensForRefresh( + commandOutput: AdminInitiateAuthCommandOutput, + ): RefreshAuthResult { + const result = commandOutput.AuthenticationResult; + + if (result == null) { + throw new NotFoundException( + 'No associated authentication result for refresh', + ); + } + + if (result.AccessToken == null || result.IdToken == null) { + throw new NotFoundException( + 'Necessary Authentication Result tokens not found for refresh', + ); + } + + return result as RefreshAuthResult; + } } diff --git a/apps/backend/src/auth/authenticated-request.ts b/apps/backend/src/auth/authenticated-request.ts new file mode 100644 index 000000000..d8c0673f4 --- /dev/null +++ b/apps/backend/src/auth/authenticated-request.ts @@ -0,0 +1,7 @@ +import { Request } from 'express'; +import { User } from '../users/user.entity'; + +// user does not have to be provided by the client but is added automatically by the auth backend +export interface AuthenticatedRequest extends Request { + user: User; +} diff --git a/apps/backend/src/auth/dtos/confirm-password.dto.ts b/apps/backend/src/auth/dtos/confirm-password.dto.ts index ec1d63bb0..921deff68 100644 --- a/apps/backend/src/auth/dtos/confirm-password.dto.ts +++ b/apps/backend/src/auth/dtos/confirm-password.dto.ts @@ -2,11 +2,11 @@ import { IsEmail, IsString } from 'class-validator'; export class ConfirmPasswordDto { @IsEmail() - email: string; + email!: string; @IsString() - newPassword: string; + newPassword!: string; @IsString() - confirmationCode: string; + confirmationCode!: string; } diff --git a/apps/backend/src/auth/dtos/delete-user.dto.ts b/apps/backend/src/auth/dtos/delete-user.dto.ts index 1a6163763..78c4a7fa9 100644 --- a/apps/backend/src/auth/dtos/delete-user.dto.ts +++ b/apps/backend/src/auth/dtos/delete-user.dto.ts @@ -2,5 +2,5 @@ import { IsPositive } from 'class-validator'; export class DeleteUserDto { @IsPositive() - userId: number; + userId!: number; } diff --git a/apps/backend/src/auth/dtos/forgot-password.dto.ts b/apps/backend/src/auth/dtos/forgot-password.dto.ts index bbedf0832..e65f7d5bb 100644 --- a/apps/backend/src/auth/dtos/forgot-password.dto.ts +++ b/apps/backend/src/auth/dtos/forgot-password.dto.ts @@ -2,5 +2,5 @@ import { IsEmail } from 'class-validator'; export class ForgotPasswordDto { @IsEmail() - email: string; + email!: string; } diff --git a/apps/backend/src/auth/dtos/refresh-token.dto.ts b/apps/backend/src/auth/dtos/refresh-token.dto.ts index f67905d32..47feef29d 100644 --- a/apps/backend/src/auth/dtos/refresh-token.dto.ts +++ b/apps/backend/src/auth/dtos/refresh-token.dto.ts @@ -2,8 +2,8 @@ import { IsString } from 'class-validator'; export class RefreshTokenDto { @IsString() - refreshToken: string; + refreshToken!: string; @IsString() - userSub: string; + userSub!: string; } diff --git a/apps/backend/src/auth/dtos/sign-in-response.dto.ts b/apps/backend/src/auth/dtos/sign-in-response.dto.ts index b22f6c88a..24fc08994 100644 --- a/apps/backend/src/auth/dtos/sign-in-response.dto.ts +++ b/apps/backend/src/auth/dtos/sign-in-response.dto.ts @@ -1,7 +1,7 @@ export class SignInResponseDto { - accessToken: string; + accessToken!: string; - refreshToken: string; + refreshToken!: string; - idToken: string; + idToken!: string; } diff --git a/apps/backend/src/auth/dtos/sign-in.dto.ts b/apps/backend/src/auth/dtos/sign-in.dto.ts index 51cd9c95d..0be7d513b 100644 --- a/apps/backend/src/auth/dtos/sign-in.dto.ts +++ b/apps/backend/src/auth/dtos/sign-in.dto.ts @@ -2,8 +2,8 @@ import { IsEmail, IsString } from 'class-validator'; export class SignInDto { @IsEmail() - email: string; + email!: string; @IsString() - password: string; + password!: string; } diff --git a/apps/backend/src/auth/dtos/sign-up.dto.ts b/apps/backend/src/auth/dtos/sign-up.dto.ts index 258690eb3..6fa066a3f 100644 --- a/apps/backend/src/auth/dtos/sign-up.dto.ts +++ b/apps/backend/src/auth/dtos/sign-up.dto.ts @@ -2,16 +2,16 @@ import { IsEmail, IsNotEmpty, IsString, IsPhoneNumber } from 'class-validator'; export class SignUpDto { @IsString() - firstName: string; + firstName!: string; @IsString() - lastName: string; + lastName!: string; @IsEmail() - email: string; + email!: string; @IsString() - password: string; + password!: string; @IsString() @IsNotEmpty() @@ -19,5 +19,5 @@ export class SignUpDto { message: 'phone must be a valid phone number (make sure all the digits are correct)', }) - phone: string; + phone!: string; } diff --git a/apps/backend/src/auth/dtos/verify-user.dto.ts b/apps/backend/src/auth/dtos/verify-user.dto.ts index 663916056..b7f300fc6 100644 --- a/apps/backend/src/auth/dtos/verify-user.dto.ts +++ b/apps/backend/src/auth/dtos/verify-user.dto.ts @@ -2,8 +2,8 @@ import { IsEmail, IsString } from 'class-validator'; export class VerifyUserDto { @IsEmail() - email: string; + email!: string; @IsString() - verificationCode: string; + verificationCode!: string; } diff --git a/apps/backend/src/aws/aws-s3.service.ts b/apps/backend/src/aws/aws-s3.service.ts index 045038d52..1035558e8 100644 --- a/apps/backend/src/aws/aws-s3.service.ts +++ b/apps/backend/src/aws/aws-s3.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@nestjs/common'; import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; +import { validateEnv } from '../utils/validation.utils'; @Injectable() export class AWSS3Service { @@ -9,15 +10,15 @@ export class AWSS3Service { constructor() { this.region = process.env.AWS_REGION || 'us-east-2'; - this.bucket = process.env.AWS_BUCKET_NAME; + this.bucket = validateEnv('AWS_BUCKET_NAME'); if (!this.bucket) { throw new Error('AWS_BUCKET_NAME is not defined'); } this.client = new S3Client({ region: this.region, credentials: { - accessKeyId: process.env.AWS_ACCESS_KEY_ID, - secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + accessKeyId: validateEnv('AWS_ACCESS_KEY_ID'), + secretAccessKey: validateEnv('AWS_SECRET_ACCESS_KEY'), }, }); } diff --git a/apps/backend/src/config/migrations.ts b/apps/backend/src/config/migrations.ts index b4c465a2f..efecf4935 100644 --- a/apps/backend/src/config/migrations.ts +++ b/apps/backend/src/config/migrations.ts @@ -29,6 +29,7 @@ import { AddDonationRecurrenceFields1770080947285 } from '../migrations/17700809 import { UpdateManufacturerEntity1768680807820 } from '../migrations/1768680807820-UpdateManufacturerEntity'; import { AddUserPoolId1769189327767 } from '../migrations/1769189327767-AddUserPoolId'; import { UpdateOrderEntity1769990652833 } from '../migrations/1769990652833-UpdateOrderEntity'; +import { DonationItemFoodTypeNotNull1771524930613 } from '../migrations/1771524930613-DonationItemFoodTypeNotNull'; const schemaMigrations = [ User1725726359198, @@ -62,6 +63,7 @@ const schemaMigrations = [ UpdateManufacturerEntity1768680807820, AddUserPoolId1769189327767, UpdateOrderEntity1769990652833, + DonationItemFoodTypeNotNull1771524930613, ]; export default schemaMigrations; diff --git a/apps/backend/src/donationItems/donationItems.entity.ts b/apps/backend/src/donationItems/donationItems.entity.ts index bd9a50982..b787e18ae 100644 --- a/apps/backend/src/donationItems/donationItems.entity.ts +++ b/apps/backend/src/donationItems/donationItems.entity.ts @@ -13,39 +13,38 @@ import { FoodType } from './types'; @Entity('donation_items') export class DonationItem { @PrimaryGeneratedColumn({ name: 'item_id' }) - itemId: number; + itemId!: number; @Column({ name: 'donation_id', type: 'int' }) - donationId: number; + donationId!: number; @ManyToOne(() => Donation, { nullable: false }) @JoinColumn({ name: 'donation_id', referencedColumnName: 'donationId' }) - donation: Donation; + donation!: Donation; @Column({ name: 'item_name', type: 'varchar', length: 255 }) - itemName: string; + itemName!: string; @Column({ name: 'quantity', type: 'int' }) - quantity: number; + quantity!: number; @Column({ name: 'reserved_quantity', type: 'int', default: 0 }) - reservedQuantity: number; + reservedQuantity!: number; @Column({ name: 'oz_per_item', type: 'int', nullable: true }) - ozPerItem: number; + ozPerItem!: number | null; @Column({ name: 'estimated_value', type: 'int', nullable: true }) - estimatedValue: number; + estimatedValue!: number | null; @Column({ name: 'food_type', type: 'enum', enum: FoodType, enumName: 'food_type_enum', - nullable: true, }) - foodType: FoodType; + foodType!: FoodType; @OneToMany(() => Allocation, (allocation) => allocation.item) - allocations: Allocation[]; + allocations!: Allocation[]; } diff --git a/apps/backend/src/donationItems/dtos/create-donation-items.dto.ts b/apps/backend/src/donationItems/dtos/create-donation-items.dto.ts index 11a63d771..87476a3b3 100644 --- a/apps/backend/src/donationItems/dtos/create-donation-items.dto.ts +++ b/apps/backend/src/donationItems/dtos/create-donation-items.dto.ts @@ -15,34 +15,34 @@ export class CreateDonationItemDto { @IsString() @IsNotEmpty() @Length(1, 255) - itemName: string; + itemName!: string; @IsNumber() @Min(1) - quantity: number; + quantity!: number; @IsNumber() @Min(0) - reservedQuantity: number; + reservedQuantity!: number; @IsNumber() @Min(1) - ozPerItem: number; + ozPerItem!: number; @IsNumber() @Min(1) - estimatedValue: number; + estimatedValue!: number; @IsEnum(FoodType) - foodType: FoodType; + foodType!: FoodType; } export class CreateMultipleDonationItemsDto { @IsNumber() - donationId: number; + donationId!: number; @IsArray() @ValidateNested({ each: true }) @Type(() => CreateDonationItemDto) - items: CreateDonationItemDto[]; + items!: CreateDonationItemDto[]; } diff --git a/apps/backend/src/donations/donations.entity.ts b/apps/backend/src/donations/donations.entity.ts index 854401b3c..daa5659c7 100644 --- a/apps/backend/src/donations/donations.entity.ts +++ b/apps/backend/src/donations/donations.entity.ts @@ -37,13 +37,13 @@ export class Donation { status!: DonationStatus; @Column({ name: 'total_items', type: 'int', nullable: true }) - totalItems?: number; + totalItems!: number | null; @Column({ name: 'total_oz', type: 'numeric', nullable: true }) - totalOz?: number; + totalOz!: number | null; @Column({ name: 'total_estimated_value', type: 'numeric', nullable: true }) - totalEstimatedValue?: number; + totalEstimatedValue!: number | null; @Column({ name: 'recurrence', @@ -55,7 +55,7 @@ export class Donation { recurrence!: RecurrenceEnum; @Column({ name: 'recurrence_freq', type: 'int', nullable: true }) - recurrenceFreq?: number; + recurrenceFreq!: number | null; @Column({ name: 'next_donation_dates', @@ -63,8 +63,8 @@ export class Donation { array: true, nullable: true, }) - nextDonationDates?: Date[]; + nextDonationDates!: Date[] | null; @Column({ name: 'occurrences_remaining', type: 'int', nullable: true }) - occurrencesRemaining?: number; + occurrencesRemaining!: number | null; } diff --git a/apps/backend/src/foodManufacturers/dtos/manufacturer-application.dto.ts b/apps/backend/src/foodManufacturers/dtos/manufacturer-application.dto.ts index a6d4bbbae..556e6910a 100644 --- a/apps/backend/src/foodManufacturers/dtos/manufacturer-application.dto.ts +++ b/apps/backend/src/foodManufacturers/dtos/manufacturer-application.dto.ts @@ -16,27 +16,27 @@ export class FoodManufacturerApplicationDto { @IsString() @IsNotEmpty() @Length(1, 255) - foodManufacturerName: string; + foodManufacturerName!: string; @IsString() @IsNotEmpty() @Length(1, 255) - foodManufacturerWebsite: string; + foodManufacturerWebsite!: string; @IsString() @IsNotEmpty() @Length(1, 255) - contactFirstName: string; + contactFirstName!: string; @IsString() @IsNotEmpty() @Length(1, 255) - contactLastName: string; + contactLastName!: string; @IsEmail() @IsNotEmpty() @Length(1, 255) - contactEmail: string; + contactEmail!: string; @IsString() @IsNotEmpty() @@ -44,7 +44,7 @@ export class FoodManufacturerApplicationDto { message: 'contactPhone must be a valid phone number (make sure all the digits are correct)', }) - contactPhone: string; + contactPhone!: string; @IsOptional() @IsString() @@ -75,27 +75,27 @@ export class FoodManufacturerApplicationDto { @ArrayNotEmpty() @IsEnum(Allergen, { each: true }) - unlistedProductAllergens: Allergen[]; + unlistedProductAllergens!: Allergen[]; @ArrayNotEmpty() @IsEnum(Allergen, { each: true }) - facilityFreeAllergens: Allergen[]; + facilityFreeAllergens!: Allergen[]; @IsBoolean() - productsGlutenFree: boolean; + productsGlutenFree!: boolean; @IsBoolean() - productsContainSulfites: boolean; + productsContainSulfites!: boolean; @IsString() @IsNotEmpty() - productsSustainableExplanation: string; + productsSustainableExplanation!: string; @IsBoolean() - inKindDonations: boolean; + inKindDonations!: boolean; @IsEnum(DonateWastedFood) - donateWastedFood: DonateWastedFood; + donateWastedFood!: DonateWastedFood; @IsOptional() @IsEnum(ManufacturerAttribute) diff --git a/apps/backend/src/foodManufacturers/manufacturers.entity.ts b/apps/backend/src/foodManufacturers/manufacturers.entity.ts index aa52ce89b..8d3510520 100644 --- a/apps/backend/src/foodManufacturers/manufacturers.entity.ts +++ b/apps/backend/src/foodManufacturers/manufacturers.entity.ts @@ -39,7 +39,7 @@ export class FoodManufacturer { length: 255, nullable: true, }) - secondaryContactFirstName?: string; + secondaryContactFirstName!: string | null; @Column({ name: 'secondary_contact_last_name', @@ -47,7 +47,7 @@ export class FoodManufacturer { length: 255, nullable: true, }) - secondaryContactLastName?: string; + secondaryContactLastName!: string | null; @Column({ name: 'secondary_contact_email', @@ -55,7 +55,7 @@ export class FoodManufacturer { length: 255, nullable: true, }) - secondaryContactEmail?: string; + secondaryContactEmail!: string | null; @Column({ name: 'secondary_contact_phone', @@ -63,7 +63,7 @@ export class FoodManufacturer { length: 20, nullable: true, }) - secondaryContactPhone?: string; + secondaryContactPhone!: string | null; @Column({ name: 'unlisted_product_allergens', @@ -113,17 +113,17 @@ export class FoodManufacturer { enumName: 'manufacturer_attribute_enum', nullable: true, }) - manufacturerAttribute?: ManufacturerAttribute; + manufacturerAttribute!: ManufacturerAttribute | null; @Column({ name: 'additional_comments', type: 'text', nullable: true, }) - additionalComments?: string; + additionalComments!: string | null; @Column({ name: 'newsletter_subscription', type: 'boolean', nullable: true }) - newsletterSubscription?: boolean; + newsletterSubscription!: boolean | null; @OneToMany(() => Donation, (donation) => donation.foodManufacturer) donations!: Donation[]; diff --git a/apps/backend/src/foodManufacturers/manufacturers.service.ts b/apps/backend/src/foodManufacturers/manufacturers.service.ts index 22cf3e3c6..d6a3b6156 100644 --- a/apps/backend/src/foodManufacturers/manufacturers.service.ts +++ b/apps/backend/src/foodManufacturers/manufacturers.service.ts @@ -54,13 +54,13 @@ export class FoodManufacturersService { // secondary contact information foodManufacturer.secondaryContactFirstName = - foodManufacturerData.secondaryContactFirstName; + foodManufacturerData.secondaryContactFirstName ?? null; foodManufacturer.secondaryContactLastName = - foodManufacturerData.secondaryContactLastName; + foodManufacturerData.secondaryContactLastName ?? null; foodManufacturer.secondaryContactEmail = - foodManufacturerData.secondaryContactEmail; + foodManufacturerData.secondaryContactEmail ?? null; foodManufacturer.secondaryContactPhone = - foodManufacturerData.secondaryContactPhone; + foodManufacturerData.secondaryContactPhone ?? null; // food manufacturer details information foodManufacturer.foodManufacturerName = @@ -80,11 +80,11 @@ export class FoodManufacturersService { foodManufacturer.inKindDonations = foodManufacturerData.inKindDonations; foodManufacturer.donateWastedFood = foodManufacturerData.donateWastedFood; foodManufacturer.manufacturerAttribute = - foodManufacturerData.manufacturerAttribute; + foodManufacturerData.manufacturerAttribute ?? null; foodManufacturer.additionalComments = - foodManufacturerData.additionalComments; + foodManufacturerData.additionalComments ?? null; foodManufacturer.newsletterSubscription = - foodManufacturerData.newsletterSubscription; + foodManufacturerData.newsletterSubscription ?? null; await this.repo.save(foodManufacturer); } diff --git a/apps/backend/src/foodRequests/dtos/create-request.dto.ts b/apps/backend/src/foodRequests/dtos/create-request.dto.ts new file mode 100644 index 000000000..9515bfcd8 --- /dev/null +++ b/apps/backend/src/foodRequests/dtos/create-request.dto.ts @@ -0,0 +1,27 @@ +import { + ArrayNotEmpty, + IsEnum, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, +} from 'class-validator'; +import { RequestSize } from '../types'; +import { FoodType } from '../../donationItems/types'; + +export class CreateRequestDto { + @IsNumber() + pantryId!: number; + + @IsEnum(RequestSize) + requestedSize!: RequestSize; + + @ArrayNotEmpty() + @IsEnum(FoodType, { each: true }) + requestedItems!: FoodType[]; + + @IsOptional() + @IsString() + @IsNotEmpty() + additionalInformation?: string; +} diff --git a/apps/backend/src/foodRequests/dtos/order-details.dto.ts b/apps/backend/src/foodRequests/dtos/order-details.dto.ts index 21d360ec8..392c5e420 100644 --- a/apps/backend/src/foodRequests/dtos/order-details.dto.ts +++ b/apps/backend/src/foodRequests/dtos/order-details.dto.ts @@ -2,14 +2,14 @@ import { FoodType } from '../../donationItems/types'; import { OrderStatus } from '../../orders/types'; export class OrderItemDetailsDto { - name: string; - quantity: number; - foodType: FoodType; + name!: string; + quantity!: number; + foodType!: FoodType; } export class OrderDetailsDto { - orderId: number; - status: OrderStatus; - foodManufacturerName: string; - items: OrderItemDetailsDto[]; + orderId!: number; + status!: OrderStatus; + foodManufacturerName!: string; + items!: OrderItemDetailsDto[]; } diff --git a/apps/backend/src/foodRequests/request.controller.spec.ts b/apps/backend/src/foodRequests/request.controller.spec.ts index de62ab829..3957ca41c 100644 --- a/apps/backend/src/foodRequests/request.controller.spec.ts +++ b/apps/backend/src/foodRequests/request.controller.spec.ts @@ -10,6 +10,7 @@ import { RequestSize } from './types'; import { OrderStatus } from '../orders/types'; import { FoodType } from '../donationItems/types'; import { OrderDetailsDto } from './dtos/order-details.dto'; +import { CreateRequestDto } from './dtos/create-request.dto'; import { Order } from '../orders/order.entity'; const mockRequestsService = mock(); @@ -146,14 +147,14 @@ describe('RequestsController', () => { describe('POST /create', () => { it('should call requestsService.create and return the created food request', async () => { - const createBody: Partial = { + const createBody = { pantryId: 1, requestedSize: RequestSize.MEDIUM, - requestedItems: ['Test item 1', 'Test item 2'], + requestedItems: [ + FoodType.DAIRY_FREE_ALTERNATIVES, + FoodType.DRIED_BEANS, + ], additionalInformation: 'Test information.', - dateReceived: null, - feedback: null, - photos: null, }; const createdRequest: Partial = { @@ -167,7 +168,7 @@ describe('RequestsController', () => { createdRequest as FoodRequest, ); - const result = await controller.createRequest(createBody as FoodRequest); + const result = await controller.createRequest(createBody); expect(result).toEqual(createdRequest); expect(mockRequestsService.create).toHaveBeenCalledWith( @@ -175,9 +176,6 @@ describe('RequestsController', () => { createBody.requestedSize, createBody.requestedItems, createBody.additionalInformation, - createBody.dateReceived, - createBody.feedback, - createBody.photos, ); }); }); diff --git a/apps/backend/src/foodRequests/request.controller.ts b/apps/backend/src/foodRequests/request.controller.ts index 230eb0c48..5d6b69cbe 100644 --- a/apps/backend/src/foodRequests/request.controller.ts +++ b/apps/backend/src/foodRequests/request.controller.ts @@ -7,8 +7,8 @@ import { Body, UploadedFiles, UseInterceptors, - BadRequestException, NotFoundException, + ValidationPipe, } from '@nestjs/common'; import { ApiBody } from '@nestjs/swagger'; import { RequestsService } from './request.service'; @@ -22,6 +22,7 @@ import { OrdersService } from '../orders/order.service'; import { RequestSize } from './types'; import { OrderStatus } from '../orders/types'; import { OrderDetailsDto } from './dtos/order-details.dto'; +import { CreateRequestDto } from './dtos/create-request.dto'; @Controller('requests') export class RequestsController { @@ -93,30 +94,14 @@ export class RequestsController { }, }) async createRequest( - @Body() - body: { - pantryId: number; - requestedSize: RequestSize; - requestedItems: string[]; - additionalInformation: string; - dateReceived: Date; - feedback: string; - photos: string[]; - }, + @Body(new ValidationPipe()) + requestData: CreateRequestDto, ): Promise { - if ( - !Object.values(RequestSize).includes(body.requestedSize as RequestSize) - ) { - throw new BadRequestException('Invalid request size'); - } return this.requestsService.create( - body.pantryId, - body.requestedSize, - body.requestedItems, - body.additionalInformation, - body.dateReceived, - body.feedback, - body.photos, + requestData.pantryId, + requestData.requestedSize, + requestData.requestedItems, + requestData.additionalInformation, ); } diff --git a/apps/backend/src/foodRequests/request.entity.ts b/apps/backend/src/foodRequests/request.entity.ts index 25ba8e66b..aef43a7c7 100644 --- a/apps/backend/src/foodRequests/request.entity.ts +++ b/apps/backend/src/foodRequests/request.entity.ts @@ -14,14 +14,14 @@ import { Pantry } from '../pantries/pantries.entity'; @Entity('food_requests') export class FoodRequest { @PrimaryGeneratedColumn({ name: 'request_id' }) - requestId: number; + requestId!: number; @Column({ name: 'pantry_id', type: 'int' }) - pantryId: number; + pantryId!: number; @ManyToOne(() => Pantry, { nullable: false }) @JoinColumn({ name: 'pantry_id', referencedColumnName: 'pantryId' }) - pantry: Pantry; + pantry!: Pantry; @Column({ name: 'requested_size', @@ -29,30 +29,30 @@ export class FoodRequest { enum: RequestSize, enumName: 'request_size_enum', }) - requestedSize: RequestSize; + requestedSize!: RequestSize; @Column({ name: 'requested_items', type: 'text', array: true }) - requestedItems: string[]; + requestedItems!: string[]; @Column({ name: 'additional_information', type: 'text', nullable: true }) - additionalInformation: string; + additionalInformation!: string | null; @CreateDateColumn({ name: 'requested_at', type: 'timestamp', default: () => 'NOW()', }) - requestedAt: Date; + requestedAt!: Date; @Column({ name: 'date_received', type: 'timestamp', nullable: true }) - dateReceived: Date; + dateReceived!: Date | null; @Column({ name: 'feedback', type: 'text', nullable: true }) - feedback: string; + feedback!: string | null; @Column({ name: 'photos', type: 'text', array: true, nullable: true }) - photos: string[]; + photos!: string[] | null; @OneToMany(() => Order, (order) => order.request, { nullable: true }) - orders: Order[]; + orders!: Order[] | null; } diff --git a/apps/backend/src/foodRequests/request.service.spec.ts b/apps/backend/src/foodRequests/request.service.spec.ts index 1eb21b692..f60d2ad82 100644 --- a/apps/backend/src/foodRequests/request.service.spec.ts +++ b/apps/backend/src/foodRequests/request.service.spec.ts @@ -17,12 +17,14 @@ const mockRequestsRepository = mock>(); const mockPantryRepository = mock>(); const mockOrdersRepository = mock>(); -const mockRequest: Partial = { +const mockRequest: FoodRequest = { requestId: 1, pantryId: 1, requestedItems: ['Canned Goods', 'Vegetables'], additionalInformation: 'No onions, please.', - requestedAt: null, + requestedAt: new Date(), + requestedSize: RequestSize.LARGE, + pantry: new Pantry(), dateReceived: null, feedback: null, photos: null, @@ -250,9 +252,6 @@ describe('RequestsService', () => { mockRequest.requestedSize, mockRequest.requestedItems, mockRequest.additionalInformation, - mockRequest.dateReceived, - mockRequest.feedback, - mockRequest.photos, ); expect(result).toEqual(mockRequest); @@ -261,9 +260,6 @@ describe('RequestsService', () => { requestedSize: mockRequest.requestedSize, requestedItems: mockRequest.requestedItems, additionalInformation: mockRequest.additionalInformation, - dateReceived: mockRequest.dateReceived, - feedback: mockRequest.feedback, - photos: mockRequest.photos, }); expect(mockRequestsRepository.save).toHaveBeenCalledWith(mockRequest); }); @@ -277,9 +273,6 @@ describe('RequestsService', () => { RequestSize.MEDIUM, ['Canned Goods', 'Vegetables'], 'Additional info', - null, - null, - null, ), ).rejects.toThrow(`Pantry ${invalidPantryId} not found`); @@ -298,7 +291,7 @@ describe('RequestsService', () => { requestedSize: RequestSize.LARGE, requestedItems: ['Rice', 'Beans'], additionalInformation: 'Gluten-free items only.', - requestedAt: null, + requestedAt: undefined, dateReceived: null, feedback: null, photos: null, @@ -310,7 +303,7 @@ describe('RequestsService', () => { requestedSize: RequestSize.SMALL, requestedItems: ['Fruits', 'Snacks'], additionalInformation: 'No nuts, please.', - requestedAt: null, + requestedAt: undefined, dateReceived: null, feedback: null, photos: null, @@ -336,7 +329,7 @@ describe('RequestsService', () => { it('should update and return the food request with new delivery details', async () => { const mockOrder: Partial = { orderId: 1, - request: null, + request: undefined, status: OrderStatus.SHIPPED, createdAt: new Date(), shippedAt: new Date(), diff --git a/apps/backend/src/foodRequests/request.service.ts b/apps/backend/src/foodRequests/request.service.ts index c74b2f878..d57338fc3 100644 --- a/apps/backend/src/foodRequests/request.service.ts +++ b/apps/backend/src/foodRequests/request.service.ts @@ -77,10 +77,7 @@ export class RequestsService { pantryId: number, requestedSize: RequestSize, requestedItems: string[], - additionalInformation: string | undefined, - dateReceived: Date | undefined, - feedback: string | undefined, - photos: string[] | undefined, + additionalInformation: string | undefined | null, ): Promise { validateId(pantryId, 'Pantry'); @@ -94,9 +91,6 @@ export class RequestsService { requestedSize, requestedItems, additionalInformation, - dateReceived, - feedback, - photos, }); return await this.repo.save(foodRequest); diff --git a/apps/backend/src/migrations/1771524930613-DonationItemFoodTypeNotNull.ts b/apps/backend/src/migrations/1771524930613-DonationItemFoodTypeNotNull.ts new file mode 100644 index 000000000..5041c50a2 --- /dev/null +++ b/apps/backend/src/migrations/1771524930613-DonationItemFoodTypeNotNull.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class DonationItemFoodTypeNotNull1771524930613 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE donation_items + ALTER COLUMN food_type SET NOT NULL; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE donation_items + ALTER COLUMN food_type DROP NOT NULL; + `); + } +} diff --git a/apps/backend/src/orders/order.entity.ts b/apps/backend/src/orders/order.entity.ts index 2913ff150..fa389f7ec 100644 --- a/apps/backend/src/orders/order.entity.ts +++ b/apps/backend/src/orders/order.entity.ts @@ -58,14 +58,14 @@ export class Order { type: 'timestamp', nullable: true, }) - shippedAt?: Date; + shippedAt!: Date | null; @Column({ name: 'delivered_at', type: 'timestamp', nullable: true, }) - deliveredAt?: Date; + deliveredAt!: Date | null; @OneToMany(() => Allocation, (allocation) => allocation.order) allocations!: Allocation[]; @@ -76,7 +76,7 @@ export class Order { length: 255, nullable: true, }) - trackingLink?: string; + trackingLink!: string; @Column({ name: 'shipping_cost', @@ -85,5 +85,5 @@ export class Order { scale: 2, nullable: true, }) - shippingCost?: number; + shippingCost!: number; } diff --git a/apps/backend/src/orders/order.module.ts b/apps/backend/src/orders/order.module.ts index 0734f8760..1f435f438 100644 --- a/apps/backend/src/orders/order.module.ts +++ b/apps/backend/src/orders/order.module.ts @@ -3,8 +3,6 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { OrdersController } from './order.controller'; import { Order } from './order.entity'; import { OrdersService } from './order.service'; -import { JwtStrategy } from '../auth/jwt.strategy'; -import { AuthService } from '../auth/auth.service'; import { Pantry } from '../pantries/pantries.entity'; import { AllocationModule } from '../allocations/allocations.module'; import { AuthModule } from '../auth/auth.module'; diff --git a/apps/backend/src/orders/order.service.ts b/apps/backend/src/orders/order.service.ts index b7af3beb0..36160d6ba 100644 --- a/apps/backend/src/orders/order.service.ts +++ b/apps/backend/src/orders/order.service.ts @@ -103,6 +103,10 @@ export class OrdersService { pantryId: request.pantryId, }); + if (!pantry) { + throw new NotFoundException(`Pantry ${request.pantryId} not found`); + } + return pantry; } diff --git a/apps/backend/src/pantries/dtos/pantry-application.dto.ts b/apps/backend/src/pantries/dtos/pantry-application.dto.ts index 09943e60e..ea0f0ae26 100644 --- a/apps/backend/src/pantries/dtos/pantry-application.dto.ts +++ b/apps/backend/src/pantries/dtos/pantry-application.dto.ts @@ -23,17 +23,17 @@ export class PantryApplicationDto { @IsString() @IsNotEmpty() @Length(1, 255) - contactFirstName: string; + contactFirstName!: string; @IsString() @IsNotEmpty() @Length(1, 255) - contactLastName: string; + contactLastName!: string; @IsEmail() @IsNotEmpty() @Length(1, 255) - contactEmail: string; + contactEmail!: string; // This validation is very strict and won't accept phone numbers // that look right but aren't actually possible phone numbers @@ -43,10 +43,10 @@ export class PantryApplicationDto { message: 'contactPhone must be a valid phone number (make sure all the digits are correct)', }) - contactPhone: string; + contactPhone!: string; @IsBoolean() - hasEmailContact: boolean; + hasEmailContact!: boolean; @IsOptional() @IsString() @@ -83,12 +83,12 @@ export class PantryApplicationDto { @IsString() @IsNotEmpty() @Length(1, 255) - pantryName: string; + pantryName!: string; @IsString() @IsNotEmpty() @Length(1, 255) - shipmentAddressLine1: string; + shipmentAddressLine1!: string; @IsOptional() @IsString() @@ -99,17 +99,17 @@ export class PantryApplicationDto { @IsString() @IsNotEmpty() @Length(1, 255) - shipmentAddressCity: string; + shipmentAddressCity!: string; @IsString() @IsNotEmpty() @Length(1, 255) - shipmentAddressState: string; + shipmentAddressState!: string; @IsString() @IsNotEmpty() @Length(1, 255) - shipmentAddressZip: string; + shipmentAddressZip!: string; @IsOptional() @IsString() @@ -120,7 +120,7 @@ export class PantryApplicationDto { @IsString() @IsNotEmpty() @Length(1, 255) - mailingAddressLine1: string; + mailingAddressLine1!: string; @IsOptional() @IsString() @@ -131,17 +131,17 @@ export class PantryApplicationDto { @IsString() @IsNotEmpty() @Length(1, 255) - mailingAddressCity: string; + mailingAddressCity!: string; @IsString() @IsNotEmpty() @Length(1, 255) - mailingAddressState: string; + mailingAddressState!: string; @IsString() @IsNotEmpty() @Length(1, 255) - mailingAddressZip: string; + mailingAddressZip!: string; @IsOptional() @IsString() @@ -152,19 +152,18 @@ export class PantryApplicationDto { @IsString() @IsNotEmpty() @Length(1, 25) - allergenClients: string; + allergenClients!: string; - @IsOptional() @IsString({ each: true }) @IsNotEmpty({ each: true }) @MaxLength(255, { each: true }) - restrictions?: string[]; + restrictions!: string[]; @IsEnum(RefrigeratedDonation) - refrigeratedDonation: RefrigeratedDonation; + refrigeratedDonation!: RefrigeratedDonation; @IsBoolean() - acceptFoodDeliveries: boolean; + acceptFoodDeliveries!: boolean; @IsOptional() @IsString() @@ -172,7 +171,7 @@ export class PantryApplicationDto { deliveryWindowInstructions?: string; @IsEnum(ReserveFoodForAllergic) - reserveFoodForAllergic: ReserveFoodForAllergic; + reserveFoodForAllergic!: ReserveFoodForAllergic; // TODO: Really, this validation should be different depending on the value of reserveFoodForAllergic @IsOptional() @@ -181,7 +180,7 @@ export class PantryApplicationDto { reservationExplanation?: string; @IsBoolean() - dedicatedAllergyFriendly: boolean; + dedicatedAllergyFriendly!: boolean; @IsOptional() @IsEnum(ClientVisitFrequency) @@ -197,7 +196,7 @@ export class PantryApplicationDto { @ArrayNotEmpty() @IsEnum(Activity, { each: true }) - activities: Activity[]; + activities!: Activity[]; @IsOptional() @IsString() @@ -208,12 +207,12 @@ export class PantryApplicationDto { @IsString() @IsNotEmpty() @Length(1, 255) - itemsInStock: string; + itemsInStock!: string; @IsString() @IsNotEmpty() @Length(1, 255) - needMoreOptions: string; + needMoreOptions!: string; @IsOptional() @IsBoolean() diff --git a/apps/backend/src/pantries/pantries.controller.spec.ts b/apps/backend/src/pantries/pantries.controller.spec.ts index 96828a911..925948218 100644 --- a/apps/backend/src/pantries/pantries.controller.spec.ts +++ b/apps/backend/src/pantries/pantries.controller.spec.ts @@ -17,6 +17,7 @@ import { import { ApplicationStatus } from '../shared/types'; import { NotFoundException, UnauthorizedException } from '@nestjs/common'; import { User } from '../users/user.entity'; +import { AuthenticatedRequest } from '../auth/authenticated-request'; const mockPantriesService = mock(); const mockOrdersService = mock(); @@ -38,7 +39,7 @@ describe('PantriesController', () => { contactEmail: 'jane.smith@example.com', contactPhone: '(508) 222-2222', hasEmailContact: true, - emailContactOther: null, + emailContactOther: undefined, secondaryContactFirstName: 'John', secondaryContactLastName: 'Doe', secondaryContactEmail: 'john.doe@example.com', @@ -253,16 +254,18 @@ describe('PantriesController', () => { const pantry: Partial = { pantryId: 10 }; mockPantriesService.findByUserId.mockResolvedValueOnce(pantry as Pantry); - const result = await controller.getCurrentUserPantryId(req); + const result = await controller.getCurrentUserPantryId( + req as AuthenticatedRequest, + ); expect(result).toEqual(10); expect(mockPantriesService.findByUserId).toHaveBeenCalledWith(1); }); it('throws UnauthorizedException when unauthenticated', async () => { - await expect(controller.getCurrentUserPantryId({})).rejects.toThrow( - new UnauthorizedException('Not authenticated'), - ); + await expect( + controller.getCurrentUserPantryId({} as AuthenticatedRequest), + ).rejects.toThrow(new UnauthorizedException('Not authenticated')); }); it('propagates NotFoundException from service', async () => { @@ -271,7 +274,9 @@ describe('PantriesController', () => { new NotFoundException('Pantry for User 999 not found'), ); - const promise = controller.getCurrentUserPantryId(req); + const promise = controller.getCurrentUserPantryId( + req as AuthenticatedRequest, + ); await expect(promise).rejects.toBeInstanceOf(NotFoundException); await expect(promise).rejects.toThrow('Pantry for User 999 not found'); expect(mockPantriesService.findByUserId).toHaveBeenCalledWith(999); diff --git a/apps/backend/src/pantries/pantries.controller.ts b/apps/backend/src/pantries/pantries.controller.ts index 8ed72be20..e8e1f0cb2 100644 --- a/apps/backend/src/pantries/pantries.controller.ts +++ b/apps/backend/src/pantries/pantries.controller.ts @@ -27,6 +27,7 @@ import { import { Order } from '../orders/order.entity'; import { OrdersService } from '../orders/order.service'; import { Public } from '../auth/public.decorator'; +import { AuthenticatedRequest } from '../auth/authenticated-request'; @Controller('pantries') export class PantriesController { @@ -37,12 +38,15 @@ export class PantriesController { @Roles(Role.PANTRY) @Get('/my-id') - async getCurrentUserPantryId(@Req() req): Promise { - const currentUser = req.user; - if (!currentUser) { + async getCurrentUserPantryId( + @Req() req: AuthenticatedRequest | Request, + ): Promise { + if (!('user' in req)) { throw new UnauthorizedException('Not authenticated'); } + const currentUser = req.user; + const pantry = await this.pantriesService.findByUserId(currentUser.id); return pantry.pantryId; } diff --git a/apps/backend/src/pantries/pantries.entity.ts b/apps/backend/src/pantries/pantries.entity.ts index 08767f2c4..292c457b4 100644 --- a/apps/backend/src/pantries/pantries.entity.ts +++ b/apps/backend/src/pantries/pantries.entity.ts @@ -20,13 +20,13 @@ import { ApplicationStatus } from '../shared/types'; @Entity('pantries') export class Pantry { @PrimaryGeneratedColumn({ name: 'pantry_id' }) - pantryId: number; + pantryId!: number; @Column({ name: 'pantry_name', type: 'varchar', length: 255 }) - pantryName: string; + pantryName!: string; @Column({ name: 'shipment_address_line_1', type: 'varchar', length: 255 }) - shipmentAddressLine1: string; + shipmentAddressLine1!: string; @Column({ name: 'shipment_address_line_2', @@ -34,16 +34,16 @@ export class Pantry { length: 255, nullable: true, }) - shipmentAddressLine2?: string; + shipmentAddressLine2!: string | null; @Column({ name: 'shipment_address_city', type: 'varchar', length: 255 }) - shipmentAddressCity: string; + shipmentAddressCity!: string; @Column({ name: 'shipment_address_state', type: 'varchar', length: 255 }) - shipmentAddressState: string; + shipmentAddressState!: string; @Column({ name: 'shipment_address_zip', type: 'varchar', length: 255 }) - shipmentAddressZip: string; + shipmentAddressZip!: string; @Column({ name: 'shipment_address_country', @@ -51,10 +51,10 @@ export class Pantry { length: 255, nullable: true, }) - shipmentAddressCountry?: string; + shipmentAddressCountry!: string | null; @Column({ name: 'mailing_address_line_1', type: 'varchar', length: 255 }) - mailingAddressLine1: string; + mailingAddressLine1!: string; @Column({ name: 'mailing_address_line_2', @@ -62,16 +62,16 @@ export class Pantry { length: 255, nullable: true, }) - mailingAddressLine2?: string; + mailingAddressLine2!: string | null; @Column({ name: 'mailing_address_city', type: 'varchar', length: 255 }) - mailingAddressCity: string; + mailingAddressCity!: string; @Column({ name: 'mailing_address_state', type: 'varchar', length: 255 }) - mailingAddressState: string; + mailingAddressState!: string; @Column({ name: 'mailing_address_zip', type: 'varchar', length: 255 }) - mailingAddressZip: string; + mailingAddressZip!: string; @Column({ name: 'mailing_address_country', @@ -79,10 +79,10 @@ export class Pantry { length: 255, nullable: true, }) - mailingAddressCountry?: string; + mailingAddressCountry!: string | null; @Column({ name: 'allergen_clients', type: 'varchar', length: 25 }) - allergenClients: string; + allergenClients!: string; @Column({ name: 'refrigerated_donation', @@ -90,17 +90,17 @@ export class Pantry { enum: RefrigeratedDonation, enumName: 'refrigerated_donation_enum', }) - refrigeratedDonation: RefrigeratedDonation; + refrigeratedDonation!: RefrigeratedDonation; @Column({ name: 'accept_food_deliveries', type: 'boolean' }) - acceptFoodDeliveries: boolean; + acceptFoodDeliveries!: boolean; @Column({ name: 'delivery_window_instructions', type: 'text', nullable: true, }) - deliveryWindowInstructions?: string; + deliveryWindowInstructions!: string | null; @Column({ name: 'reserve_food_for_allergic', @@ -108,16 +108,16 @@ export class Pantry { enum: ReserveFoodForAllergic, enumName: 'reserve_food_for_allergic_enum', }) - reserveFoodForAllergic: string; + reserveFoodForAllergic!: string; @Column({ name: 'reservation_explanation', type: 'text', nullable: true }) - reservationExplanation?: string; + reservationExplanation!: string | null; @Column({ name: 'dedicated_allergy_friendly', type: 'boolean', }) - dedicatedAllergyFriendly: boolean; + dedicatedAllergyFriendly!: boolean; @Column({ name: 'client_visit_frequency', @@ -126,7 +126,7 @@ export class Pantry { enumName: 'client_visit_frequency_enum', nullable: true, }) - clientVisitFrequency?: ClientVisitFrequency; + clientVisitFrequency!: ClientVisitFrequency | null; @Column({ name: 'identify_allergens_confidence', @@ -135,7 +135,7 @@ export class Pantry { enumName: 'allergens_confidence_enum', nullable: true, }) - identifyAllergensConfidence?: AllergensConfidence; + identifyAllergensConfidence!: AllergensConfidence | null; @Column({ name: 'serve_allergic_children', @@ -144,19 +144,19 @@ export class Pantry { enumName: 'serve_allergic_children_enum', nullable: true, }) - serveAllergicChildren?: ServeAllergicChildren; + serveAllergicChildren!: ServeAllergicChildren | null; @Column({ name: 'newsletter_subscription', type: 'boolean', nullable: true }) - newsletterSubscription?: boolean; + newsletterSubscription!: boolean | null; @Column({ name: 'restrictions', type: 'text', array: true }) - restrictions: string[]; + restrictions!: string[]; @Column({ name: 'has_email_contact', type: 'boolean' }) - hasEmailContact: boolean; + hasEmailContact!: boolean; @Column({ name: 'email_contact_other', type: 'text', nullable: true }) - emailContactOther?: string; + emailContactOther!: string | null; @Column({ name: 'secondary_contact_first_name', @@ -164,7 +164,7 @@ export class Pantry { length: 255, nullable: true, }) - secondaryContactFirstName?: string; + secondaryContactFirstName!: string | null; @Column({ name: 'secondary_contact_last_name', @@ -172,7 +172,7 @@ export class Pantry { length: 255, nullable: true, }) - secondaryContactLastName?: string; + secondaryContactLastName!: string | null; @Column({ name: 'secondary_contact_email', @@ -180,7 +180,7 @@ export class Pantry { length: 255, nullable: true, }) - secondaryContactEmail?: string; + secondaryContactEmail!: string | null; @Column({ name: 'secondary_contact_phone', @@ -188,7 +188,7 @@ export class Pantry { length: 20, nullable: true, }) - secondaryContactPhone?: string; + secondaryContactPhone!: string | null; // cascade: ['insert'] means that when we create a new // pantry, the pantry user will automatically be added @@ -202,7 +202,7 @@ export class Pantry { name: 'pantry_user_id', referencedColumnName: 'id', }) - pantryUser: User; + pantryUser!: User; @Column({ name: 'status', @@ -210,14 +210,14 @@ export class Pantry { enum: ApplicationStatus, enumName: 'application_status_enum', }) - status: ApplicationStatus; + status!: ApplicationStatus; @Column({ name: 'date_applied', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', }) - dateApplied: Date; + dateApplied!: Date; @Column({ name: 'activities', @@ -226,17 +226,17 @@ export class Pantry { enumName: 'activity_enum', array: true, }) - activities: Activity[]; + activities!: Activity[]; @Column({ name: 'activities_comments', type: 'text', nullable: true }) - activitiesComments?: string; + activitiesComments!: string | null; @Column({ name: 'items_in_stock', type: 'text' }) - itemsInStock: string; + itemsInStock!: string; @Column({ name: 'need_more_options', type: 'text' }) - needMoreOptions: string; + needMoreOptions!: string; @ManyToMany(() => User, (user) => user.pantries) - volunteers?: User[]; + volunteers!: User[] | null; } diff --git a/apps/backend/src/pantries/pantries.service.spec.ts b/apps/backend/src/pantries/pantries.service.spec.ts index 1b54f4f32..8163c1ebc 100644 --- a/apps/backend/src/pantries/pantries.service.spec.ts +++ b/apps/backend/src/pantries/pantries.service.spec.ts @@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { PantriesService } from './pantries.service'; import { getRepositoryToken } from '@nestjs/typeorm'; import { Pantry } from './pantries.entity'; -import { Repository } from 'typeorm'; +import { Repository, UpdateResult } from 'typeorm'; import { NotFoundException } from '@nestjs/common'; import { mock } from 'jest-mock-extended'; import { PantryApplicationDto } from './dtos/pantry-application.dto'; @@ -35,7 +35,7 @@ describe('PantriesService', () => { contactEmail: 'jane.smith@example.com', contactPhone: '(508) 222-2222', hasEmailContact: true, - emailContactOther: null, + emailContactOther: undefined, secondaryContactFirstName: 'John', secondaryContactLastName: 'Doe', secondaryContactEmail: 'john.doe@example.com', @@ -164,7 +164,7 @@ describe('PantriesService', () => { describe('approve', () => { it('should approve a pantry', async () => { mockRepository.findOne.mockResolvedValueOnce(mockPendingPantry); - mockRepository.update.mockResolvedValueOnce(undefined); + mockRepository.update.mockResolvedValueOnce({} as UpdateResult); await service.approve(1); @@ -191,7 +191,7 @@ describe('PantriesService', () => { describe('deny', () => { it('should deny a pantry', async () => { mockRepository.findOne.mockResolvedValueOnce(mockPendingPantry); - mockRepository.update.mockResolvedValueOnce(undefined); + mockRepository.update.mockResolvedValueOnce({} as UpdateResult); await service.deny(1); diff --git a/apps/backend/src/pantries/pantries.service.ts b/apps/backend/src/pantries/pantries.service.ts index 24238e927..8755c4199 100644 --- a/apps/backend/src/pantries/pantries.service.ts +++ b/apps/backend/src/pantries/pantries.service.ts @@ -46,29 +46,31 @@ export class PantriesService { pantry.pantryUser = pantryContact; pantry.hasEmailContact = pantryData.hasEmailContact; - pantry.emailContactOther = pantryData.emailContactOther; + pantry.emailContactOther = pantryData.emailContactOther ?? null; // secondary contact information - pantry.secondaryContactFirstName = pantryData.secondaryContactFirstName; - pantry.secondaryContactLastName = pantryData.secondaryContactLastName; - pantry.secondaryContactEmail = pantryData.secondaryContactEmail; - pantry.secondaryContactPhone = pantryData.secondaryContactPhone; + pantry.secondaryContactFirstName = + pantryData.secondaryContactFirstName ?? null; + pantry.secondaryContactLastName = + pantryData.secondaryContactLastName ?? null; + pantry.secondaryContactEmail = pantryData.secondaryContactEmail ?? null; + pantry.secondaryContactPhone = pantryData.secondaryContactPhone ?? null; // food shipment address information pantry.shipmentAddressLine1 = pantryData.shipmentAddressLine1; - pantry.shipmentAddressLine2 = pantryData.shipmentAddressLine2; + pantry.shipmentAddressLine2 = pantryData.shipmentAddressLine2 ?? null; pantry.shipmentAddressCity = pantryData.shipmentAddressCity; pantry.shipmentAddressState = pantryData.shipmentAddressState; pantry.shipmentAddressZip = pantryData.shipmentAddressZip; - pantry.shipmentAddressCountry = pantryData.shipmentAddressCountry; + pantry.shipmentAddressCountry = pantryData.shipmentAddressCountry ?? null; // mailing address information pantry.mailingAddressLine1 = pantryData.mailingAddressLine1; - pantry.mailingAddressLine2 = pantryData.mailingAddressLine2; + pantry.mailingAddressLine2 = pantryData.mailingAddressLine2 ?? null; pantry.mailingAddressCity = pantryData.mailingAddressCity; pantry.mailingAddressState = pantryData.mailingAddressState; pantry.mailingAddressZip = pantryData.mailingAddressZip; - pantry.mailingAddressCountry = pantryData.mailingAddressCountry; + pantry.mailingAddressCountry = pantryData.mailingAddressCountry ?? null; // pantry details information pantry.pantryName = pantryData.pantryName; @@ -77,15 +79,16 @@ export class PantriesService { pantry.refrigeratedDonation = pantryData.refrigeratedDonation; pantry.dedicatedAllergyFriendly = pantryData.dedicatedAllergyFriendly; pantry.reserveFoodForAllergic = pantryData.reserveFoodForAllergic; - pantry.reservationExplanation = pantryData.reservationExplanation; - pantry.clientVisitFrequency = pantryData.clientVisitFrequency; - pantry.identifyAllergensConfidence = pantryData.identifyAllergensConfidence; - pantry.serveAllergicChildren = pantryData.serveAllergicChildren; + pantry.reservationExplanation = pantryData.reservationExplanation ?? null; + pantry.clientVisitFrequency = pantryData.clientVisitFrequency ?? null; + pantry.identifyAllergensConfidence = + pantryData.identifyAllergensConfidence ?? null; + pantry.serveAllergicChildren = pantryData.serveAllergicChildren ?? null; pantry.activities = pantryData.activities; - pantry.activitiesComments = pantryData.activitiesComments; + pantry.activitiesComments = pantryData.activitiesComments ?? null; pantry.itemsInStock = pantryData.itemsInStock; pantry.needMoreOptions = pantryData.needMoreOptions; - pantry.newsletterSubscription = pantryData.newsletterSubscription; + pantry.newsletterSubscription = pantryData.newsletterSubscription ?? null; // pantry contact is automatically added to User table await this.repo.save(pantry); diff --git a/apps/backend/src/users/dtos/userSchema.dto.ts b/apps/backend/src/users/dtos/userSchema.dto.ts index ac8cd1ec1..2f110c0bd 100644 --- a/apps/backend/src/users/dtos/userSchema.dto.ts +++ b/apps/backend/src/users/dtos/userSchema.dto.ts @@ -12,17 +12,17 @@ export class userSchemaDto { @IsEmail() @IsNotEmpty() @Length(1, 255) - email: string; + email!: string; @IsString() @IsNotEmpty() @Length(1, 255) - firstName: string; + firstName!: string; @IsString() @IsNotEmpty() @Length(1, 255) - lastName: string; + lastName!: string; @IsString() @IsNotEmpty() @@ -30,8 +30,8 @@ export class userSchemaDto { message: 'phone must be a valid phone number (make sure all the digits are correct)', }) - phone: string; + phone!: string; @IsEnum(Role) - role: Role; + role!: Role; } diff --git a/apps/backend/src/users/user.entity.ts b/apps/backend/src/users/user.entity.ts index 4481b22dc..14641579e 100644 --- a/apps/backend/src/users/user.entity.ts +++ b/apps/backend/src/users/user.entity.ts @@ -12,7 +12,7 @@ import { Pantry } from '../pantries/pantries.entity'; @Entity() export class User { @PrimaryGeneratedColumn({ name: 'user_id' }) - id: number; + id!: number; @Column({ type: 'enum', @@ -21,22 +21,22 @@ export class User { enumName: 'users_role_enum', default: Role.VOLUNTEER, }) - role: Role; + role!: Role; @Column() - firstName: string; + firstName!: string; @Column() - lastName: string; + lastName!: string; @Column() - email: string; + email!: string; @Column({ type: 'varchar', length: 20, }) - phone: string; + phone!: string; @Column({ type: 'varchar', @@ -44,7 +44,7 @@ export class User { name: 'user_cognito_sub', default: '', }) - userCognitoSub: string; + userCognitoSub!: string; @ManyToMany(() => Pantry, (pantry) => pantry.volunteers) @JoinTable({ @@ -58,5 +58,5 @@ export class User { referencedColumnName: 'pantryId', }, }) - pantries?: Pantry[]; + pantries!: Pantry[] | null; } diff --git a/apps/backend/src/users/users.controller.spec.ts b/apps/backend/src/users/users.controller.spec.ts index 97811a0e1..f373f5cbf 100644 --- a/apps/backend/src/users/users.controller.spec.ts +++ b/apps/backend/src/users/users.controller.spec.ts @@ -257,8 +257,8 @@ describe('UsersController', () => { expect(result).toEqual(updatedUser); expect(result.pantries).toHaveLength(2); - expect(result.pantries[0].pantryId).toBe(1); - expect(result.pantries[1].pantryId).toBe(3); + expect(result.pantries![0]!.pantryId).toBe(1); + expect(result.pantries![1]!.pantryId).toBe(3); expect(mockUserService.assignPantriesToVolunteer).toHaveBeenCalledWith( 3, pantryIds, diff --git a/apps/backend/src/users/users.service.ts b/apps/backend/src/users/users.service.ts index 8432ba1a1..bff9435e7 100644 --- a/apps/backend/src/users/users.service.ts +++ b/apps/backend/src/users/users.service.ts @@ -115,14 +115,14 @@ export class UsersService { const { pantries, ...volunteerWithoutPantries } = v; return { ...volunteerWithoutPantries, - pantryIds: pantries.map((p) => p.pantryId), + pantryIds: (pantries ?? []).map((p) => p.pantryId), }; }); } async getVolunteerPantries(volunteerId: number): Promise { const volunteer = await this.findVolunteer(volunteerId); - return volunteer.pantries; + return volunteer.pantries ?? []; } async assignPantriesToVolunteer( @@ -134,12 +134,12 @@ export class UsersService { const volunteer = await this.findVolunteer(volunteerId); const pantries = await this.pantriesService.findByIds(pantryIds); - const existingPantryIds = volunteer.pantries.map((p) => p.pantryId); + const existingPantryIds = (volunteer.pantries ?? []).map((p) => p.pantryId); const newPantries = pantries.filter( (p) => !existingPantryIds.includes(p.pantryId), ); - volunteer.pantries = [...volunteer.pantries, ...newPantries]; + volunteer.pantries = [...(volunteer.pantries ?? []), ...newPantries]; return this.repo.save(volunteer); } diff --git a/apps/backend/src/utils/validation.utils.ts b/apps/backend/src/utils/validation.utils.ts index 5c4f14a78..be7f141a3 100644 --- a/apps/backend/src/utils/validation.utils.ts +++ b/apps/backend/src/utils/validation.utils.ts @@ -1,7 +1,20 @@ -import { BadRequestException } from '@nestjs/common'; +import { + BadRequestException, + InternalServerErrorException, +} from '@nestjs/common'; export function validateId(id: number, entityName: string): void { if (!id || id < 1) { throw new BadRequestException(`Invalid ${entityName} ID`); } } + +export function validateEnv(name: string): string { + const v = process.env[name]; + + if (!v) { + throw new InternalServerErrorException(`Missing env var: ${name}`); + } + + return v; +} diff --git a/apps/backend/tsconfig.json b/apps/backend/tsconfig.json index c1e2dd4e8..0e3d25aa3 100644 --- a/apps/backend/tsconfig.json +++ b/apps/backend/tsconfig.json @@ -11,6 +11,7 @@ } ], "compilerOptions": { - "esModuleInterop": true + "esModuleInterop": true, + "strict": true } } diff --git a/apps/frontend/src/components/forms/requestFormModal.tsx b/apps/frontend/src/components/forms/requestFormModal.tsx index db321db32..d447c5307 100644 --- a/apps/frontend/src/components/forms/requestFormModal.tsx +++ b/apps/frontend/src/components/forms/requestFormModal.tsx @@ -63,7 +63,7 @@ const FoodRequestFormModal: React.FC = ({ const foodRequestData: CreateFoodRequestBody = { pantryId, requestedSize: requestedSize as RequestSize, - additionalInformation: additionalNotes || '', + additionalInformation: additionalNotes || null, requestedItems: selectedItems, dateReceived: null, feedback: null, diff --git a/apps/frontend/src/types/types.ts b/apps/frontend/src/types/types.ts index 5c4136ec6..813ec0b9b 100644 --- a/apps/frontend/src/types/types.ts +++ b/apps/frontend/src/types/types.ts @@ -79,7 +79,7 @@ export interface PantryApplicationDto { mailingAddressZip: string; mailingAddressCountry?: string; allergenClients: string; - restrictions?: string[]; + restrictions: string[]; refrigeratedDonation: RefrigeratedDonation; acceptFoodDeliveries: boolean; deliveryWindowInstructions?: string; @@ -96,6 +96,13 @@ export interface PantryApplicationDto { newsletterSubscription?: string; } +export interface CreateRequestDto { + pantryId: number; + requestedSize: RequestSize; + requestedItems: FoodType[]; + additionalInformation?: string; +} + export enum DonationStatus { AVAILABLE = 'available', FULFILLED = 'fulfilled', diff --git a/yarn.lock b/yarn.lock index 295bbb82a..efaf10178 100644 --- a/yarn.lock +++ b/yarn.lock @@ -348,23 +348,23 @@ tslib "^1.11.1" "@aws-sdk/client-cognito-identity-provider@^3.410.0": - version "3.992.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.992.0.tgz#293314db5bea2e35ca504196f29ba7864b9d66eb" - integrity sha512-i44cLvuFhcn8qHzMi95iCDlncl2So3ZtUb0NIok8pyr0VUfkpSDH0VxdJJz0YX8C7xCufH2EUUDxJjLdOYqIJQ== + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity-provider/-/client-cognito-identity-provider-3.989.0.tgz#28752c5066a3c002959fe0c4939e0ee7587c0e4a" + integrity sha512-uyc+0QROjfFld8OA60veQKmlgg+OOm6BgZV8nkQFDR+azr6xrxhzIdftckgXe6yPkXRJjQ3NxRdtuWjf2fdlUw== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "^3.973.10" - "@aws-sdk/credential-provider-node" "^3.972.9" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/credential-provider-node" "^3.972.8" "@aws-sdk/middleware-host-header" "^3.972.3" "@aws-sdk/middleware-logger" "^3.972.3" "@aws-sdk/middleware-recursion-detection" "^3.972.3" - "@aws-sdk/middleware-user-agent" "^3.972.10" + "@aws-sdk/middleware-user-agent" "^3.972.9" "@aws-sdk/region-config-resolver" "^3.972.3" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.992.0" + "@aws-sdk/util-endpoints" "3.989.0" "@aws-sdk/util-user-agent-browser" "^3.972.3" - "@aws-sdk/util-user-agent-node" "^3.972.8" + "@aws-sdk/util-user-agent-node" "^3.972.7" "@smithy/config-resolver" "^4.4.6" "@smithy/core" "^3.23.0" "@smithy/fetch-http-handler" "^5.3.9" @@ -532,31 +532,31 @@ tslib "^2.6.2" "@aws-sdk/client-s3@^3.735.0": - version "3.992.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.992.0.tgz#27908fd00ee0597140d2f6d052d3dac65b9aca40" - integrity sha512-6xfXGCvnWGgy5zZAse64Ru2G2qLKnPY7h8tchlsmGWVcJOWgz7iM3jmsWsQiJ79zH9A8HAPHU+ZD8TYYkwC+0Q== + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.989.0.tgz#1bd3fecf701d407f6762ca6fa8b7807671b7b15a" + integrity sha512-ccz2miIetWAgrJYmKCpSnRjF8jew7DPstl54nufhfPMtM1MLxD2z55eSk1eJj3Umhu4CioNN1aY1ILT7fwlSiw== dependencies: "@aws-crypto/sha1-browser" "5.2.0" "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "^3.973.10" - "@aws-sdk/credential-provider-node" "^3.972.9" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/credential-provider-node" "^3.972.8" "@aws-sdk/middleware-bucket-endpoint" "^3.972.3" "@aws-sdk/middleware-expect-continue" "^3.972.3" - "@aws-sdk/middleware-flexible-checksums" "^3.972.8" + "@aws-sdk/middleware-flexible-checksums" "^3.972.7" "@aws-sdk/middleware-host-header" "^3.972.3" "@aws-sdk/middleware-location-constraint" "^3.972.3" "@aws-sdk/middleware-logger" "^3.972.3" "@aws-sdk/middleware-recursion-detection" "^3.972.3" - "@aws-sdk/middleware-sdk-s3" "^3.972.10" + "@aws-sdk/middleware-sdk-s3" "^3.972.9" "@aws-sdk/middleware-ssec" "^3.972.3" - "@aws-sdk/middleware-user-agent" "^3.972.10" + "@aws-sdk/middleware-user-agent" "^3.972.9" "@aws-sdk/region-config-resolver" "^3.972.3" - "@aws-sdk/signature-v4-multi-region" "3.992.0" + "@aws-sdk/signature-v4-multi-region" "3.989.0" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.992.0" + "@aws-sdk/util-endpoints" "3.989.0" "@aws-sdk/util-user-agent-browser" "^3.972.3" - "@aws-sdk/util-user-agent-node" "^3.972.8" + "@aws-sdk/util-user-agent-node" "^3.972.7" "@smithy/config-resolver" "^4.4.6" "@smithy/core" "^3.23.0" "@smithy/eventstream-serde-browser" "^4.2.8" @@ -592,23 +592,23 @@ "@smithy/util-waiter" "^4.2.8" tslib "^2.6.2" -"@aws-sdk/client-sso@3.990.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.990.0.tgz#a5471e810b848f740e5c6a8abe90eb2304670c8b" - integrity sha512-xTEaPjZwOqVjGbLOP7qzwbdOWJOo1ne2mUhTZwEBBkPvNk4aXB/vcYwWwrjoSWUqtit4+GDbO75ePc/S6TUJYQ== +"@aws-sdk/client-sso@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.989.0.tgz#d5dce053b4cac2d6c1b0f25a6609e74e795df74c" + integrity sha512-3sC+J1ru5VFXLgt9KZmXto0M7mnV5RkS6FNGwRMK3XrojSjHso9DLOWjbnXhbNv4motH8vu53L1HK2VC1+Nj5w== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/middleware-host-header" "^3.972.3" "@aws-sdk/middleware-logger" "^3.972.3" "@aws-sdk/middleware-recursion-detection" "^3.972.3" - "@aws-sdk/middleware-user-agent" "^3.972.10" + "@aws-sdk/middleware-user-agent" "^3.972.9" "@aws-sdk/region-config-resolver" "^3.972.3" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.990.0" + "@aws-sdk/util-endpoints" "3.989.0" "@aws-sdk/util-user-agent-browser" "^3.972.3" - "@aws-sdk/util-user-agent-node" "^3.972.8" + "@aws-sdk/util-user-agent-node" "^3.972.7" "@smithy/config-resolver" "^4.4.6" "@smithy/core" "^3.23.0" "@smithy/fetch-http-handler" "^5.3.9" @@ -636,10 +636,10 @@ "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/core@^3.973.10", "@aws-sdk/core@^3.973.6": - version "3.973.10" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.973.10.tgz#a8fb3cfe28dfa880b7f669e4696caa6af1e86172" - integrity sha512-4u/FbyyT3JqzfsESI70iFg6e2yp87MB5kS2qcxIA66m52VSTN1fvuvbCY1h/LKq1LvuxIrlJ1ItcyjvcKoaPLg== +"@aws-sdk/core@^3.973.6", "@aws-sdk/core@^3.973.9": + version "3.973.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.973.9.tgz#a42eb97e3e340df7f58f460116c848da376d8ef7" + integrity sha512-cyUOfJSizn8da7XrBEFBf4UMI4A6JQNX6ZFcKtYmh/CrwfzsDcabv3k/z0bNwQ3pX5aeq5sg/8Bs/ASiL0bJaA== dependencies: "@aws-sdk/types" "^3.973.1" "@aws-sdk/xml-builder" "^3.972.4" @@ -663,23 +663,23 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-env@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.8.tgz#0cab351881dc326d7d078156d9f115f08b6423b5" - integrity sha512-r91OOPAcHnLCSxaeu/lzZAVRCZ/CtTNuwmJkUwpwSDshUrP7bkX1OmFn2nUMWd9kN53Q4cEo8b7226G4olt2Mg== +"@aws-sdk/credential-provider-env@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.7.tgz#bdb19770d7ebddd9a12115575cc75ab83a322853" + integrity sha512-r8kBtglvLjGxBT87l6Lqkh9fL8yJJ6O4CYQPjKlj3AkCuL4/4784x3rxxXWw9LTKXOo114VB6mjxAuy5pI7XIg== dependencies: - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-http@^3.972.10": - version "3.972.10" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.10.tgz#d8c35c12da06f2392d6a5d4940782e087d557839" - integrity sha512-DTtuyXSWB+KetzLcWaSahLJCtTUe/3SXtlGp4ik9PCe9xD6swHEkG8n8/BNsQ9dsihb9nhFvuUB4DpdBGDcvVg== +"@aws-sdk/credential-provider-http@^3.972.9": + version "3.972.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.9.tgz#4c266169f071e21ffc49b15b02f4f80ec03b2e62" + integrity sha512-40caFblEg/TPrp9EpvyMxp4xlJ5TuTI+A8H6g8FhHn2hfH2PObFAPLF9d5AljK/G69E1YtTklkuQeAwPlV3w8Q== dependencies: - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@smithy/fetch-http-handler" "^5.3.9" "@smithy/node-http-handler" "^4.4.10" @@ -690,19 +690,19 @@ "@smithy/util-stream" "^4.5.12" tslib "^2.6.2" -"@aws-sdk/credential-provider-ini@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.8.tgz#2e9dbc3feabd04fff2953029834f2be7abca879c" - integrity sha512-n2dMn21gvbBIEh00E8Nb+j01U/9rSqFIamWRdGm/mE5e+vHQ9g0cBNdrYFlM6AAiryKVHZmShWT9D1JAWJ3ISw== - dependencies: - "@aws-sdk/core" "^3.973.10" - "@aws-sdk/credential-provider-env" "^3.972.8" - "@aws-sdk/credential-provider-http" "^3.972.10" - "@aws-sdk/credential-provider-login" "^3.972.8" - "@aws-sdk/credential-provider-process" "^3.972.8" - "@aws-sdk/credential-provider-sso" "^3.972.8" - "@aws-sdk/credential-provider-web-identity" "^3.972.8" - "@aws-sdk/nested-clients" "3.990.0" +"@aws-sdk/credential-provider-ini@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.7.tgz#28fd9fc9e6da712f392240bd1b882d99f4e5d98a" + integrity sha512-zeYKrMwM5bCkHFho/x3+1OL0vcZQ0OhTR7k35tLq74+GP5ieV3juHXTZfa2LVE0Bg75cHIIerpX0gomVOhzo/w== + dependencies: + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/credential-provider-env" "^3.972.7" + "@aws-sdk/credential-provider-http" "^3.972.9" + "@aws-sdk/credential-provider-login" "^3.972.7" + "@aws-sdk/credential-provider-process" "^3.972.7" + "@aws-sdk/credential-provider-sso" "^3.972.7" + "@aws-sdk/credential-provider-web-identity" "^3.972.7" + "@aws-sdk/nested-clients" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/credential-provider-imds" "^4.2.8" "@smithy/property-provider" "^4.2.8" @@ -710,13 +710,13 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-login@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.8.tgz#3f0c0dc8b49f525bed1c318b675a799be01ca686" - integrity sha512-rMFuVids8ICge/X9DF5pRdGMIvkVhDV9IQFQ8aTYk6iF0rl9jOUa1C3kjepxiXUlpgJQT++sLZkT9n0TMLHhQw== +"@aws-sdk/credential-provider-login@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.7.tgz#c98aa999c1538c28aff2eb8d61c82d359acb0404" + integrity sha512-Q103cLU6OjAllYjX7+V+PKQw654jjvZUkD+lbUUiFbqut6gR5zwl1DrelvJPM5hnzIty7BCaxaRB3KMuz3M/ug== dependencies: - "@aws-sdk/core" "^3.973.10" - "@aws-sdk/nested-clients" "3.990.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/nested-clients" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/protocol-http" "^5.3.8" @@ -724,17 +724,17 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-node@^3.972.5", "@aws-sdk/credential-provider-node@^3.972.9": - version "3.972.9" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.9.tgz#c92158aab359787eedd64d83931c35a0a00f6072" - integrity sha512-LfJfO0ClRAq2WsSnA9JuUsNyIicD2eyputxSlSL0EiMrtxOxELLRG6ZVYDf/a1HCepaYPXeakH4y8D5OLCauag== - dependencies: - "@aws-sdk/credential-provider-env" "^3.972.8" - "@aws-sdk/credential-provider-http" "^3.972.10" - "@aws-sdk/credential-provider-ini" "^3.972.8" - "@aws-sdk/credential-provider-process" "^3.972.8" - "@aws-sdk/credential-provider-sso" "^3.972.8" - "@aws-sdk/credential-provider-web-identity" "^3.972.8" +"@aws-sdk/credential-provider-node@^3.972.5", "@aws-sdk/credential-provider-node@^3.972.8": + version "3.972.8" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.8.tgz#6dabc10f104a6cfa7a8bfbae9000fbce7453b0d0" + integrity sha512-AaDVOT7iNJyLjc3j91VlucPZ4J8Bw+eu9sllRDugJqhHWYyR3Iyp2huBUW8A3+DfHoh70sxGkY92cThAicSzlQ== + dependencies: + "@aws-sdk/credential-provider-env" "^3.972.7" + "@aws-sdk/credential-provider-http" "^3.972.9" + "@aws-sdk/credential-provider-ini" "^3.972.7" + "@aws-sdk/credential-provider-process" "^3.972.7" + "@aws-sdk/credential-provider-sso" "^3.972.7" + "@aws-sdk/credential-provider-web-identity" "^3.972.7" "@aws-sdk/types" "^3.973.1" "@smithy/credential-provider-imds" "^4.2.8" "@smithy/property-provider" "^4.2.8" @@ -742,39 +742,39 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-process@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.8.tgz#99c14367e33880b2c6f88b1417bd92fc6f390043" - integrity sha512-6cg26ffFltxM51OOS8NH7oE41EccaYiNlbd5VgUYwhiGCySLfHoGuGrLm2rMB4zhy+IO5nWIIG0HiodX8zdvHA== +"@aws-sdk/credential-provider-process@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.7.tgz#a32117662790f8811ee08af9d5c7f2542dd9a289" + integrity sha512-hxMo1V3ujWWrQSONxQJAElnjredkRpB6p8SDjnvRq70IwYY38R/CZSys0IbhRPxdgWZ5j12yDRk2OXhxw4Gj3g== dependencies: - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-sso@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.8.tgz#aad4174425cae4535db2456f85b6c1315544f2a3" - integrity sha512-35kqmFOVU1n26SNv+U37sM8b2TzG8LyqAcd6iM9gprqxyHEh/8IM3gzN4Jzufs3qM6IrH8e43ryZWYdvfVzzKQ== +"@aws-sdk/credential-provider-sso@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.7.tgz#87cfeeaf907eb574388fd65e3b749044d57cca54" + integrity sha512-ZGKBOHEj8Ap15jhG2XMncQmKLTqA++2DVU2eZfLu3T/pkwDyhCp5eZv5c/acFxbZcA/6mtxke+vzO/n+aeHs4A== dependencies: - "@aws-sdk/client-sso" "3.990.0" - "@aws-sdk/core" "^3.973.10" - "@aws-sdk/token-providers" "3.990.0" + "@aws-sdk/client-sso" "3.989.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/token-providers" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-web-identity@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.8.tgz#b662e6a234fb0b169760857236bbb2916396a674" - integrity sha512-CZhN1bOc1J3ubQPqbmr5b4KaMJBgdDvYsmEIZuX++wFlzmZsKj1bwkaiTEb5U2V7kXuzLlpF5HJSOM9eY/6nGA== +"@aws-sdk/credential-provider-web-identity@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.7.tgz#c983dd478c0a1be4069abb10ff11527e07c7b224" + integrity sha512-AbYupBIoSJoVMlbMqBhNvPhqj+CdGtzW7Uk4ZIMBm2br18pc3rkG1VaKVFV85H87QCvLHEnni1idJjaX1wOmIw== dependencies: - "@aws-sdk/core" "^3.973.10" - "@aws-sdk/nested-clients" "3.990.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/nested-clients" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" @@ -782,9 +782,9 @@ tslib "^2.6.2" "@aws-sdk/lib-storage@^3.735.0": - version "3.992.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.992.0.tgz#70b7a6f5340d65f6d6360ae00811fb81b73dff0b" - integrity sha512-XMbA5Sscho56oMNZi9G3LJirZqazpOlQvcGWoH1UvF1PN3iiYpO1l2g84LH9Xju1yU3BiLaxukEzD5aKyrPp0w== + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.989.0.tgz#b877f0971334e4d7a3ce58e69c1932de11630d21" + integrity sha512-8pJXMJ7MT5At/5ANFC68IbhfG8hNe0/ISsbtdVopgQEsiZEAHr0HDNoPcyoRnc3RTzjykz7Q95uf/Lpz3PQNmA== dependencies: "@smithy/abort-controller" "^4.2.8" "@smithy/middleware-endpoint" "^4.4.14" @@ -817,15 +817,15 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-flexible-checksums@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.8.tgz#aaf841f58e88e545a0ee799bca941f93efdfd796" - integrity sha512-Hn6gumcN/3/8Fzo9z7N1pA2PRfE8S+qAqdb4g3MqzXjIOIe+VxD7edO/DKAJ1YH11639EGQIHBz0wdOb5btjtw== +"@aws-sdk/middleware-flexible-checksums@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.7.tgz#b812fd2ad23c3eae79d7d0d5cc44660d84862b15" + integrity sha512-YU/5rpz8k2mwFGi2M0px9ChOQZY7Bbow5knB2WLRVPqDM/cG8T5zj55UaWS1qcaFpE7vCX9a9/kvYBlKGcD+KA== dependencies: "@aws-crypto/crc32" "5.2.0" "@aws-crypto/crc32c" "5.2.0" "@aws-crypto/util" "5.2.0" - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/crc64-nvme" "3.972.0" "@aws-sdk/types" "^3.973.1" "@smithy/is-array-buffer" "^4.2.0" @@ -876,12 +876,12 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-sdk-s3@^3.972.10": - version "3.972.10" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.10.tgz#5aa0f09fa8b17e7dfbde431f0b6ab2521872209f" - integrity sha512-wLkB4bshbBtsAiC2WwlHzOWXu1fx3ftL63fQl0DxEda48Q6B8bcHydZppE3KjEIpPyiNOllByfSnb07cYpIgmw== +"@aws-sdk/middleware-sdk-s3@^3.972.9": + version "3.972.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.9.tgz#6b3fad9a22a25b8a28fd7491b1888e796eb986eb" + integrity sha512-F4Ak2HM7te/o3izFTqg/jUTBLjavpaJ5iynKM6aLMwNddXbwAZQ1VbIG8RFUHBo7fBHj2eeN2FNLtIFT4ejWYQ== dependencies: - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@aws-sdk/util-arn-parser" "^3.972.2" "@smithy/core" "^3.23.0" @@ -905,36 +905,36 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-user-agent@^3.972.10", "@aws-sdk/middleware-user-agent@^3.972.6": - version "3.972.10" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.10.tgz#0efb74242de786087de289677a2d2a3a9895f182" - integrity sha512-bBEL8CAqPQkI91ZM5a9xnFAzedpzH6NYCOtNyLarRAzTUTFN2DKqaC60ugBa7pnU1jSi4mA7WAXBsrod7nJltg== +"@aws-sdk/middleware-user-agent@^3.972.6", "@aws-sdk/middleware-user-agent@^3.972.9": + version "3.972.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.9.tgz#998e38d32b4fa4bda71c017c3044f7f46dc4f031" + integrity sha512-1g1B7yf7KzessB0mKNiV9gAHEwbM662xgU+VE4LxyGe6kVGZ8LqYsngjhE+Stna09CJ7Pxkjr6Uq1OtbGwJJJg== dependencies: - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.990.0" + "@aws-sdk/util-endpoints" "3.989.0" "@smithy/core" "^3.23.0" "@smithy/protocol-http" "^5.3.8" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/nested-clients@3.990.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.990.0.tgz#8e1b35231e98b35b23e6dff1e71256993819a422" - integrity sha512-3NA0s66vsy8g7hPh36ZsUgO4SiMyrhwcYvuuNK1PezO52vX3hXDW4pQrC6OQLGKGJV0o6tbEyQtXb/mPs8zg8w== +"@aws-sdk/nested-clients@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.989.0.tgz#0fbe4db7af0c38b7b41f31dba6f26b29dc8b7082" + integrity sha512-Dbk2HMPU3mb6RrSRzgf0WCaWSbgtZG258maCpuN2/ONcAQNpOTw99V5fU5CA1qVK6Vkm4Fwj2cnOnw7wbGVlOw== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "^3.973.10" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/middleware-host-header" "^3.972.3" "@aws-sdk/middleware-logger" "^3.972.3" "@aws-sdk/middleware-recursion-detection" "^3.972.3" - "@aws-sdk/middleware-user-agent" "^3.972.10" + "@aws-sdk/middleware-user-agent" "^3.972.9" "@aws-sdk/region-config-resolver" "^3.972.3" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.990.0" + "@aws-sdk/util-endpoints" "3.989.0" "@aws-sdk/util-user-agent-browser" "^3.972.3" - "@aws-sdk/util-user-agent-node" "^3.972.8" + "@aws-sdk/util-user-agent-node" "^3.972.7" "@smithy/config-resolver" "^4.4.6" "@smithy/core" "^3.23.0" "@smithy/fetch-http-handler" "^5.3.9" @@ -973,25 +973,25 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/signature-v4-multi-region@3.992.0": - version "3.992.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.992.0.tgz#a2875715201005cdcbf47d36ecdfe38d76d95f7d" - integrity sha512-jWoaM89xH2cYOY6O+PWMa0yqjzKlE61Ehea1hJe34kHg9QvZOkcSA5OT9CNaFXsAvafeAAHBhSE8XlDiNaJFuw== +"@aws-sdk/signature-v4-multi-region@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.989.0.tgz#bbd474693c8b1ee1fc32282774ad104f6791c20b" + integrity sha512-rVhR/BUZdnru7tLlxWD+uzoKB1LAs2L0pcoh6rYgIYuCtQflnsC6Ud0SpfqIsOapBSBKXdoW73IITFf+XFMdCQ== dependencies: - "@aws-sdk/middleware-sdk-s3" "^3.972.10" + "@aws-sdk/middleware-sdk-s3" "^3.972.9" "@aws-sdk/types" "^3.973.1" "@smithy/protocol-http" "^5.3.8" "@smithy/signature-v4" "^5.3.8" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/token-providers@3.990.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.990.0.tgz#045b21339258f1c7b3f1b8dedc475a8cc3842d68" - integrity sha512-L3BtUb2v9XmYgQdfGBzbBtKMXaP5fV973y3Qdxeevs6oUTVXFmi/mV1+LnScA/1wVPJC9/hlK+1o5vbt7cG7EQ== +"@aws-sdk/token-providers@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.989.0.tgz#4bc8c2c122f91de6b9eb174a14d3f8d8a72f441a" + integrity sha512-OdBByMv+OjOZoekrk4THPFpLuND5aIQbDHCGh3n2rvifAbm31+6e0OLhxSeCF1UMPm+nKq12bXYYEoCIx5SQBg== dependencies: - "@aws-sdk/core" "^3.973.10" - "@aws-sdk/nested-clients" "3.990.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/nested-clients" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" @@ -1024,21 +1024,10 @@ "@smithy/util-endpoints" "^3.2.8" tslib "^2.6.2" -"@aws-sdk/util-endpoints@3.990.0": - version "3.990.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.990.0.tgz#3c78424f2ea48a1bba5e8fa5bf0d8f205c0675ce" - integrity sha512-kVwtDc9LNI3tQZHEMNbkLIOpeDK8sRSTuT8eMnzGY+O+JImPisfSTjdh+jw9OTznu+MYZjQsv0258sazVKunYg== - dependencies: - "@aws-sdk/types" "^3.973.1" - "@smithy/types" "^4.12.0" - "@smithy/url-parser" "^4.2.8" - "@smithy/util-endpoints" "^3.2.8" - tslib "^2.6.2" - -"@aws-sdk/util-endpoints@3.992.0": - version "3.992.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.992.0.tgz#cfba9509156c124663203a8536bef18b7f81b37b" - integrity sha512-FHgdMVbTZ2Lu7hEIoGYfkd5UazNSsAgPcupEnh15vsWKFKhuw6w/6tM1k/yNaa7l1wx0Wt1UuK0m+gQ0BJpuvg== +"@aws-sdk/util-endpoints@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.989.0.tgz#08301e145a658c4a1a682354f108a5b0eb58af92" + integrity sha512-eKmAOeQM4Qusq0jtcbZPiNWky8XaojByKC/n+THbJ8vJf7t4ys8LlcZ4PrBSHZISe9cC484mQsPVOQh6iySjqw== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/types" "^4.12.0" @@ -1063,12 +1052,12 @@ bowser "^2.11.0" tslib "^2.6.2" -"@aws-sdk/util-user-agent-node@^3.972.4", "@aws-sdk/util-user-agent-node@^3.972.8": - version "3.972.8" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.8.tgz#c79f71cf1149501cc898862e3c350be601c9a0f8" - integrity sha512-XJZuT0LWsFCW1C8dEpPAXSa7h6Pb3krr2y//1X0Zidpcl0vmgY5nL/X0JuBZlntpBzaN3+U4hvKjuijyiiR8zw== +"@aws-sdk/util-user-agent-node@^3.972.4", "@aws-sdk/util-user-agent-node@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.7.tgz#c55e1eb7911215127bfd5dfb29c1bf2e3247581d" + integrity sha512-oyhv+FjrgHjP+F16cmsrJzNP4qaRJzkV1n9Lvv4uyh3kLqo3rIe9NSBSBa35f2TedczfG2dD+kaQhHBB47D6Og== dependencies: - "@aws-sdk/middleware-user-agent" "^3.972.10" + "@aws-sdk/middleware-user-agent" "^3.972.9" "@aws-sdk/types" "^3.973.1" "@smithy/node-config-provider" "^4.3.8" "@smithy/types" "^4.12.0" @@ -4088,9 +4077,9 @@ yargs-parser "21.1.1" "@pandacss/is-valid-prop@^1.4.2": - version "1.8.2" - resolved "https://registry.yarnpkg.com/@pandacss/is-valid-prop/-/is-valid-prop-1.8.2.tgz#d887733345b06bfe3853fe0491e21f7602e5a309" - integrity sha512-wfZ4kzvHXQ9pG3wuIGTUCcbC7Op8pqIQZNIRY/bqWQu67WTHxZUHUPSZgQMhguI8Tz4ot+DNf4Qhha0bhLvNEQ== + version "1.8.1" + resolved "https://registry.yarnpkg.com/@pandacss/is-valid-prop/-/is-valid-prop-1.8.1.tgz#8d23dd897a006c21f5ce0bcb66759b1b625d3b9a" + integrity sha512-gf2HTBCOboc65Jlb9swAjbffXSIv+A4vzSQ9iHyTCDLMcXTHYjPOQNliI36WkuQgR0pNXggBbQXGNaT9wKcrAw== "@parcel/watcher-android-arm64@2.5.6": version "2.5.6" @@ -4924,10 +4913,10 @@ "@smithy/util-middleware" "^4.2.8" tslib "^2.6.2" -"@smithy/core@^3.22.0", "@smithy/core@^3.23.0", "@smithy/core@^3.23.1": - version "3.23.1" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.23.1.tgz#d3d30e1111093f4833435416bf7daac4eab3b0d3" - integrity sha512-F6nYWvsF0EUYo3Ge1+RWajbhfM9EkCoiZkDQNMrqsOSTZsgNfxjg4FZzFaEBlT0Oex6Fwt7HkRoQH2B9gGQZSw== +"@smithy/core@^3.22.0", "@smithy/core@^3.23.0": + version "3.23.0" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.23.0.tgz#64dca2825753316ace7b8342cb96c9dfc5de4e2a" + integrity sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg== dependencies: "@smithy/middleware-serde" "^4.2.9" "@smithy/protocol-http" "^5.3.8" @@ -5092,12 +5081,12 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@smithy/middleware-endpoint@^4.4.12", "@smithy/middleware-endpoint@^4.4.14", "@smithy/middleware-endpoint@^4.4.15": - version "4.4.15" - resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.15.tgz#dee18a3c23da7b81c88bcd794a7f4445f8c6f6c3" - integrity sha512-XPt69QTK5267KxXnX0Lu5zFAYiwoqTnM5HiMmosFg43A9Enoao75fXw9Qvie/3oWbEZmSMqELfUBsphRJ3C0XQ== +"@smithy/middleware-endpoint@^4.4.12", "@smithy/middleware-endpoint@^4.4.14": + version "4.4.14" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.14.tgz#df8aca71af70366f39305eeaf18ffd650f764219" + integrity sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag== dependencies: - "@smithy/core" "^3.23.1" + "@smithy/core" "^3.23.0" "@smithy/middleware-serde" "^4.2.9" "@smithy/node-config-provider" "^4.3.8" "@smithy/shared-ini-file-loader" "^4.4.3" @@ -5107,14 +5096,14 @@ tslib "^2.6.2" "@smithy/middleware-retry@^4.4.29", "@smithy/middleware-retry@^4.4.31": - version "4.4.32" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.4.32.tgz#3aed77456028de227abe9a77516e2633300f4f48" - integrity sha512-SzklZYMxHp5Rqghah7eFKlAbaMMa72+WZeMJZFmdcjipM+QWwIWIHprJnGdRlK6bpvfDvEB4JrVa4vPWz4BE5w== + version "4.4.31" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.4.31.tgz#1dbdbaedbd62f4900e3520f65599810123c0c461" + integrity sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg== dependencies: "@smithy/node-config-provider" "^4.3.8" "@smithy/protocol-http" "^5.3.8" "@smithy/service-error-classification" "^4.2.8" - "@smithy/smithy-client" "^4.11.4" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" "@smithy/util-middleware" "^4.2.8" "@smithy/util-retry" "^4.2.8" @@ -5221,13 +5210,13 @@ "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" -"@smithy/smithy-client@^4.11.1", "@smithy/smithy-client@^4.11.3", "@smithy/smithy-client@^4.11.4": - version "4.11.4" - resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.11.4.tgz#c78bb5f3393063d8f6b4cd6516ad0942aa673387" - integrity sha512-Cs+Hwj4vAn6bHnLflSfgV6q9shkXUWAHcwgcVQ7Ez5v7YrINuIGfCfp0NBqh+lYUgLriCW5RjhF6Z6x8vgFYRQ== +"@smithy/smithy-client@^4.11.1", "@smithy/smithy-client@^4.11.3": + version "4.11.3" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.11.3.tgz#94d1083d5bc3b09e510f680ad7f82395765badf3" + integrity sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg== dependencies: - "@smithy/core" "^3.23.1" - "@smithy/middleware-endpoint" "^4.4.15" + "@smithy/core" "^3.23.0" + "@smithy/middleware-endpoint" "^4.4.14" "@smithy/middleware-stack" "^4.2.8" "@smithy/protocol-http" "^5.3.8" "@smithy/types" "^4.12.0" @@ -5328,25 +5317,25 @@ tslib "^2.6.2" "@smithy/util-defaults-mode-browser@^4.3.28", "@smithy/util-defaults-mode-browser@^4.3.30": - version "4.3.31" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.31.tgz#e2337c476189abfcd9b22025ccdbed99b4bf903d" - integrity sha512-76fzZbPajGAtCjMbWaFmxLYxRtLkZSYNG8drOjZU9Y0TJIPxaQwg8/JiQNLLPezmK0GTiglzki7Go+oTG0NMAw== + version "4.3.30" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.30.tgz#0494c467897ddf5b09b6f87712992b7b0ebe1cc1" + integrity sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng== dependencies: "@smithy/property-provider" "^4.2.8" - "@smithy/smithy-client" "^4.11.4" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" "@smithy/util-defaults-mode-node@^4.2.31", "@smithy/util-defaults-mode-node@^4.2.33": - version "4.2.34" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.34.tgz#c0b61f1ea01006df56150286e686cfd80058960f" - integrity sha512-mhT5F2nwA9OHmdkQu+r2GKLMAmE3ht8rBWHLGo5i8acRRVo9XUrqN2nxI2f6yRyw8e7hZ2TCqNRVOJk9VUWyhQ== + version "4.2.33" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.33.tgz#b5d8b88d398d4556fe3e6299d7a14eac2b892750" + integrity sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA== dependencies: "@smithy/config-resolver" "^4.4.6" "@smithy/credential-provider-imds" "^4.2.8" "@smithy/node-config-provider" "^4.3.8" "@smithy/property-provider" "^4.2.8" - "@smithy/smithy-client" "^4.11.4" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" @@ -6066,28 +6055,37 @@ "@types/node" "*" "@typescript-eslint/eslint-plugin@^8.23.0": - version "8.56.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz#5aec3db807a6b8437ea5d5ebf7bd16b4119aba8d" - integrity sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw== + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz#086d2ef661507b561f7b17f62d3179d692a0765f" + integrity sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ== dependencies: "@eslint-community/regexpp" "^4.12.2" - "@typescript-eslint/scope-manager" "8.56.0" - "@typescript-eslint/type-utils" "8.56.0" - "@typescript-eslint/utils" "8.56.0" - "@typescript-eslint/visitor-keys" "8.56.0" + "@typescript-eslint/scope-manager" "8.55.0" + "@typescript-eslint/type-utils" "8.55.0" + "@typescript-eslint/utils" "8.55.0" + "@typescript-eslint/visitor-keys" "8.55.0" ignore "^7.0.5" natural-compare "^1.4.0" ts-api-utils "^2.4.0" "@typescript-eslint/parser@^8.23.0": - version "8.56.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.56.0.tgz#8ecff1678b8b1a742d29c446ccf5eeea7f971d72" - integrity sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg== + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.55.0.tgz#6eace4e9e95f178d3447ed1f17f3d6a5dfdb345c" + integrity sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw== + dependencies: + "@typescript-eslint/scope-manager" "8.55.0" + "@typescript-eslint/types" "8.55.0" + "@typescript-eslint/typescript-estree" "8.55.0" + "@typescript-eslint/visitor-keys" "8.55.0" + debug "^4.4.3" + +"@typescript-eslint/project-service@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.55.0.tgz#b8a71c06a625bdad481c24d5614b68e252f3ae9b" + integrity sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ== dependencies: - "@typescript-eslint/scope-manager" "8.56.0" - "@typescript-eslint/types" "8.56.0" - "@typescript-eslint/typescript-estree" "8.56.0" - "@typescript-eslint/visitor-keys" "8.56.0" + "@typescript-eslint/tsconfig-utils" "^8.55.0" + "@typescript-eslint/types" "^8.55.0" debug "^4.4.3" "@typescript-eslint/project-service@8.56.0": @@ -6107,6 +6105,14 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" +"@typescript-eslint/scope-manager@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz#8a0752c31c788651840dc98f840b0c2ebe143b8c" + integrity sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q== + dependencies: + "@typescript-eslint/types" "8.55.0" + "@typescript-eslint/visitor-keys" "8.55.0" + "@typescript-eslint/scope-manager@8.56.0": version "8.56.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz#604030a4c6433df3728effdd441d47f45a86edb4" @@ -6115,12 +6121,28 @@ "@typescript-eslint/types" "8.56.0" "@typescript-eslint/visitor-keys" "8.56.0" +"@typescript-eslint/tsconfig-utils@8.55.0", "@typescript-eslint/tsconfig-utils@^8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz#62f1d005419985e09d37a040b2f1450e4e805afa" + integrity sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q== + "@typescript-eslint/tsconfig-utils@8.56.0", "@typescript-eslint/tsconfig-utils@^8.56.0": version "8.56.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz#2538ce83cbc376e685487960cbb24b65fe2abc4e" integrity sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg== -"@typescript-eslint/type-utils@8.56.0", "@typescript-eslint/type-utils@^8.0.0": +"@typescript-eslint/type-utils@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz#195d854b3e56308ce475fdea2165313bb1190200" + integrity sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g== + dependencies: + "@typescript-eslint/types" "8.55.0" + "@typescript-eslint/typescript-estree" "8.55.0" + "@typescript-eslint/utils" "8.55.0" + debug "^4.4.3" + ts-api-utils "^2.4.0" + +"@typescript-eslint/type-utils@^8.0.0": version "8.56.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz#72b4edc1fc73988998f1632b3ec99c2a66eaac6e" integrity sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA== @@ -6136,6 +6158,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== +"@typescript-eslint/types@8.55.0", "@typescript-eslint/types@^8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.55.0.tgz#8449c5a7adac61184cac92dbf6315733569708c2" + integrity sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w== + "@typescript-eslint/types@8.56.0", "@typescript-eslint/types@^8.56.0": version "8.56.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.56.0.tgz#a2444011b9a98ca13d70411d2cbfed5443b3526a" @@ -6154,6 +6181,21 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz#c83ac92c11ce79bedd984937c7780a65e7f7b2e3" + integrity sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw== + dependencies: + "@typescript-eslint/project-service" "8.55.0" + "@typescript-eslint/tsconfig-utils" "8.55.0" + "@typescript-eslint/types" "8.55.0" + "@typescript-eslint/visitor-keys" "8.55.0" + debug "^4.4.3" + minimatch "^9.0.5" + semver "^7.7.3" + tinyglobby "^0.2.15" + ts-api-utils "^2.4.0" + "@typescript-eslint/typescript-estree@8.56.0": version "8.56.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz#fadbc74c14c5bac947db04980ff58bb178701c2e" @@ -6169,6 +6211,16 @@ tinyglobby "^0.2.15" ts-api-utils "^2.4.0" +"@typescript-eslint/utils@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.55.0.tgz#c1744d94a3901deb01f58b09d3478d811f96d619" + integrity sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow== + dependencies: + "@eslint-community/eslint-utils" "^4.9.1" + "@typescript-eslint/scope-manager" "8.55.0" + "@typescript-eslint/types" "8.55.0" + "@typescript-eslint/typescript-estree" "8.55.0" + "@typescript-eslint/utils@8.56.0", "@typescript-eslint/utils@^8.0.0": version "8.56.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.56.0.tgz#063ce6f702ec603de1b83ee795ed5e877d6f7841" @@ -6201,6 +6253,14 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz#3d9a40fd4e3705c63d8fae3af58988add3ed464d" + integrity sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA== + dependencies: + "@typescript-eslint/types" "8.55.0" + eslint-visitor-keys "^4.2.1" + "@typescript-eslint/visitor-keys@8.56.0": version "8.56.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz#7d6592ab001827d3ce052155edf7ecad19688d7d" @@ -7416,7 +7476,17 @@ ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.12.0, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ajv@^8.12.0: version "8.18.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.18.0.tgz#8864186b6738d003eb3a933172bb3833e10cefbc" integrity sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A== @@ -8206,9 +8276,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001766: - version "1.0.30001770" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz#4dc47d3b263a50fbb243448034921e0a88591a84" - integrity sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw== + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== caseless@~0.12.0: version "0.12.0" @@ -9701,6 +9771,11 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" + integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== + eslint-visitor-keys@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz#b9aa1a74aa48c44b3ae46c1597ce7171246a94a9" @@ -10044,9 +10119,9 @@ fast-xml-parser@5.3.4: strnum "^2.1.0" fast-xml-parser@^5.3.4: - version "5.3.6" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz#85a69117ca156b1b3c52e426495b6de266cb6a4b" - integrity sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA== + version "5.3.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.3.5.tgz#3e914cb852e636923cb555deaa356f7366e18b49" + integrity sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA== dependencies: strnum "^2.1.2" @@ -11362,9 +11437,9 @@ is-wsl@^2.2.0: is-docker "^2.0.0" is-wsl@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.1.tgz#327897b26832a3eb117da6c27492d04ca132594f" - integrity sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw== + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" + integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw== dependencies: is-inside-container "^1.0.0" @@ -12502,9 +12577,9 @@ levn@^0.4.1: type-check "~0.4.0" libphonenumber-js@^1.11.1: - version "1.12.37" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.37.tgz#a60e3f14ce79f5df4c9a16bede3608d3eab37a5f" - integrity sha512-rDU6bkpuMs8YRt/UpkuYEAsYSoNuDEbrE41I3KNvmXREGH6DGBJ8Wbak4by29wNOQ27zk4g4HL82zf0OGhwRuw== + version "1.12.36" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.12.36.tgz#3698ba31e77fc4e5d4e3257dedc76f28cb594c35" + integrity sha512-woWhKMAVx1fzzUnMCyOzglgSgf6/AFHLASdOBcchYCyvWSGWt12imw3iu2hdI5d4dGZRsNWAmWiz37sDKUPaRQ== license-webpack-plugin@^4.0.2: version "4.0.2" @@ -13175,16 +13250,6 @@ node-emoji@1.11.0: dependencies: lodash "^4.17.21" -node-exports-info@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/node-exports-info/-/node-exports-info-1.6.0.tgz#1aedafb01a966059c9a5e791a94a94d93f5c2a13" - integrity sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw== - dependencies: - array.prototype.flatmap "^1.3.3" - es-errors "^1.3.0" - object.entries "^1.1.9" - semver "^6.3.1" - node-fetch@2.7.0, node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -14308,14 +14373,7 @@ qrcode@1.5.0: pngjs "^5.0.0" yargs "^15.3.1" -qs@^6.4.0: - version "6.15.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.0.tgz#db8fd5d1b1d2d6b5b33adaf87429805f1909e7b3" - integrity sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ== - dependencies: - side-channel "^1.1.0" - -qs@~6.14.0, qs@~6.14.1: +qs@^6.4.0, qs@~6.14.0, qs@~6.14.1: version "6.14.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.2.tgz#b5634cf9d9ad9898e31fba3504e866e8efb6798c" integrity sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q== @@ -14635,14 +14693,11 @@ resolve@^1.1.7, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.22.11, resolve@^1.2 supports-preserve-symlinks-flag "^1.0.0" resolve@^2.0.0-next.5: - version "2.0.0-next.6" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.6.tgz#b3961812be69ace7b3bc35d5bf259434681294af" - integrity sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA== + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== dependencies: - es-errors "^1.3.0" - is-core-module "^2.16.1" - node-exports-info "^1.6.0" - object-keys "^1.1.1" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -16567,9 +16622,9 @@ webpack-node-externals@3.0.0, webpack-node-externals@^3.0.0: integrity sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ== webpack-sources@^3.0.0, webpack-sources@^3.2.3, webpack-sources@^3.3.3: - version "3.3.4" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.4.tgz#a338b95eb484ecc75fbb196cbe8a2890618b4891" - integrity sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q== + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== webpack-subresource-integrity@^5.1.0: version "5.1.0"