diff --git a/.env.example b/.env.example index 5bc884c..3c356d9 100644 --- a/.env.example +++ b/.env.example @@ -21,6 +21,9 @@ AWS_S3_BUCKET= AWS_S3_ENDPOINT= AWS_S3_FORCE_PATH_STYLE= +# default: 50mb +FILE_UPLOAD_SIZE_LIMIT= + # options: smtp | postmark MAIL_DRIVER=smtp MAIL_FROM_ADDRESS=hello@example.com diff --git a/apps/client/src/features/editor/components/attachment/upload-attachment-action.tsx b/apps/client/src/features/editor/components/attachment/upload-attachment-action.tsx index 921d30f..2386361 100644 --- a/apps/client/src/features/editor/components/attachment/upload-attachment-action.tsx +++ b/apps/client/src/features/editor/components/attachment/upload-attachment-action.tsx @@ -1,6 +1,8 @@ import { handleAttachmentUpload } from "@docmost/editor-ext"; import { uploadFile } from "@/features/page/services/page-service.ts"; import { notifications } from "@mantine/notifications"; +import {getFileUploadSizeLimit} from "@/lib/config.ts"; +import {formatBytes} from "@/lib"; export const uploadAttachmentAction = handleAttachmentUpload({ onUpload: async (file: File, pageId: string): Promise => { @@ -18,10 +20,10 @@ export const uploadAttachmentAction = handleAttachmentUpload({ if (file.type.includes("image/") || file.type.includes("video/")) { return false; } - if (file.size / 1024 / 1024 > 50) { + if (file.size > getFileUploadSizeLimit()) { notifications.show({ color: "red", - message: `File exceeds the 50 MB attachment limit`, + message: `File exceeds the ${formatBytes(getFileUploadSizeLimit())} attachment limit`, }); return false; } diff --git a/apps/client/src/features/editor/components/image/upload-image-action.tsx b/apps/client/src/features/editor/components/image/upload-image-action.tsx index ea7f621..6c6e8db 100644 --- a/apps/client/src/features/editor/components/image/upload-image-action.tsx +++ b/apps/client/src/features/editor/components/image/upload-image-action.tsx @@ -1,6 +1,8 @@ import { handleImageUpload } from "@docmost/editor-ext"; import { uploadFile } from "@/features/page/services/page-service.ts"; import { notifications } from "@mantine/notifications"; +import {getFileUploadSizeLimit} from "@/lib/config.ts"; +import { formatBytes } from "@/lib"; export const uploadImageAction = handleImageUpload({ onUpload: async (file: File, pageId: string): Promise => { @@ -18,10 +20,10 @@ export const uploadImageAction = handleImageUpload({ if (!file.type.includes("image/")) { return false; } - if (file.size / 1024 / 1024 > 50) { + if (file.size > getFileUploadSizeLimit()) { notifications.show({ color: "red", - message: `File exceeds the 50 MB attachment limit`, + message: `File exceeds the ${formatBytes(getFileUploadSizeLimit())} attachment limit`, }); return false; } diff --git a/apps/client/src/features/editor/components/video/upload-video-action.tsx b/apps/client/src/features/editor/components/video/upload-video-action.tsx index 3a59ad1..4173207 100644 --- a/apps/client/src/features/editor/components/video/upload-video-action.tsx +++ b/apps/client/src/features/editor/components/video/upload-video-action.tsx @@ -1,6 +1,8 @@ import { handleVideoUpload } from "@docmost/editor-ext"; import { uploadFile } from "@/features/page/services/page-service.ts"; import { notifications } from "@mantine/notifications"; +import {getFileUploadSizeLimit} from "@/lib/config.ts"; +import {formatBytes} from "@/lib"; export const uploadVideoAction = handleVideoUpload({ onUpload: async (file: File, pageId: string): Promise => { @@ -19,13 +21,14 @@ export const uploadVideoAction = handleVideoUpload({ return false; } - if (file.size / 1024 / 1024 > 50) { + if (file.size > getFileUploadSizeLimit()) { notifications.show({ color: "red", - message: `File exceeds the 50 MB attachment limit`, + message: `File exceeds the ${formatBytes(getFileUploadSizeLimit())} attachment limit`, }); return false; } return true; }, }); + diff --git a/apps/client/src/lib/config.ts b/apps/client/src/lib/config.ts index add2bf7..64c7c4e 100644 --- a/apps/client/src/lib/config.ts +++ b/apps/client/src/lib/config.ts @@ -1,51 +1,58 @@ +import bytes from "bytes"; + declare global { - interface Window { - CONFIG?: Record; - } + interface Window { + CONFIG?: Record; + } } export function getAppUrl(): string { - //let appUrl = window.CONFIG?.APP_URL || process.env.APP_URL; + //let appUrl = window.CONFIG?.APP_URL || process.env.APP_URL; - // if (import.meta.env.DEV) { - // return appUrl || "http://localhost:3000"; - //} + // if (import.meta.env.DEV) { + // return appUrl || "http://localhost:3000"; + //} - return `${window.location.protocol}//${window.location.host}`; + return `${window.location.protocol}//${window.location.host}`; } export function getBackendUrl(): string { - return getAppUrl() + '/api'; + return getAppUrl() + '/api'; } export function getCollaborationUrl(): string { - const COLLAB_PATH = '/collab'; + const COLLAB_PATH = '/collab'; - let url = getAppUrl(); - if (import.meta.env.DEV) { - url = process.env.APP_URL; - } + let url = getAppUrl(); + if (import.meta.env.DEV) { + url = process.env.APP_URL; + } - const wsProtocol = url.startsWith('https') ? 'wss' : 'ws'; - return `${wsProtocol}://${url.split('://')[1]}${COLLAB_PATH}`; + const wsProtocol = url.startsWith('https') ? 'wss' : 'ws'; + return `${wsProtocol}://${url.split('://')[1]}${COLLAB_PATH}`; } export function getAvatarUrl(avatarUrl: string) { - if (!avatarUrl) { - return null; - } + if (!avatarUrl) { + return null; + } - if (avatarUrl?.startsWith('http')) { - return avatarUrl; - } + if (avatarUrl?.startsWith('http')) { + return avatarUrl; + } - return getBackendUrl() + '/attachments/img/avatar/' + avatarUrl; + return getBackendUrl() + '/attachments/img/avatar/' + avatarUrl; } export function getSpaceUrl(spaceSlug: string) { - return '/s/' + spaceSlug; + return '/s/' + spaceSlug; } export function getFileUrl(src: string) { - return src?.startsWith('/files/') ? getBackendUrl() + src : src; + return src?.startsWith('/files/') ? getBackendUrl() + src : src; } + +export function getFileUploadSizeLimit() { + const limit = window.CONFIG?.FILE_UPLOAD_SIZE_LIMIT || process?.env.FILE_UPLOAD_SIZE_LIMIT || '50mb'; + return bytes(limit); +} \ No newline at end of file diff --git a/apps/client/vite.config.ts b/apps/client/vite.config.ts index 9da366e..4ffa6b5 100644 --- a/apps/client/vite.config.ts +++ b/apps/client/vite.config.ts @@ -5,12 +5,13 @@ import * as path from "path"; export const envPath = path.resolve(process.cwd(), "..", ".."); export default defineConfig(({ mode }) => { - const { APP_URL } = loadEnv(mode, envPath, ""); + const { APP_URL, FILE_UPLOAD_SIZE_LIMIT } = loadEnv(mode, envPath, ""); return { define: { "process.env": { APP_URL, + FILE_UPLOAD_SIZE_LIMIT }, 'APP_VERSION': JSON.stringify(process.env.npm_package_version), }, diff --git a/apps/server/package.json b/apps/server/package.json index 61baefb..f1ca9ee 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -51,7 +51,6 @@ "@socket.io/redis-adapter": "^8.3.0", "bcrypt": "^5.1.1", "bullmq": "^5.12.12", - "bytes": "^3.1.2", "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "fix-esm": "^1.0.1", @@ -81,7 +80,6 @@ "@nestjs/schematics": "^10.1.4", "@nestjs/testing": "^10.4.1", "@types/bcrypt": "^5.0.2", - "@types/bytes": "^3.1.4", "@types/debounce": "^1.2.4", "@types/fs-extra": "^11.0.4", "@types/jest": "^29.5.12", diff --git a/apps/server/src/core/attachment/attachment.constants.ts b/apps/server/src/core/attachment/attachment.constants.ts index 73c2c30..2710d88 100644 --- a/apps/server/src/core/attachment/attachment.constants.ts +++ b/apps/server/src/core/attachment/attachment.constants.ts @@ -16,4 +16,3 @@ export const inlineFileExtensions = [ '.mp4', '.mov', ]; -export const MAX_FILE_SIZE = '50MB'; diff --git a/apps/server/src/core/attachment/attachment.controller.ts b/apps/server/src/core/attachment/attachment.controller.ts index 7777378..0227f59 100644 --- a/apps/server/src/core/attachment/attachment.controller.ts +++ b/apps/server/src/core/attachment/attachment.controller.ts @@ -1,308 +1,310 @@ 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} 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, - MAX_FILE_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 {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, - ) {} - - @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(MAX_FILE_SIZE); - - 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 ${MAX_FILE_SIZE} limit`, - ); - } - } - - 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 ${MAX_FILE_SIZE} 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 + 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, ) { - throw new NotFoundException(); } - 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': 'public, max-age=3600', - }); - - 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'); - } - } - - @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); - - 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 + @UseGuards(JwtAuthGuard) + @HttpCode(HttpStatus.OK) + @Post('files/upload') + @UseInterceptors(FileInterceptor) + async uploadFile( + @Req() req: any, + @Res() res: FastifyReply, + @AuthUser() user: User, + @AuthWorkspace() workspace: Workspace, ) { - throw new BadRequestException('Invalid image attachment type'); + 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`, + ); + } + } + + 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.'); + } } - 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 + @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, ) { - throw new BadRequestException('Invalid image attachment type'); + 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 + ) { + throw new NotFoundException(); + } + + 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': 'public, max-age=3600', + }); + + 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'); + } } - const filePath = `${getAttachmentFolderPath(attachmentType, workspace.id)}/${fileName}`; + @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); - try { - const fileStream = await this.storageService.read(filePath); - res.headers({ - 'Content-Type': getMimeType(filePath), - 'Cache-Control': 'public, max-age=86400', - }); - 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`, + ); + } + } + + 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.'); + } + } + + @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 + ) { + 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': 'public, max-age=86400', + }); + return res.send(fileStream); + } catch (err) { + this.logger.error(err); + throw new NotFoundException('File not found'); + } } - } } diff --git a/apps/server/src/integrations/environment/environment.service.ts b/apps/server/src/integrations/environment/environment.service.ts index 3385d0e..3daa822 100644 --- a/apps/server/src/integrations/environment/environment.service.ts +++ b/apps/server/src/integrations/environment/environment.service.ts @@ -43,6 +43,11 @@ export class EnvironmentService { return this.configService.get('STORAGE_DRIVER', 'local'); } + getFileUploadSizeLimit(): string { + + return this.configService.get('FILE_UPLOAD_SIZE_LIMIT', '50mb'); + } + getAwsS3AccessKeyId(): string { return this.configService.get('AWS_S3_ACCESS_KEY_ID'); } diff --git a/apps/server/src/integrations/import/import.controller.ts b/apps/server/src/integrations/import/import.controller.ts index 902376d..975301a 100644 --- a/apps/server/src/integrations/import/import.controller.ts +++ b/apps/server/src/integrations/import/import.controller.ts @@ -21,7 +21,6 @@ import { import { FileInterceptor } from '../../common/interceptors/file.interceptor'; import * as bytes from 'bytes'; import * as path from 'path'; -import { MAX_FILE_SIZE } from '../../core/attachment/attachment.constants'; import { ImportService } from './import.service'; import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator'; @@ -45,7 +44,7 @@ export class ImportController { ) { const validFileExtensions = ['.md', '.html']; - const maxFileSize = bytes(MAX_FILE_SIZE); + const maxFileSize = bytes('100mb'); let file = null; try { @@ -56,7 +55,7 @@ export class ImportController { this.logger.error(err.message); if (err?.statusCode === 413) { throw new BadRequestException( - `File too large. Exceeds the ${MAX_FILE_SIZE} limit`, + `File too large. Exceeds the 100mb import limit`, ); } } diff --git a/apps/server/src/integrations/static/static.module.ts b/apps/server/src/integrations/static/static.module.ts index 9ab43eb..1753605 100644 --- a/apps/server/src/integrations/static/static.module.ts +++ b/apps/server/src/integrations/static/static.module.ts @@ -33,6 +33,7 @@ export class StaticModule implements OnModuleInit { ENV: this.environmentService.getNodeEnv(), APP_URL: this.environmentService.getAppUrl(), IS_CLOUD: this.environmentService.isCloud(), + FILE_UPLOAD_SIZE_LIMIT: this.environmentService.getFileUploadSizeLimit() }; const windowScriptContent = ``; diff --git a/package.json b/package.json index e4c6c59..d15d997 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "@tiptap/react": "^2.6.6", "@tiptap/starter-kit": "^2.6.6", "@tiptap/suggestion": "^2.6.6", + "bytes": "^3.1.2", "cross-env": "^7.0.3", "fractional-indexing-jittered": "^0.9.1", "ioredis": "^5.4.1", @@ -68,6 +69,7 @@ }, "devDependencies": { "@nx/js": "19.6.3", + "@types/bytes": "^3.1.4", "@types/uuid": "^10.0.0", "concurrently": "^8.2.2", "nx": "19.6.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03645aa..73535bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -137,6 +137,9 @@ importers: '@tiptap/suggestion': specifier: ^2.6.6 version: 2.6.6(@tiptap/core@2.6.6(@tiptap/pm@2.6.6))(@tiptap/pm@2.6.6) + bytes: + specifier: ^3.1.2 + version: 3.1.2 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -158,7 +161,10 @@ importers: devDependencies: '@nx/js': specifier: 19.6.3 - version: 19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25)(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25))(typescript@5.5.4) + version: 19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)))(typescript@5.5.4) + '@types/bytes': + specifier: ^3.1.4 + version: 3.1.4 '@types/uuid': specifier: ^10.0.0 version: 10.0.0 @@ -167,7 +173,7 @@ importers: version: 8.2.2 nx: specifier: 19.6.3 - version: 19.6.3(@swc/core@1.5.25) + version: 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) tsx: specifier: ^4.19.0 version: 4.19.0 @@ -369,7 +375,7 @@ importers: version: 7.0.4 '@nestjs/bullmq': specifier: ^10.2.1 - version: 10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bullmq@5.12.12) + version: 10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)(bullmq@5.12.12) '@nestjs/common': specifier: ^10.4.1 version: 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -381,7 +387,7 @@ importers: version: 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/event-emitter': specifier: ^2.0.4 - version: 2.0.4(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)) + version: 2.0.4(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1) '@nestjs/jwt': specifier: ^10.2.0 version: 10.2.0(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)) @@ -393,13 +399,13 @@ importers: version: 10.0.3(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(passport@0.7.0) '@nestjs/platform-fastify': specifier: ^10.4.1 - version: 10.4.1(@fastify/static@7.0.4)(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)) + version: 10.4.1(@fastify/static@7.0.4)(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1) '@nestjs/platform-socket.io': specifier: ^10.4.1 version: 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(rxjs@7.8.1) '@nestjs/terminus': specifier: ^10.2.3 - version: 10.2.3(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1) + version: 10.2.3(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/websockets': specifier: ^10.4.1 version: 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)(@nestjs/platform-socket.io@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -418,9 +424,6 @@ importers: bullmq: specifier: ^5.12.12 version: 5.12.12 - bytes: - specifier: ^3.1.2 - version: 3.1.2 class-transformer: specifier: ^0.5.1 version: 0.5.1 @@ -453,7 +456,7 @@ importers: version: 5.0.7 nestjs-kysely: specifier: ^1.0.0 - version: 1.0.0(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(kysely@0.27.4)(reflect-metadata@0.2.2) + version: 1.0.0(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)(kysely@0.27.4)(reflect-metadata@0.2.2) nodemailer: specifier: ^6.9.14 version: 6.9.14 @@ -493,19 +496,16 @@ importers: devDependencies: '@nestjs/cli': specifier: ^10.4.5 - version: 10.4.5(@swc/core@1.5.25) + version: 10.4.5(@swc/core@1.5.25(@swc/helpers@0.5.5)) '@nestjs/schematics': specifier: ^10.1.4 version: 10.1.4(chokidar@3.6.0)(typescript@5.5.4) '@nestjs/testing': specifier: ^10.4.1 - version: 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)) + version: 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1) '@types/bcrypt': specifier: ^5.0.2 version: 5.0.2 - '@types/bytes': - specifier: ^3.1.4 - version: 3.1.4 '@types/debounce': specifier: ^1.2.4 version: 1.2.4 @@ -553,7 +553,7 @@ importers: version: 5.2.1(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.0)))(eslint@9.9.1(jiti@1.21.0))(prettier@3.3.3) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + version: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) kysely-codegen: specifier: ^0.16.3 version: 0.16.3(kysely@0.27.4)(pg@8.12.0) @@ -571,13 +571,13 @@ importers: version: 7.0.0 ts-jest: specifier: ^29.2.5 - version: 29.2.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)))(typescript@5.5.4) + version: 29.2.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)))(typescript@5.5.4) ts-loader: specifier: ^9.5.1 - version: 9.5.1(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.5.25)) + version: 9.5.1(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5))) ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4) + version: 10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -4036,6 +4036,7 @@ packages: are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} + deprecated: This package is no longer supported. arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -5228,6 +5229,7 @@ packages: gauge@3.0.2: resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} engines: {node: '>=10'} + deprecated: This package is no longer supported. generic-pool@3.9.0: resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} @@ -6321,6 +6323,7 @@ packages: npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. nwsapi@2.2.10: resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} @@ -10084,7 +10087,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -10098,7 +10101,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -10384,21 +10387,21 @@ snapshots: '@emnapi/runtime': 1.2.0 '@tybys/wasm-util': 0.9.0 - '@nestjs/bull-shared@10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))': + '@nestjs/bull-shared@10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)': dependencies: '@nestjs/common': 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) tslib: 2.6.3 - '@nestjs/bullmq@10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bullmq@5.12.12)': + '@nestjs/bullmq@10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)(bullmq@5.12.12)': dependencies: - '@nestjs/bull-shared': 10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)) + '@nestjs/bull-shared': 10.2.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1) '@nestjs/common': 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) bullmq: 5.12.12 tslib: 2.6.3 - '@nestjs/cli@10.4.5(@swc/core@1.5.25)': + '@nestjs/cli@10.4.5(@swc/core@1.5.25(@swc/helpers@0.5.5))': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) @@ -10408,7 +10411,7 @@ snapshots: chokidar: 3.6.0 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.25)) + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5))) glob: 10.4.2 inquirer: 8.2.6 node-emoji: 1.11.0 @@ -10417,10 +10420,10 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.1.0 typescript: 5.3.3 - webpack: 5.94.0(@swc/core@1.5.25) + webpack: 5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) webpack-node-externals: 3.0.0 optionalDependencies: - '@swc/core': 1.5.25 + '@swc/core': 1.5.25(@swc/helpers@0.5.5) transitivePeerDependencies: - esbuild - uglify-js @@ -10461,7 +10464,7 @@ snapshots: transitivePeerDependencies: - encoding - '@nestjs/event-emitter@2.0.4(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))': + '@nestjs/event-emitter@2.0.4(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)': dependencies: '@nestjs/common': 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -10486,7 +10489,7 @@ snapshots: '@nestjs/common': 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) passport: 0.7.0 - '@nestjs/platform-fastify@10.4.1(@fastify/static@7.0.4)(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))': + '@nestjs/platform-fastify@10.4.1(@fastify/static@7.0.4)(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)': dependencies: '@fastify/cors': 9.0.1 '@fastify/formbody': 7.4.0 @@ -10536,7 +10539,7 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/terminus@10.2.3(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)': + '@nestjs/terminus@10.2.3(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1)': dependencies: '@nestjs/common': 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -10545,7 +10548,7 @@ snapshots: reflect-metadata: 0.2.2 rxjs: 7.8.1 - '@nestjs/testing@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))': + '@nestjs/testing@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)': dependencies: '@nestjs/common': 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -10604,15 +10607,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@nrwl/devkit@19.6.3(nx@19.6.3(@swc/core@1.5.25))': + '@nrwl/devkit@19.6.3(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)))': dependencies: - '@nx/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25)) + '@nx/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5))) transitivePeerDependencies: - nx - '@nrwl/js@19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25)(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25))(typescript@5.5.4)': + '@nrwl/js@19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)))(typescript@5.5.4)': dependencies: - '@nx/js': 19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25)(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25))(typescript@5.5.4) + '@nx/js': 19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)))(typescript@5.5.4) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -10625,18 +10628,18 @@ snapshots: - typescript - verdaccio - '@nrwl/tao@19.6.3(@swc/core@1.5.25)': + '@nrwl/tao@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5))': dependencies: - nx: 19.6.3(@swc/core@1.5.25) + nx: 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) tslib: 2.6.2 transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nrwl/workspace@19.6.3(@swc/core@1.5.25)': + '@nrwl/workspace@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5))': dependencies: - '@nx/workspace': 19.6.3(@swc/core@1.5.25) + '@nx/workspace': 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@swc-node/register' - '@swc/core' @@ -10650,20 +10653,20 @@ snapshots: transitivePeerDependencies: - encoding - '@nx/devkit@19.6.3(nx@19.6.3(@swc/core@1.5.25))': + '@nx/devkit@19.6.3(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)))': dependencies: - '@nrwl/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25)) + '@nrwl/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5))) ejs: 3.1.9 enquirer: 2.3.6 ignore: 5.3.1 minimatch: 9.0.3 - nx: 19.6.3(@swc/core@1.5.25) + nx: 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) semver: 7.6.2 tmp: 0.2.1 tslib: 2.6.2 yargs-parser: 21.1.1 - '@nx/js@19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25)(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25))(typescript@5.5.4)': + '@nx/js@19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)))(typescript@5.5.4)': dependencies: '@babel/core': 7.24.6 '@babel/plugin-proposal-decorators': 7.23.7(@babel/core@7.24.6) @@ -10672,9 +10675,9 @@ snapshots: '@babel/preset-env': 7.23.8(@babel/core@7.24.6) '@babel/preset-typescript': 7.23.3(@babel/core@7.24.6) '@babel/runtime': 7.23.7 - '@nrwl/js': 19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25)(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25))(typescript@5.5.4) - '@nx/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25)) - '@nx/workspace': 19.6.3(@swc/core@1.5.25) + '@nrwl/js': 19.6.3(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)))(typescript@5.5.4) + '@nx/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5))) + '@nx/workspace': 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) babel-plugin-const-enum: 1.2.0(@babel/core@7.24.6) babel-plugin-macros: 2.8.0 babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.24.6)(@babel/traverse@7.24.6) @@ -10692,7 +10695,7 @@ snapshots: ora: 5.3.0 semver: 7.6.2 source-map-support: 0.5.19 - ts-node: 10.9.1(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4) + ts-node: 10.9.1(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4) tsconfig-paths: 4.2.0 tslib: 2.6.2 transitivePeerDependencies: @@ -10736,13 +10739,13 @@ snapshots: '@nx/nx-win32-x64-msvc@19.6.3': optional: true - '@nx/workspace@19.6.3(@swc/core@1.5.25)': + '@nx/workspace@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5))': dependencies: - '@nrwl/workspace': 19.6.3(@swc/core@1.5.25) - '@nx/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25)) + '@nrwl/workspace': 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) + '@nx/devkit': 19.6.3(nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5))) chalk: 4.1.2 enquirer: 2.3.6 - nx: 19.6.3(@swc/core@1.5.25) + nx: 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) tslib: 2.6.2 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -11351,7 +11354,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.5.25': optional: true - '@swc/core@1.5.25': + '@swc/core@1.5.25(@swc/helpers@0.5.5)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.7 @@ -11366,6 +11369,7 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.5.25 '@swc/core-win32-ia32-msvc': 1.5.25 '@swc/core-win32-x64-msvc': 1.5.25 + '@swc/helpers': 0.5.5 optional: true '@swc/counter@0.1.3': {} @@ -12711,13 +12715,13 @@ snapshots: optionalDependencies: typescript: 5.3.3 - create-jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)): + create-jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -13529,7 +13533,7 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.25)): + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.24.6 chalk: 4.1.2 @@ -13544,7 +13548,7 @@ snapshots: semver: 7.6.2 tapable: 2.2.1 typescript: 5.3.3 - webpack: 5.94.0(@swc/core@1.5.25) + webpack: 5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) form-data@4.0.0: dependencies: @@ -14044,16 +14048,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)): + jest-cli@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + create-jest: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + jest-config: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -14063,7 +14067,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)): + jest-config@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)): dependencies: '@babel/core': 7.24.6 '@jest/test-sequencer': 29.7.0 @@ -14089,7 +14093,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 22.5.2 - ts-node: 10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4) + ts-node: 10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -14315,12 +14319,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)): + jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + jest-cli: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -14798,7 +14802,7 @@ snapshots: neo-async@2.6.2: {} - nestjs-kysely@1.0.0(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(kysely@0.27.4)(reflect-metadata@0.2.2): + nestjs-kysely@1.0.0(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.1)(kysely@0.27.4)(reflect-metadata@0.2.2): dependencies: '@nestjs/common': 10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.1(@nestjs/common@10.4.1(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -14885,10 +14889,10 @@ snapshots: nwsapi@2.2.10: {} - nx@19.6.3(@swc/core@1.5.25): + nx@19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.6.3(@swc/core@1.5.25) + '@nrwl/tao': 19.6.3(@swc/core@1.5.25(@swc/helpers@0.5.5)) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -14933,7 +14937,7 @@ snapshots: '@nx/nx-linux-x64-musl': 19.6.3 '@nx/nx-win32-arm64-msvc': 19.6.3 '@nx/nx-win32-x64-msvc': 19.6.3 - '@swc/core': 1.5.25 + '@swc/core': 1.5.25(@swc/helpers@0.5.5) transitivePeerDependencies: - debug @@ -16077,16 +16081,16 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - terser-webpack-plugin@5.3.10(@swc/core@1.5.25)(webpack@5.94.0(@swc/core@1.5.25)): + terser-webpack-plugin@5.3.10(@swc/core@1.5.25(@swc/helpers@0.5.5))(webpack@5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.29.2 - webpack: 5.94.0(@swc/core@1.5.25) + webpack: 5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) optionalDependencies: - '@swc/core': 1.5.25 + '@swc/core': 1.5.25(@swc/helpers@0.5.5) terser@5.29.2: dependencies: @@ -16160,12 +16164,12 @@ snapshots: ts-dedent@2.2.0: {} - ts-jest@29.2.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)))(typescript@5.5.4): + ts-jest@29.2.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)))(typescript@5.5.4): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4)) + jest: 29.7.0(@types/node@22.5.2)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -16179,7 +16183,7 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.24.3) - ts-loader@9.5.1(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.5.25)): + ts-loader@9.5.1(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5))): dependencies: chalk: 4.1.2 enhanced-resolve: 5.16.0 @@ -16187,9 +16191,9 @@ snapshots: semver: 7.6.0 source-map: 0.7.4 typescript: 5.5.4 - webpack: 5.94.0(@swc/core@1.5.25) + webpack: 5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) - ts-node@10.9.1(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4): + ts-node@10.9.1(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -16207,9 +16211,9 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.5.25 + '@swc/core': 1.5.25(@swc/helpers@0.5.5) - ts-node@10.9.2(@swc/core@1.5.25)(@types/node@22.5.2)(typescript@5.5.4): + ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@22.5.2)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -16227,7 +16231,7 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.5.25 + '@swc/core': 1.5.25(@swc/helpers@0.5.5) tsconfig-paths-webpack-plugin@4.1.0: dependencies: @@ -16430,7 +16434,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.94.0(@swc/core@1.5.25): + webpack@5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5)): dependencies: '@types/estree': 1.0.5 '@webassemblyjs/ast': 1.12.1 @@ -16452,7 +16456,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.5.25)(webpack@5.94.0(@swc/core@1.5.25)) + terser-webpack-plugin: 5.3.10(@swc/core@1.5.25(@swc/helpers@0.5.5))(webpack@5.94.0(@swc/core@1.5.25(@swc/helpers@0.5.5))) watchpack: 2.4.1 webpack-sources: 3.2.3 transitivePeerDependencies: