This commit is contained in:
Philipinho
2025-04-08 18:46:54 +01:00
parent a74d3feae4
commit 3a1b3fbaca
9 changed files with 607 additions and 305 deletions

View File

@ -31,6 +31,7 @@
},
"dependencies": {
"@aws-sdk/client-s3": "3.701.0",
"@aws-sdk/lib-storage": "^3.779.0",
"@aws-sdk/s3-request-presigner": "3.701.0",
"@casl/ability": "^6.7.3",
"@fastify/cookie": "^11.0.2",

View File

@ -1,310 +1,314 @@
import {
BadRequestException,
Controller,
ForbiddenException,
Get,
HttpCode,
HttpStatus,
Logger,
NotFoundException,
Param,
Post,
Req,
Res,
UseGuards,
UseInterceptors,
BadRequestException,
Controller,
ForbiddenException,
Get,
HttpCode,
HttpStatus,
Logger,
NotFoundException,
Param,
Post,
Req,
Res,
UseGuards,
UseInterceptors,
} from '@nestjs/common';
import {AttachmentService} from './services/attachment.service';
import {FastifyReply} from 'fastify';
import {FileInterceptor} from '../../common/interceptors/file.interceptor';
import { AttachmentService } from './services/attachment.service';
import { FastifyReply, FastifyRequest } from 'fastify';
import { FileInterceptor } from '../../common/interceptors/file.interceptor';
import * as bytes from 'bytes';
import {AuthUser} from '../../common/decorators/auth-user.decorator';
import {AuthWorkspace} from '../../common/decorators/auth-workspace.decorator';
import {JwtAuthGuard} from '../../common/guards/jwt-auth.guard';
import {User, Workspace} from '@docmost/db/types/entity.types';
import {StorageService} from '../../integrations/storage/storage.service';
import { AuthUser } from '../../common/decorators/auth-user.decorator';
import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { User, Workspace } from '@docmost/db/types/entity.types';
import { StorageService } from '../../integrations/storage/storage.service';
import {
getAttachmentFolderPath,
validAttachmentTypes,
getAttachmentFolderPath,
validAttachmentTypes,
} from './attachment.utils';
import {getMimeType} from '../../common/helpers';
import { getMimeType } from '../../common/helpers';
import {
AttachmentType,
inlineFileExtensions,
MAX_AVATAR_SIZE,
AttachmentType,
inlineFileExtensions,
MAX_AVATAR_SIZE,
} from './attachment.constants';
import {
SpaceCaslAction,
SpaceCaslSubject,
SpaceCaslAction,
SpaceCaslSubject,
} from '../casl/interfaces/space-ability.type';
import SpaceAbilityFactory from '../casl/abilities/space-ability.factory';
import {
WorkspaceCaslAction,
WorkspaceCaslSubject,
WorkspaceCaslAction,
WorkspaceCaslSubject,
} from '../casl/interfaces/workspace-ability.type';
import WorkspaceAbilityFactory from '../casl/abilities/workspace-ability.factory';
import {PageRepo} from '@docmost/db/repos/page/page.repo';
import {AttachmentRepo} from '@docmost/db/repos/attachment/attachment.repo';
import {validate as isValidUUID} from 'uuid';
import {EnvironmentService} from "../../integrations/environment/environment.service";
import { PageRepo } from '@docmost/db/repos/page/page.repo';
import { AttachmentRepo } from '@docmost/db/repos/attachment/attachment.repo';
import { validate as isValidUUID } from 'uuid';
import { EnvironmentService } from '../../integrations/environment/environment.service';
@Controller()
export class AttachmentController {
private readonly logger = new Logger(AttachmentController.name);
private readonly logger = new Logger(AttachmentController.name);
constructor(
private readonly attachmentService: AttachmentService,
private readonly storageService: StorageService,
private readonly workspaceAbility: WorkspaceAbilityFactory,
private readonly spaceAbility: SpaceAbilityFactory,
private readonly pageRepo: PageRepo,
private readonly attachmentRepo: AttachmentRepo,
private readonly environmentService: EnvironmentService,
) {
}
constructor(
private readonly attachmentService: AttachmentService,
private readonly storageService: StorageService,
private readonly workspaceAbility: WorkspaceAbilityFactory,
private readonly spaceAbility: SpaceAbilityFactory,
private readonly pageRepo: PageRepo,
private readonly attachmentRepo: AttachmentRepo,
private readonly environmentService: EnvironmentService,
) {}
@UseGuards(JwtAuthGuard)
@HttpCode(HttpStatus.OK)
@Post('files/upload')
@UseInterceptors(FileInterceptor)
async uploadFile(
@Req() req: any,
@Res() res: FastifyReply,
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
) {
const maxFileSize = bytes(this.environmentService.getFileUploadSizeLimit());
@UseGuards(JwtAuthGuard)
@HttpCode(HttpStatus.OK)
@Post('files/upload')
@UseInterceptors(FileInterceptor)
async uploadFile(
@Req() req: FastifyRequest,
@Res() res: FastifyReply,
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
) {
//TODO: get file size
// Request hangs if file upload fails
// no workaround seem to work yet
// https://github.com/fastify/fastify-multipart/issues/497
const maxFileSize = bytes(this.environmentService.getFileUploadSizeLimit());
let file = null;
try {
file = await req.file({
limits: {fileSize: maxFileSize, fields: 3, files: 1},
});
} catch (err: any) {
this.logger.error(err.message);
if (err?.statusCode === 413) {
throw new BadRequestException(
`File too large. Exceeds the ${this.environmentService.getFileUploadSizeLimit()} limit`,
);
}
}
let file = null;
try {
file = await req.file({
limits: { fileSize: maxFileSize, fields: 3, files: 1 },
});
if (!file) {
throw new BadRequestException('Failed to upload file');
}
const pageId = file.fields?.pageId?.value;
if (!pageId) {
throw new BadRequestException('PageId is required');
}
const page = await this.pageRepo.findById(pageId);
if (!page) {
throw new NotFoundException('Page not found');
}
const spaceAbility = await this.spaceAbility.createForUser(
user,
page.spaceId,
} catch (err: any) {
this.logger.error(err.message);
if (err?.statusCode === 413) {
throw new BadRequestException(
`File too large. Exceeds the ${this.environmentService.getFileUploadSizeLimit()} limit`,
);
if (spaceAbility.cannot(SpaceCaslAction.Manage, SpaceCaslSubject.Page)) {
throw new ForbiddenException();
}
const spaceId = page.spaceId;
const attachmentId = file.fields?.attachmentId?.value;
if (attachmentId && !isValidUUID(attachmentId)) {
throw new BadRequestException('Invalid attachment id');
}
try {
const fileResponse = await this.attachmentService.uploadFile({
filePromise: file,
pageId: pageId,
spaceId: spaceId,
userId: user.id,
workspaceId: workspace.id,
attachmentId: attachmentId,
});
return res.send(fileResponse);
} catch (err: any) {
if (err?.statusCode === 413) {
const errMessage = `File too large. Exceeds the ${this.environmentService.getFileUploadSizeLimit()} limit`;
this.logger.error(errMessage);
throw new BadRequestException(errMessage);
}
this.logger.error(err);
throw new BadRequestException('Error processing file upload.');
}
}
}
@UseGuards(JwtAuthGuard)
@Get('/files/:fileId/:fileName')
async getFile(
@Res() res: FastifyReply,
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
@Param('fileId') fileId: string,
@Param('fileName') fileName?: string,
if (!file) {
throw new BadRequestException('Failed to upload file');
}
const pageId = file.fields?.pageId?.value;
if (!pageId) {
throw new BadRequestException('PageId is required');
}
const page = await this.pageRepo.findById(pageId);
if (!page) {
throw new NotFoundException('Page not found');
}
const spaceAbility = await this.spaceAbility.createForUser(
user,
page.spaceId,
);
if (spaceAbility.cannot(SpaceCaslAction.Manage, SpaceCaslSubject.Page)) {
throw new ForbiddenException();
}
const spaceId = page.spaceId;
const attachmentId = file.fields?.attachmentId?.value;
if (attachmentId && !isValidUUID(attachmentId)) {
throw new BadRequestException('Invalid attachment id');
}
try {
const fileResponse = await this.attachmentService.uploadFile({
filePromise: file,
pageId: pageId,
spaceId: spaceId,
userId: user.id,
workspaceId: workspace.id,
attachmentId: attachmentId,
});
return res.send(fileResponse);
} catch (err: any) {
if (err?.statusCode === 413) {
const errMessage = `File too large. Exceeds the ${this.environmentService.getFileUploadSizeLimit()} limit`;
this.logger.error(errMessage);
throw new BadRequestException(errMessage);
}
this.logger.error(err);
throw new BadRequestException('Error processing file upload.');
}
}
@UseGuards(JwtAuthGuard)
@Get('/files/:fileId/:fileName')
async getFile(
@Res() res: FastifyReply,
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
@Param('fileId') fileId: string,
@Param('fileName') fileName?: string,
) {
if (!isValidUUID(fileId)) {
throw new NotFoundException('Invalid file id');
}
const attachment = await this.attachmentRepo.findById(fileId);
if (
!attachment ||
attachment.workspaceId !== workspace.id ||
!attachment.pageId ||
!attachment.spaceId
) {
if (!isValidUUID(fileId)) {
throw new NotFoundException('Invalid file id');
}
throw new NotFoundException();
}
const attachment = await this.attachmentRepo.findById(fileId);
if (
!attachment ||
attachment.workspaceId !== workspace.id ||
!attachment.pageId ||
!attachment.spaceId
) {
throw new NotFoundException();
}
const spaceAbility = await this.spaceAbility.createForUser(
user,
attachment.spaceId,
);
const spaceAbility = await this.spaceAbility.createForUser(
user,
attachment.spaceId,
if (spaceAbility.cannot(SpaceCaslAction.Read, SpaceCaslSubject.Page)) {
throw new ForbiddenException();
}
try {
const fileStream = await this.storageService.read(attachment.filePath);
res.headers({
'Content-Type': attachment.mimeType,
'Cache-Control': 'private, max-age=3600',
});
if (!inlineFileExtensions.includes(attachment.fileExt)) {
res.header(
'Content-Disposition',
`attachment; filename="${encodeURIComponent(attachment.fileName)}"`,
);
}
if (spaceAbility.cannot(SpaceCaslAction.Read, SpaceCaslSubject.Page)) {
throw new ForbiddenException();
}
return res.send(fileStream);
} catch (err) {
this.logger.error(err);
throw new NotFoundException('File not found');
}
}
try {
const fileStream = await this.storageService.read(attachment.filePath);
res.headers({
'Content-Type': attachment.mimeType,
'Cache-Control': 'private, max-age=3600',
});
@UseGuards(JwtAuthGuard)
@HttpCode(HttpStatus.OK)
@Post('attachments/upload-image')
@UseInterceptors(FileInterceptor)
async uploadAvatarOrLogo(
@Req() req: any,
@Res() res: FastifyReply,
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
) {
const maxFileSize = bytes(MAX_AVATAR_SIZE);
if (!inlineFileExtensions.includes(attachment.fileExt)) {
res.header(
'Content-Disposition',
`attachment; filename="${encodeURIComponent(attachment.fileName)}"`,
);
}
return res.send(fileStream);
} catch (err) {
this.logger.error(err);
throw new NotFoundException('File not found');
}
let file = null;
try {
file = await req.file({
limits: { fileSize: maxFileSize, fields: 3, files: 1 },
});
} catch (err: any) {
if (err?.statusCode === 413) {
throw new BadRequestException(
`File too large. Exceeds the ${MAX_AVATAR_SIZE} limit`,
);
}
}
@UseGuards(JwtAuthGuard)
@HttpCode(HttpStatus.OK)
@Post('attachments/upload-image')
@UseInterceptors(FileInterceptor)
async uploadAvatarOrLogo(
@Req() req: any,
@Res() res: FastifyReply,
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
if (!file) {
throw new BadRequestException('Invalid file upload');
}
const attachmentType = file.fields?.type?.value;
const spaceId = file.fields?.spaceId?.value;
if (!attachmentType) {
throw new BadRequestException('attachment type is required');
}
if (
!validAttachmentTypes.includes(attachmentType) ||
attachmentType === AttachmentType.File
) {
const maxFileSize = bytes(MAX_AVATAR_SIZE);
let file = null;
try {
file = await req.file({
limits: {fileSize: maxFileSize, fields: 3, files: 1},
});
} catch (err: any) {
if (err?.statusCode === 413) {
throw new BadRequestException(
`File too large. Exceeds the ${MAX_AVATAR_SIZE} limit`,
);
}
}
if (!file) {
throw new BadRequestException('Invalid file upload');
}
const attachmentType = file.fields?.type?.value;
const spaceId = file.fields?.spaceId?.value;
if (!attachmentType) {
throw new BadRequestException('attachment type is required');
}
if (
!validAttachmentTypes.includes(attachmentType) ||
attachmentType === AttachmentType.File
) {
throw new BadRequestException('Invalid image attachment type');
}
if (attachmentType === AttachmentType.WorkspaceLogo) {
const ability = this.workspaceAbility.createForUser(user, workspace);
if (
ability.cannot(
WorkspaceCaslAction.Manage,
WorkspaceCaslSubject.Settings,
)
) {
throw new ForbiddenException();
}
}
if (attachmentType === AttachmentType.SpaceLogo) {
if (!spaceId) {
throw new BadRequestException('spaceId is required');
}
const spaceAbility = await this.spaceAbility.createForUser(user, spaceId);
if (
spaceAbility.cannot(SpaceCaslAction.Manage, SpaceCaslSubject.Settings)
) {
throw new ForbiddenException();
}
}
try {
const fileResponse = await this.attachmentService.uploadImage(
file,
attachmentType,
user.id,
workspace.id,
spaceId,
);
return res.send(fileResponse);
} catch (err: any) {
this.logger.error(err);
throw new BadRequestException('Error processing file upload.');
}
throw new BadRequestException('Invalid image attachment type');
}
@Get('attachments/img/:attachmentType/:fileName')
async getLogoOrAvatar(
@Res() res: FastifyReply,
@AuthWorkspace() workspace: Workspace,
@Param('attachmentType') attachmentType: AttachmentType,
@Param('fileName') fileName?: string,
if (attachmentType === AttachmentType.WorkspaceLogo) {
const ability = this.workspaceAbility.createForUser(user, workspace);
if (
ability.cannot(
WorkspaceCaslAction.Manage,
WorkspaceCaslSubject.Settings,
)
) {
throw new ForbiddenException();
}
}
if (attachmentType === AttachmentType.SpaceLogo) {
if (!spaceId) {
throw new BadRequestException('spaceId is required');
}
const spaceAbility = await this.spaceAbility.createForUser(user, spaceId);
if (
spaceAbility.cannot(SpaceCaslAction.Manage, SpaceCaslSubject.Settings)
) {
throw new ForbiddenException();
}
}
try {
const fileResponse = await this.attachmentService.uploadImage(
file,
attachmentType,
user.id,
workspace.id,
spaceId,
);
return res.send(fileResponse);
} catch (err: any) {
this.logger.error(err);
throw new BadRequestException('Error processing file upload.');
}
}
@Get('attachments/img/:attachmentType/:fileName')
async getLogoOrAvatar(
@Res() res: FastifyReply,
@AuthWorkspace() workspace: Workspace,
@Param('attachmentType') attachmentType: AttachmentType,
@Param('fileName') fileName?: string,
) {
if (
!validAttachmentTypes.includes(attachmentType) ||
attachmentType === AttachmentType.File
) {
if (
!validAttachmentTypes.includes(attachmentType) ||
attachmentType === AttachmentType.File
) {
throw new BadRequestException('Invalid image attachment type');
}
const filePath = `${getAttachmentFolderPath(attachmentType, workspace.id)}/${fileName}`;
try {
const fileStream = await this.storageService.read(filePath);
res.headers({
'Content-Type': getMimeType(filePath),
'Cache-Control': 'private, max-age=86400',
});
return res.send(fileStream);
} catch (err) {
this.logger.error(err);
throw new NotFoundException('File not found');
}
throw new BadRequestException('Invalid image attachment type');
}
const filePath = `${getAttachmentFolderPath(attachmentType, workspace.id)}/${fileName}`;
try {
const fileStream = await this.storageService.read(filePath);
res.headers({
'Content-Type': getMimeType(filePath),
'Cache-Control': 'private, max-age=86400',
});
return res.send(fileStream);
} catch (err) {
this.logger.error(err);
throw new NotFoundException('File not found');
}
}
}

View File

@ -1,11 +1,11 @@
import { MultipartFile } from '@fastify/multipart';
import { randomBytes } from 'crypto';
import { sanitize } from 'sanitize-filename-ts';
import * as path from 'path';
import { AttachmentType } from './attachment.constants';
import { Readable } from 'stream';
export interface PreparedFile {
buffer: Buffer;
stream: Readable;
fileName: string;
fileSize: number;
fileExtension: string;
@ -22,16 +22,14 @@ export async function prepareFile(
}
try {
const rand = randomBytes(8).toString('hex');
const buffer = await file.toBuffer();
const stream = file.file;
const sanitizedFilename = sanitize(file.filename).replace(/ /g, '_');
const fileName = sanitizedFilename.slice(0, 255);
const fileSize = buffer.length;
const fileSize = 300; //buffer.length;
const fileExtension = path.extname(file.filename).toLowerCase();
return {
buffer,
stream,
fileName,
fileSize,
fileExtension,

View File

@ -76,7 +76,7 @@ export class AttachmentService {
const filePath = `${getAttachmentFolderPath(AttachmentType.File, workspaceId)}/${attachmentId}/${preparedFile.fileName}`;
await this.uploadToDrive(filePath, preparedFile.buffer);
await this.uploadToDrive(filePath, preparedFile.stream);
let attachment: Attachment = null;
try {
@ -124,7 +124,7 @@ export class AttachmentService {
const filePath = `${getAttachmentFolderPath(type, workspaceId)}/${preparedFile.fileName}`;
await this.uploadToDrive(filePath, preparedFile.buffer);
await this.uploadToDrive(filePath, preparedFile.stream);
let attachment: Attachment = null;
let oldFileName: string = null;

View File

@ -3,8 +3,11 @@ import {
LocalStorageConfig,
StorageOption,
} from '../interfaces';
import { join } from 'path';
import { join, dirname } from 'path';
import * as fs from 'fs-extra';
import { pipeline } from 'stream/promises';
import { createReadStream, createWriteStream } from 'node:fs';
import { Readable } from 'stream';
export class LocalDriver implements StorageDriver {
private readonly config: LocalStorageConfig;
@ -17,17 +20,19 @@ export class LocalDriver implements StorageDriver {
return join(this.config.storagePath, filePath);
}
async upload(filePath: string, file: Buffer): Promise<void> {
async upload(filePath: string, file: Readable): Promise<void> {
try {
await fs.outputFile(this._fullPath(filePath), file);
const fullPath = this._fullPath(filePath);
await fs.mkdir(dirname(fullPath), { recursive: true });
await pipeline(file, createWriteStream(fullPath));
} catch (err) {
throw new Error(`Failed to upload file: ${(err as Error).message}`);
}
}
async read(filePath: string): Promise<Buffer> {
async read(filePath: string): Promise<Readable> {
try {
return await fs.readFile(this._fullPath(filePath));
return createReadStream(this._fullPath(filePath));
} catch (err) {
throw new Error(`Failed to read file: ${(err as Error).message}`);
}

View File

@ -4,13 +4,12 @@ import {
GetObjectCommand,
HeadObjectCommand,
NoSuchKey,
PutObjectCommand,
S3Client,
} from '@aws-sdk/client-s3';
import { streamToBuffer } from '../storage.utils';
import { Readable } from 'stream';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { getMimeType } from '../../../common/helpers';
import { Upload } from '@aws-sdk/lib-storage';
export class S3Driver implements StorageDriver {
private readonly s3Client: S3Client;
@ -21,25 +20,27 @@ export class S3Driver implements StorageDriver {
this.s3Client = new S3Client(config as any);
}
async upload(filePath: string, file: Buffer): Promise<void> {
async upload(filePath: string, file: Readable): Promise<void> {
try {
const contentType = getMimeType(filePath);
const command = new PutObjectCommand({
Bucket: this.config.bucket,
Key: filePath,
Body: file,
ContentType: contentType,
// ACL: "public-read",
const upload = new Upload({
client: this.s3Client,
params: {
Bucket: this.config.bucket,
Key: filePath,
Body: file,
ContentType: contentType,
},
});
await this.s3Client.send(command);
await upload.done();
} catch (err) {
throw new Error(`Failed to upload file: ${(err as Error).message}`);
}
}
async read(filePath: string): Promise<Buffer> {
async read(filePath: string): Promise<Readable> {
try {
const command = new GetObjectCommand({
Bucket: this.config.bucket,
@ -48,7 +49,7 @@ export class S3Driver implements StorageDriver {
const response = await this.s3Client.send(command);
return streamToBuffer(response.Body as Readable);
return response.Body as Readable;
} catch (err) {
throw new Error(`Failed to read file from S3: ${(err as Error).message}`);
}

View File

@ -1,7 +1,9 @@
export interface StorageDriver {
upload(filePath: string, file: Buffer): Promise<void>;
import { Readable } from 'stream';
read(filePath: string): Promise<Buffer>;
export interface StorageDriver {
upload(filePath: string, file: Readable): Promise<void>;
read(filePath: string): Promise<Readable>;
exists(filePath: string): Promise<boolean>;

View File

@ -1,6 +1,7 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { STORAGE_DRIVER_TOKEN } from './constants/storage.constants';
import { StorageDriver } from './interfaces';
import { Readable } from 'stream';
@Injectable()
export class StorageService {
@ -9,12 +10,12 @@ export class StorageService {
@Inject(STORAGE_DRIVER_TOKEN) private storageDriver: StorageDriver,
) {}
async upload(filePath: string, fileContent: Buffer | any) {
async upload(filePath: string, fileContent: Readable) {
await this.storageDriver.upload(filePath, fileContent);
this.logger.debug(`File uploaded successfully. Path: ${filePath}`);
}
async read(filePath: string): Promise<Buffer> {
async read(filePath: string): Promise<Readable> {
return this.storageDriver.read(filePath);
}

294
pnpm-lock.yaml generated
View File

@ -399,6 +399,9 @@ importers:
'@aws-sdk/client-s3':
specifier: 3.701.0
version: 3.701.0
'@aws-sdk/lib-storage':
specifier: ^3.779.0
version: 3.779.0(@aws-sdk/client-s3@3.701.0)
'@aws-sdk/s3-request-presigner':
specifier: 3.701.0
version: 3.701.0
@ -766,6 +769,12 @@ packages:
peerDependencies:
'@aws-sdk/client-sts': ^3.696.0
'@aws-sdk/lib-storage@3.779.0':
resolution: {integrity: sha512-AZfykrCgfnhlb5d5uyThHsqIwt41PYgnUTMyDuk4hbuKbiY8pfOiPdg8BYsC59iD2T4Iw9NujYhWUD+l8zNKcw==}
engines: {node: '>=18.0.0'}
peerDependencies:
'@aws-sdk/client-s3': ^3.779.0
'@aws-sdk/middleware-bucket-endpoint@3.696.0':
resolution: {integrity: sha512-V07jishKHUS5heRNGFpCWCSTjRJyQLynS/ncUeE8ZYtG66StOOQWftTwDfFOSoXlIqrXgb4oT9atryzXq7Z4LQ==}
engines: {node: '>=16.0.0'}
@ -3335,6 +3344,10 @@ packages:
resolution: {integrity: sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw==}
engines: {node: '>=16.0.0'}
'@smithy/abort-controller@4.0.2':
resolution: {integrity: sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw==}
engines: {node: '>=18.0.0'}
'@smithy/chunked-blob-reader-native@3.0.1':
resolution: {integrity: sha512-VEYtPvh5rs/xlyqpm5NRnfYLZn+q0SRPELbvBV+C/G7IQ+ouTuo+NKKa3ShG5OaFR8NYVMXls9hPYLTvIKKDrQ==}
@ -3349,6 +3362,10 @@ packages:
resolution: {integrity: sha512-8olpW6mKCa0v+ibCjoCzgZHQx1SQmZuW/WkrdZo73wiTprTH6qhmskT60QLFdT9DRa5mXxjz89kQPZ7ZSsoqqg==}
engines: {node: '>=16.0.0'}
'@smithy/core@3.2.0':
resolution: {integrity: sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q==}
engines: {node: '>=18.0.0'}
'@smithy/credential-provider-imds@3.2.8':
resolution: {integrity: sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw==}
engines: {node: '>=16.0.0'}
@ -3375,6 +3392,10 @@ packages:
'@smithy/fetch-http-handler@4.1.3':
resolution: {integrity: sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA==}
'@smithy/fetch-http-handler@5.0.2':
resolution: {integrity: sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ==}
engines: {node: '>=18.0.0'}
'@smithy/hash-blob-browser@3.1.10':
resolution: {integrity: sha512-elwslXOoNunmfS0fh55jHggyhccobFkexLYC1ZeZ1xP2BTSrcIBaHV2b4xUQOdctrSNOpMqOZH1r2XzWTEhyfA==}
@ -3397,6 +3418,10 @@ packages:
resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==}
engines: {node: '>=16.0.0'}
'@smithy/is-array-buffer@4.0.0':
resolution: {integrity: sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==}
engines: {node: '>=18.0.0'}
'@smithy/md5-js@3.0.11':
resolution: {integrity: sha512-3NM0L3i2Zm4bbgG6Ymi9NBcxXhryi3uE8fIfHJZIOfZVxOkGdjdgjR9A06SFIZCfnEIWKXZdm6Yq5/aPXFFhsQ==}
@ -3408,6 +3433,10 @@ packages:
resolution: {integrity: sha512-OEJZKVUEhMOqMs3ktrTWp7UvvluMJEvD5XgQwRePSbDg1VvBaL8pX8mwPltFn6wk1GySbcVwwyldL8S+iqnrEQ==}
engines: {node: '>=16.0.0'}
'@smithy/middleware-endpoint@4.1.0':
resolution: {integrity: sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA==}
engines: {node: '>=18.0.0'}
'@smithy/middleware-retry@3.0.34':
resolution: {integrity: sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA==}
engines: {node: '>=16.0.0'}
@ -3416,34 +3445,66 @@ packages:
resolution: {integrity: sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw==}
engines: {node: '>=16.0.0'}
'@smithy/middleware-serde@4.0.3':
resolution: {integrity: sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A==}
engines: {node: '>=18.0.0'}
'@smithy/middleware-stack@3.0.11':
resolution: {integrity: sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA==}
engines: {node: '>=16.0.0'}
'@smithy/middleware-stack@4.0.2':
resolution: {integrity: sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ==}
engines: {node: '>=18.0.0'}
'@smithy/node-config-provider@3.1.12':
resolution: {integrity: sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ==}
engines: {node: '>=16.0.0'}
'@smithy/node-config-provider@4.0.2':
resolution: {integrity: sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw==}
engines: {node: '>=18.0.0'}
'@smithy/node-http-handler@3.3.3':
resolution: {integrity: sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ==}
engines: {node: '>=16.0.0'}
'@smithy/node-http-handler@4.0.4':
resolution: {integrity: sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g==}
engines: {node: '>=18.0.0'}
'@smithy/property-provider@3.1.11':
resolution: {integrity: sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==}
engines: {node: '>=16.0.0'}
'@smithy/property-provider@4.0.2':
resolution: {integrity: sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A==}
engines: {node: '>=18.0.0'}
'@smithy/protocol-http@4.1.8':
resolution: {integrity: sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==}
engines: {node: '>=16.0.0'}
'@smithy/protocol-http@5.1.0':
resolution: {integrity: sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g==}
engines: {node: '>=18.0.0'}
'@smithy/querystring-builder@3.0.11':
resolution: {integrity: sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg==}
engines: {node: '>=16.0.0'}
'@smithy/querystring-builder@4.0.2':
resolution: {integrity: sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q==}
engines: {node: '>=18.0.0'}
'@smithy/querystring-parser@3.0.11':
resolution: {integrity: sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw==}
engines: {node: '>=16.0.0'}
'@smithy/querystring-parser@4.0.2':
resolution: {integrity: sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q==}
engines: {node: '>=18.0.0'}
'@smithy/service-error-classification@3.0.11':
resolution: {integrity: sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==}
engines: {node: '>=16.0.0'}
@ -3452,6 +3513,10 @@ packages:
resolution: {integrity: sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==}
engines: {node: '>=16.0.0'}
'@smithy/shared-ini-file-loader@4.0.2':
resolution: {integrity: sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw==}
engines: {node: '>=18.0.0'}
'@smithy/signature-v4@4.2.4':
resolution: {integrity: sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==}
engines: {node: '>=16.0.0'}
@ -3460,6 +3525,10 @@ packages:
resolution: {integrity: sha512-9wYrjAZFlqWhgVo3C4y/9kpc68jgiSsKUnsFPzr/MSiRL93+QRDafGTfhhKAb2wsr69Ru87WTiqSfQusSmWipA==}
engines: {node: '>=16.0.0'}
'@smithy/smithy-client@4.2.0':
resolution: {integrity: sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw==}
engines: {node: '>=18.0.0'}
'@smithy/types@3.7.2':
resolution: {integrity: sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==}
engines: {node: '>=16.0.0'}
@ -3468,16 +3537,32 @@ packages:
resolution: {integrity: sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw==}
engines: {node: '>=18.0.0'}
'@smithy/types@4.2.0':
resolution: {integrity: sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg==}
engines: {node: '>=18.0.0'}
'@smithy/url-parser@3.0.11':
resolution: {integrity: sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw==}
'@smithy/url-parser@4.0.2':
resolution: {integrity: sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ==}
engines: {node: '>=18.0.0'}
'@smithy/util-base64@3.0.0':
resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==}
engines: {node: '>=16.0.0'}
'@smithy/util-base64@4.0.0':
resolution: {integrity: sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==}
engines: {node: '>=18.0.0'}
'@smithy/util-body-length-browser@3.0.0':
resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==}
'@smithy/util-body-length-browser@4.0.0':
resolution: {integrity: sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==}
engines: {node: '>=18.0.0'}
'@smithy/util-body-length-node@3.0.0':
resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==}
engines: {node: '>=16.0.0'}
@ -3490,6 +3575,10 @@ packages:
resolution: {integrity: sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==}
engines: {node: '>=16.0.0'}
'@smithy/util-buffer-from@4.0.0':
resolution: {integrity: sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==}
engines: {node: '>=18.0.0'}
'@smithy/util-config-provider@3.0.0':
resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==}
engines: {node: '>=16.0.0'}
@ -3510,10 +3599,18 @@ packages:
resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==}
engines: {node: '>=16.0.0'}
'@smithy/util-hex-encoding@4.0.0':
resolution: {integrity: sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==}
engines: {node: '>=18.0.0'}
'@smithy/util-middleware@3.0.11':
resolution: {integrity: sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==}
engines: {node: '>=16.0.0'}
'@smithy/util-middleware@4.0.2':
resolution: {integrity: sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ==}
engines: {node: '>=18.0.0'}
'@smithy/util-retry@3.0.11':
resolution: {integrity: sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==}
engines: {node: '>=16.0.0'}
@ -3522,10 +3619,18 @@ packages:
resolution: {integrity: sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ==}
engines: {node: '>=16.0.0'}
'@smithy/util-stream@4.2.0':
resolution: {integrity: sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ==}
engines: {node: '>=18.0.0'}
'@smithy/util-uri-escape@3.0.0':
resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==}
engines: {node: '>=16.0.0'}
'@smithy/util-uri-escape@4.0.0':
resolution: {integrity: sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==}
engines: {node: '>=18.0.0'}
'@smithy/util-utf8@2.3.0':
resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==}
engines: {node: '>=14.0.0'}
@ -3534,6 +3639,10 @@ packages:
resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==}
engines: {node: '>=16.0.0'}
'@smithy/util-utf8@4.0.0':
resolution: {integrity: sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==}
engines: {node: '>=18.0.0'}
'@smithy/util-waiter@3.2.0':
resolution: {integrity: sha512-PpjSboaDUE6yl+1qlg3Si57++e84oXdWGbuFUSAciXsVfEZJJJupR2Nb0QuXHiunt2vGR+1PTizOMvnUPaG2Qg==}
engines: {node: '>=16.0.0'}
@ -4776,6 +4885,9 @@ packages:
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
buffer@5.6.0:
resolution: {integrity: sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==}
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
@ -8208,6 +8320,9 @@ packages:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
stream-browserify@3.0.0:
resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==}
streamsearch@1.1.0:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
@ -9479,6 +9594,17 @@ snapshots:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@aws-sdk/lib-storage@3.779.0(@aws-sdk/client-s3@3.701.0)':
dependencies:
'@aws-sdk/client-s3': 3.701.0
'@smithy/abort-controller': 4.0.2
'@smithy/middleware-endpoint': 4.1.0
'@smithy/smithy-client': 4.2.0
buffer: 5.6.0
events: 3.3.0
stream-browserify: 3.0.0
tslib: 2.8.1
'@aws-sdk/middleware-bucket-endpoint@3.696.0':
dependencies:
'@aws-sdk/types': 3.696.0
@ -12099,7 +12225,7 @@ snapshots:
nx: 20.4.5(@swc/core@1.5.25(@swc/helpers@0.5.5))
semver: 7.6.3
tmp: 0.2.1
tslib: 2.8.0
tslib: 2.8.1
yargs-parser: 21.1.1
'@nx/js@20.4.5(@babel/traverse@7.25.9)(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.13.4)(nx@20.4.5(@swc/core@1.5.25(@swc/helpers@0.5.5)))(typescript@5.7.3)':
@ -12181,7 +12307,7 @@ snapshots:
chalk: 4.1.2
enquirer: 2.3.6
nx: 20.4.5(@swc/core@1.5.25(@swc/helpers@0.5.5))
tslib: 2.8.0
tslib: 2.8.1
yargs-parser: 21.1.1
transitivePeerDependencies:
- '@swc-node/register'
@ -12405,6 +12531,11 @@ snapshots:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/abort-controller@4.0.2':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/chunked-blob-reader-native@3.0.1':
dependencies:
'@smithy/util-base64': 3.0.0
@ -12433,6 +12564,17 @@ snapshots:
'@smithy/util-utf8': 3.0.0
tslib: 2.8.1
'@smithy/core@3.2.0':
dependencies:
'@smithy/middleware-serde': 4.0.3
'@smithy/protocol-http': 5.1.0
'@smithy/types': 4.2.0
'@smithy/util-body-length-browser': 4.0.0
'@smithy/util-middleware': 4.0.2
'@smithy/util-stream': 4.2.0
'@smithy/util-utf8': 4.0.0
tslib: 2.8.1
'@smithy/credential-provider-imds@3.2.8':
dependencies:
'@smithy/node-config-provider': 3.1.12
@ -12479,6 +12621,14 @@ snapshots:
'@smithy/util-base64': 3.0.0
tslib: 2.8.1
'@smithy/fetch-http-handler@5.0.2':
dependencies:
'@smithy/protocol-http': 5.1.0
'@smithy/querystring-builder': 4.0.2
'@smithy/types': 4.2.0
'@smithy/util-base64': 4.0.0
tslib: 2.8.1
'@smithy/hash-blob-browser@3.1.10':
dependencies:
'@smithy/chunked-blob-reader': 4.0.0
@ -12512,6 +12662,10 @@ snapshots:
dependencies:
tslib: 2.8.1
'@smithy/is-array-buffer@4.0.0':
dependencies:
tslib: 2.8.1
'@smithy/md5-js@3.0.11':
dependencies:
'@smithy/types': 3.7.2
@ -12535,6 +12689,17 @@ snapshots:
'@smithy/util-middleware': 3.0.11
tslib: 2.8.1
'@smithy/middleware-endpoint@4.1.0':
dependencies:
'@smithy/core': 3.2.0
'@smithy/middleware-serde': 4.0.3
'@smithy/node-config-provider': 4.0.2
'@smithy/shared-ini-file-loader': 4.0.2
'@smithy/types': 4.2.0
'@smithy/url-parser': 4.0.2
'@smithy/util-middleware': 4.0.2
tslib: 2.8.1
'@smithy/middleware-retry@3.0.34':
dependencies:
'@smithy/node-config-provider': 3.1.12
@ -12552,11 +12717,21 @@ snapshots:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/middleware-serde@4.0.3':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/middleware-stack@3.0.11':
dependencies:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/middleware-stack@4.0.2':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/node-config-provider@3.1.12':
dependencies:
'@smithy/property-provider': 3.1.11
@ -12564,6 +12739,13 @@ snapshots:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/node-config-provider@4.0.2':
dependencies:
'@smithy/property-provider': 4.0.2
'@smithy/shared-ini-file-loader': 4.0.2
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/node-http-handler@3.3.3':
dependencies:
'@smithy/abort-controller': 3.1.9
@ -12572,27 +12754,56 @@ snapshots:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/node-http-handler@4.0.4':
dependencies:
'@smithy/abort-controller': 4.0.2
'@smithy/protocol-http': 5.1.0
'@smithy/querystring-builder': 4.0.2
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/property-provider@3.1.11':
dependencies:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/property-provider@4.0.2':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/protocol-http@4.1.8':
dependencies:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/protocol-http@5.1.0':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/querystring-builder@3.0.11':
dependencies:
'@smithy/types': 3.7.2
'@smithy/util-uri-escape': 3.0.0
tslib: 2.8.1
'@smithy/querystring-builder@4.0.2':
dependencies:
'@smithy/types': 4.2.0
'@smithy/util-uri-escape': 4.0.0
tslib: 2.8.1
'@smithy/querystring-parser@3.0.11':
dependencies:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/querystring-parser@4.0.2':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/service-error-classification@3.0.11':
dependencies:
'@smithy/types': 3.7.2
@ -12602,6 +12813,11 @@ snapshots:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/shared-ini-file-loader@4.0.2':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/signature-v4@4.2.4':
dependencies:
'@smithy/is-array-buffer': 3.0.0
@ -12623,6 +12839,16 @@ snapshots:
'@smithy/util-stream': 3.3.4
tslib: 2.8.1
'@smithy/smithy-client@4.2.0':
dependencies:
'@smithy/core': 3.2.0
'@smithy/middleware-endpoint': 4.1.0
'@smithy/middleware-stack': 4.0.2
'@smithy/protocol-http': 5.1.0
'@smithy/types': 4.2.0
'@smithy/util-stream': 4.2.0
tslib: 2.8.1
'@smithy/types@3.7.2':
dependencies:
tslib: 2.8.1
@ -12631,22 +12857,42 @@ snapshots:
dependencies:
tslib: 2.8.1
'@smithy/types@4.2.0':
dependencies:
tslib: 2.8.1
'@smithy/url-parser@3.0.11':
dependencies:
'@smithy/querystring-parser': 3.0.11
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/url-parser@4.0.2':
dependencies:
'@smithy/querystring-parser': 4.0.2
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/util-base64@3.0.0':
dependencies:
'@smithy/util-buffer-from': 3.0.0
'@smithy/util-utf8': 3.0.0
tslib: 2.8.1
'@smithy/util-base64@4.0.0':
dependencies:
'@smithy/util-buffer-from': 4.0.0
'@smithy/util-utf8': 4.0.0
tslib: 2.8.1
'@smithy/util-body-length-browser@3.0.0':
dependencies:
tslib: 2.8.1
'@smithy/util-body-length-browser@4.0.0':
dependencies:
tslib: 2.8.1
'@smithy/util-body-length-node@3.0.0':
dependencies:
tslib: 2.8.1
@ -12661,6 +12907,11 @@ snapshots:
'@smithy/is-array-buffer': 3.0.0
tslib: 2.8.1
'@smithy/util-buffer-from@4.0.0':
dependencies:
'@smithy/is-array-buffer': 4.0.0
tslib: 2.8.1
'@smithy/util-config-provider@3.0.0':
dependencies:
tslib: 2.8.1
@ -12693,11 +12944,20 @@ snapshots:
dependencies:
tslib: 2.8.1
'@smithy/util-hex-encoding@4.0.0':
dependencies:
tslib: 2.8.1
'@smithy/util-middleware@3.0.11':
dependencies:
'@smithy/types': 3.7.2
tslib: 2.8.1
'@smithy/util-middleware@4.0.2':
dependencies:
'@smithy/types': 4.2.0
tslib: 2.8.1
'@smithy/util-retry@3.0.11':
dependencies:
'@smithy/service-error-classification': 3.0.11
@ -12715,10 +12975,25 @@ snapshots:
'@smithy/util-utf8': 3.0.0
tslib: 2.8.1
'@smithy/util-stream@4.2.0':
dependencies:
'@smithy/fetch-http-handler': 5.0.2
'@smithy/node-http-handler': 4.0.4
'@smithy/types': 4.2.0
'@smithy/util-base64': 4.0.0
'@smithy/util-buffer-from': 4.0.0
'@smithy/util-hex-encoding': 4.0.0
'@smithy/util-utf8': 4.0.0
tslib: 2.8.1
'@smithy/util-uri-escape@3.0.0':
dependencies:
tslib: 2.8.1
'@smithy/util-uri-escape@4.0.0':
dependencies:
tslib: 2.8.1
'@smithy/util-utf8@2.3.0':
dependencies:
'@smithy/util-buffer-from': 2.2.0
@ -12729,6 +13004,11 @@ snapshots:
'@smithy/util-buffer-from': 3.0.0
tslib: 2.8.1
'@smithy/util-utf8@4.0.0':
dependencies:
'@smithy/util-buffer-from': 4.0.0
tslib: 2.8.1
'@smithy/util-waiter@3.2.0':
dependencies:
'@smithy/abort-controller': 3.1.9
@ -14214,6 +14494,11 @@ snapshots:
buffer-from@1.1.2: {}
buffer@5.6.0:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
buffer@5.7.1:
dependencies:
base64-js: 1.5.1
@ -18221,6 +18506,11 @@ snapshots:
statuses@2.0.1: {}
stream-browserify@3.0.0:
dependencies:
inherits: 2.0.4
readable-stream: 3.6.2
streamsearch@1.1.0: {}
string-length@4.0.2: