From a573acedd0317f3472cb0f8b95f6aa15315312e5 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:13:25 +0100 Subject: [PATCH 01/46] fix: local storage, and package overrides --- apps/client/package.json | 2 +- apps/server/package.json | 24 +- .../core/attachment/attachment.controller.ts | 5 + .../src/core/user/dto/update-user.dto.ts | 4 - apps/server/src/core/user/user.service.ts | 4 - .../workspace/dto/update-workspace.dto.ts | 5 - .../src/integrations/export/export.service.ts | 99 +++- .../storage/drivers/local.driver.spec.ts | 67 +++ .../storage/drivers/local.driver.ts | 9 +- package.json | 10 +- pnpm-lock.yaml | 486 +++++++++--------- 11 files changed, 409 insertions(+), 306 deletions(-) create mode 100644 apps/server/src/integrations/storage/drivers/local.driver.spec.ts diff --git a/apps/client/package.json b/apps/client/package.json index 6b8a8b60d..bdf222097 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -42,7 +42,7 @@ "mantine-form-zod-resolver": "^1.3.0", "mermaid": "^11.13.0", "mitt": "^3.0.1", - "posthog-js": "1.363.1", + "posthog-js": "1.370.0", "react": "^18.3.1", "react-arborist": "3.4.0", "react-clear-modal": "^2.0.18", diff --git a/apps/server/package.json b/apps/server/package.json index 4aca4acd0..97af8db7d 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -38,8 +38,8 @@ "@aws-sdk/s3-request-presigner": "3.1014.0", "@clickhouse/client": "^1.18.2", "@fastify/cookie": "^11.0.2", - "@fastify/multipart": "^9.4.0", - "@fastify/static": "^9.0.0", + "@fastify/multipart": "^10.0.0", + "@fastify/static": "^9.1.3", "@keyv/redis": "^5.1.6", "@langchain/core": "1.1.39", "@langchain/textsplitters": "1.0.1", @@ -48,19 +48,19 @@ "@nestjs-labs/nestjs-ioredis": "^11.0.4", "@nestjs/bullmq": "^11.0.4", "@nestjs/cache-manager": "^3.1.0", - "@nestjs/common": "^11.1.18", - "@nestjs/config": "^4.0.3", - "@nestjs/core": "^11.1.18", + "@nestjs/common": "^11.1.19", + "@nestjs/config": "^4.0.4", + "@nestjs/core": "^11.1.19", "@nestjs/event-emitter": "^3.0.1", "@nestjs/jwt": "11.0.2", "@nestjs/mapped-types": "^2.1.1", "@nestjs/passport": "^11.0.5", - "@nestjs/platform-fastify": "^11.1.18", - "@nestjs/platform-socket.io": "^11.1.18", - "@nestjs/schedule": "^6.1.1", + "@nestjs/platform-fastify": "^11.1.19", + "@nestjs/platform-socket.io": "^11.1.19", + "@nestjs/schedule": "^6.1.3", "@nestjs/terminus": "^11.1.1", "@nestjs/throttler": "^6.5.0", - "@nestjs/websockets": "^11.1.18", + "@nestjs/websockets": "^11.1.19", "@node-saml/passport-saml": "^5.1.0", "@react-email/components": "1.0.10", "@react-email/render": "2.0.4", @@ -69,7 +69,7 @@ "ai-sdk-ollama": "^3.8.1", "bcrypt": "^6.0.0", "bowser": "^2.14.1", - "bullmq": "^5.71.0", + "bullmq": "^5.76.0", "cache-manager": "^7.2.8", "cheerio": "^1.2.0", "class-transformer": "^0.5.1", @@ -123,9 +123,9 @@ }, "devDependencies": { "@eslint/js": "^9.28.0", - "@nestjs/cli": "^11.0.18", + "@nestjs/cli": "^11.0.21", "@nestjs/schematics": "^11.0.10", - "@nestjs/testing": "^11.1.18", + "@nestjs/testing": "^11.1.19", "@types/bcrypt": "^6.0.0", "@types/debounce": "^1.2.4", "@types/fs-extra": "^11.0.4", diff --git a/apps/server/src/core/attachment/attachment.controller.ts b/apps/server/src/core/attachment/attachment.controller.ts index 7b24cc356..784e527e6 100644 --- a/apps/server/src/core/attachment/attachment.controller.ts +++ b/apps/server/src/core/attachment/attachment.controller.ts @@ -53,6 +53,7 @@ import { EnvironmentService } from '../../integrations/environment/environment.s import { TokenService } from '../auth/services/token.service'; import { JwtAttachmentPayload, JwtType } from '../auth/dto/jwt-payload'; import * as path from 'path'; +import { sanitize } from 'sanitize-filename-ts'; import { AttachmentInfoDto, RemoveIconDto } from './dto/attachment.dto'; import { PageAccessService } from '../page/page-access/page-access.service'; import { AuditEvent, AuditResource } from '../../common/events/audit-events'; @@ -356,6 +357,10 @@ export class AttachmentController { throw new BadRequestException('Invalid image attachment type'); } + if (!fileName || sanitize(fileName) !== fileName) { + throw new BadRequestException('Invalid file name'); + } + const filenameWithoutExt = path.basename(fileName, path.extname(fileName)); if (!isValidUUID(filenameWithoutExt)) { throw new BadRequestException('Invalid file id'); diff --git a/apps/server/src/core/user/dto/update-user.dto.ts b/apps/server/src/core/user/dto/update-user.dto.ts index f1c02c516..9d8ef8ef8 100644 --- a/apps/server/src/core/user/dto/update-user.dto.ts +++ b/apps/server/src/core/user/dto/update-user.dto.ts @@ -13,10 +13,6 @@ import { CreateUserDto } from '../../auth/dto/create-user.dto'; export class UpdateUserDto extends PartialType( OmitType(CreateUserDto, ['password'] as const), ) { - @IsOptional() - @IsString() - avatarUrl: string; - @IsOptional() @IsBoolean() fullPageWidth: boolean; diff --git a/apps/server/src/core/user/user.service.ts b/apps/server/src/core/user/user.service.ts index fa2298274..7a1439767 100644 --- a/apps/server/src/core/user/user.service.ts +++ b/apps/server/src/core/user/user.service.ts @@ -110,10 +110,6 @@ export class UserService { user.email = updateUserDto.email; } - if (updateUserDto.avatarUrl) { - user.avatarUrl = updateUserDto.avatarUrl; - } - if (updateUserDto.locale) { user.locale = updateUserDto.locale; } diff --git a/apps/server/src/core/workspace/dto/update-workspace.dto.ts b/apps/server/src/core/workspace/dto/update-workspace.dto.ts index 4b1482084..a08b1e524 100644 --- a/apps/server/src/core/workspace/dto/update-workspace.dto.ts +++ b/apps/server/src/core/workspace/dto/update-workspace.dto.ts @@ -5,15 +5,10 @@ import { IsBoolean, IsInt, IsOptional, - IsString, Min, } from 'class-validator'; export class UpdateWorkspaceDto extends PartialType(CreateWorkspaceDto) { - @IsOptional() - @IsString() - logo: string; - @IsOptional() @IsArray() emailDomains: string[]; diff --git a/apps/server/src/integrations/export/export.service.ts b/apps/server/src/integrations/export/export.service.ts index 3f8da1bf9..b4bc73fac 100644 --- a/apps/server/src/integrations/export/export.service.ts +++ b/apps/server/src/integrations/export/export.service.ts @@ -39,6 +39,8 @@ import { } from '../../common/helpers/prosemirror/utils'; import { htmlToMarkdown } from '@docmost/editor-ext'; +type AllowedAttachment = { id: string; fileName: string; filePath: string }; + @Injectable() export class ExportService { private readonly logger = new Logger(ExportService.name); @@ -272,6 +274,12 @@ export class ExportService { computeLocalPath(tree, format, null, '', slugIdToPath); + // Batch resolve attachments once for the whole export so we only run the + // owning-page view check a single time, regardless of page count. + const allowedAttachments = includeAttachments + ? await this.resolveAccessibleAttachments(tree, userId, ignorePermissions) + : new Map(); + const stack: { folder: JSZip; parentPageId: string | null }[] = [ { folder: zip, parentPageId: null }, ]; @@ -301,7 +309,7 @@ export class ExportService { ); if (includeAttachments) { - await this.zipAttachments(updatedJsonContent, page.spaceId, folder); + await this.zipAttachments(updatedJsonContent, folder, allowedAttachments); updatedJsonContent = updateAttachmentUrlsToLocalPaths(updatedJsonContent); } @@ -347,31 +355,80 @@ export class ExportService { zip.file('docmost-metadata.json', JSON.stringify(metadata, null, 2)); } - async zipAttachments(prosemirrorJson: any, spaceId: string, zip: JSZip) { + async zipAttachments( + prosemirrorJson: any, + zip: JSZip, + allowed: Map, + ) { const attachmentIds = getAttachmentIds(prosemirrorJson); - if (attachmentIds.length > 0) { - const attachments = await this.db - .selectFrom('attachments') - .select(['id', 'fileName', 'filePath']) - .where('id', 'in', attachmentIds) - .where('spaceId', '=', spaceId) - .execute(); + await Promise.all( + attachmentIds.map(async (id) => { + const attachment = allowed.get(id); + if (!attachment) return; + try { + const fileBuffer = await this.storageService.read( + attachment.filePath, + ); + const filePath = `/files/${attachment.id}/${attachment.fileName}`; + zip.file(filePath, fileBuffer); + } catch (err) { + this.logger.debug(`Attachment export error ${attachment.id}`, err); + } + }), + ); + } - await Promise.all( - attachments.map(async (attachment) => { - try { - const fileBuffer = await this.storageService.read( - attachment.filePath, - ); - const filePath = `/files/${attachment.id}/${attachment.fileName}`; - zip.file(filePath, fileBuffer); - } catch (err) { - this.logger.debug(`Attachment export error ${attachment.id}`, err); - } - }), + private async resolveAccessibleAttachments( + tree: PageExportTree, + userId: string | undefined, + ignorePermissions: boolean, + ): Promise> { + const allAttachmentIds = new Set(); + let spaceId: string | undefined; + for (const siblings of Object.values(tree)) { + for (const page of siblings) { + if (!spaceId) spaceId = page.spaceId; + for (const id of getAttachmentIds(getProsemirrorContent(page.content))) { + allAttachmentIds.add(id); + } + } + } + + if (allAttachmentIds.size === 0 || !spaceId) { + return new Map(); + } + + const attachments = await this.db + .selectFrom('attachments') + .select(['id', 'fileName', 'filePath', 'pageId']) + .where('id', 'in', [...allAttachmentIds]) + .where('spaceId', '=', spaceId) + .execute(); + + let visible = attachments; + if (!ignorePermissions && userId) { + const ownerPageIds = [ + ...new Set( + attachments + .map((a) => a.pageId) + .filter((id): id is string => !!id), + ), + ]; + const accessible = ownerPageIds.length + ? await this.pagePermissionRepo.filterAccessiblePageIds({ + pageIds: ownerPageIds, + userId, + spaceId, + }) + : []; + const accessibleSet = new Set(accessible); + visible = attachments.filter( + (a) => a.pageId && accessibleSet.has(a.pageId), ); } + + return new Map(visible.map((a) => [a.id, a])); } async turnPageMentionsToLinks( diff --git a/apps/server/src/integrations/storage/drivers/local.driver.spec.ts b/apps/server/src/integrations/storage/drivers/local.driver.spec.ts new file mode 100644 index 000000000..ccdddcc5d --- /dev/null +++ b/apps/server/src/integrations/storage/drivers/local.driver.spec.ts @@ -0,0 +1,67 @@ +import { resolve, sep } from 'path'; +import { LocalDriver } from './local.driver'; + +type FullPath = (filePath: string) => string; + +describe('LocalDriver._fullPath', () => { + const ROOT = resolve('/data/storage'); + const driver = new LocalDriver({ storagePath: ROOT }); + const fullPath = ((driver as any)._fullPath as FullPath).bind(driver); + + describe('legitimate inputs (behavior preserved)', () => { + it.each([ + ['workspace-id/avatars/uuid.png', `${ROOT}${sep}workspace-id${sep}avatars${sep}uuid.png`], + ['workspace-id/files/uuid/file.pdf', `${ROOT}${sep}workspace-id${sep}files${sep}uuid${sep}file.pdf`], + ['a/b/c/d/e.bin', `${ROOT}${sep}a${sep}b${sep}c${sep}d${sep}e.bin`], + ['', ROOT], + ['.', ROOT], + ['./x/y.png', `${ROOT}${sep}x${sep}y.png`], + ['a//b', `${ROOT}${sep}a${sep}b`], + ['a/b/../c', `${ROOT}${sep}a${sep}c`], + ])('resolves %j to %j', (input, expected) => { + expect(fullPath(input)).toBe(expected); + }); + }); + + describe('traversal rejected', () => { + it.each([ + '../etc/passwd', + '../../../etc/passwd', + 'workspace/../../../etc/passwd', + '..', + '../..', + 'a/../../..', + ])('throws for %j', (input) => { + expect(() => fullPath(input)).toThrow('Invalid file path'); + }); + }); + + describe('absolute path rejected', () => { + it.each([ + '/etc/passwd', + '/root/.ssh/id_rsa', + sep + 'absolute', + ])('throws for %j', (input) => { + expect(() => fullPath(input)).toThrow('Invalid file path'); + }); + }); + + describe('prefix-confusion rejected', () => { + it('rejects a sibling directory whose name starts with the storage root', () => { + const siblingDriver = new LocalDriver({ storagePath: '/data/storage' }); + const siblingFullPath = ((siblingDriver as any)._fullPath as FullPath).bind(siblingDriver); + // Attempt to reach /data/storage-evil/secret by traversal: + // resolve('/data/storage', '../storage-evil/secret') === '/data/storage-evil/secret' + // Without the `+ sep` guard, a startsWith check would match. + expect(() => siblingFullPath('../storage-evil/secret')).toThrow('Invalid file path'); + }); + }); + + describe('storage root itself', () => { + it('accepts the root when input resolves to it', () => { + expect(fullPath('')).toBe(ROOT); + expect(fullPath('.')).toBe(ROOT); + expect(fullPath('a/..')).toBe(ROOT); + }); + }); +}); diff --git a/apps/server/src/integrations/storage/drivers/local.driver.ts b/apps/server/src/integrations/storage/drivers/local.driver.ts index 39342c619..60be7c5df 100644 --- a/apps/server/src/integrations/storage/drivers/local.driver.ts +++ b/apps/server/src/integrations/storage/drivers/local.driver.ts @@ -3,7 +3,7 @@ import { LocalStorageConfig, StorageOption, } from '../interfaces'; -import { join, dirname } from 'path'; +import { dirname, resolve, sep } from 'path'; import * as fs from 'fs-extra'; import { Readable } from 'stream'; import { createReadStream, createWriteStream } from 'node:fs'; @@ -17,7 +17,12 @@ export class LocalDriver implements StorageDriver { } private _fullPath(filePath: string): string { - return join(this.config.storagePath, filePath); + const storageRoot = resolve(this.config.storagePath); + const fullPath = resolve(storageRoot, filePath); + if (fullPath !== storageRoot && !fullPath.startsWith(storageRoot + sep)) { + throw new Error('Invalid file path'); + } + return fullPath; } async upload(filePath: string, file: Buffer | Readable): Promise { diff --git a/package.json b/package.json index bf7b27618..6d3d97c2d 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "cross-env": "^10.1.0", "date-fns": "^4.1.0", "diff": "8.0.3", - "dompurify": "^3.3.3", + "dompurify": "3.4.1", "fractional-indexing-jittered": "^1.0.0", "highlight.js": "^11.11.1", "image-dimensions": "^2.5.0", @@ -102,9 +102,9 @@ "y-prosemirror": "1.3.7", "glob": "13.0.6", "ws": "8.20.0", - "dompurify": "3.3.3", + "dompurify": "3.4.1", "tmp": "0.2.5", - "hono": "4.12.12", + "hono": "4.12.14", "mermaid": "11.13.0", "nanoid@^3": "3.3.8", "socket.io-parser": "4.2.6", @@ -123,7 +123,7 @@ "flatted": "3.4.2", "picomatch@<2.3.2": "2.3.2", "picomatch@>=4.0.0 <4.0.4": "4.0.4", - "fastify": "5.8.3", + "fastify": "5.8.5", "yaml@>=1.0.0 <1.10.3": "1.10.3", "yaml@>=2.0.0 <2.8.3": "2.8.3", "path-to-regexp@^8": "8.4.0", @@ -131,7 +131,7 @@ "@xmldom/xmldom": "0.8.12", "handlebars": "4.7.9", "axios": "1.15.0", - "langsmith": "0.5.18", + "langsmith": "0.5.19", "follow-redirects": "1.16.0" }, "neverBuiltDependencies": [] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d30859b71..56dd6d794 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,9 +9,9 @@ overrides: y-prosemirror: 1.3.7 glob: 13.0.6 ws: 8.20.0 - dompurify: 3.3.3 + dompurify: 3.4.1 tmp: 0.2.5 - hono: 4.12.12 + hono: 4.12.14 mermaid: 11.13.0 nanoid@^3: 3.3.8 socket.io-parser: 4.2.6 @@ -30,7 +30,7 @@ overrides: flatted: 3.4.2 picomatch@<2.3.2: 2.3.2 picomatch@>=4.0.0 <4.0.4: 4.0.4 - fastify: 5.8.3 + fastify: 5.8.5 yaml@>=1.0.0 <1.10.3: 1.10.3 yaml@>=2.0.0 <2.8.3: 2.8.3 path-to-regexp@^8: 8.4.0 @@ -38,7 +38,7 @@ overrides: '@xmldom/xmldom': 0.8.12 handlebars: 4.7.9 axios: 1.15.0 - langsmith: 0.5.18 + langsmith: 0.5.19 follow-redirects: 1.16.0 patchedDependencies: @@ -180,8 +180,8 @@ importers: specifier: 8.0.3 version: 8.0.3 dompurify: - specifier: 3.3.3 - version: 3.3.3 + specifier: 3.4.1 + version: 3.4.1 fractional-indexing-jittered: specifier: ^1.0.0 version: 1.0.0 @@ -343,8 +343,8 @@ importers: specifier: ^3.0.1 version: 3.0.1 posthog-js: - specifier: 1.363.1 - version: 1.363.1 + specifier: 1.370.0 + version: 1.370.0 react: specifier: ^18.3.1 version: 18.3.1 @@ -482,11 +482,11 @@ importers: specifier: ^11.0.2 version: 11.0.2 '@fastify/multipart': - specifier: ^9.4.0 - version: 9.4.0 + specifier: ^10.0.0 + version: 10.0.0 '@fastify/static': - specifier: ^9.0.0 - version: 9.0.0 + specifier: ^9.1.3 + version: 9.1.3 '@keyv/redis': specifier: ^5.1.6 version: 5.1.6(keyv@5.6.0) @@ -501,55 +501,55 @@ importers: version: 1.29.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) '@nest-lab/throttler-storage-redis': specifier: ^1.2.0 - version: 1.2.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/throttler@6.5.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2))(ioredis@5.10.1)(reflect-metadata@0.2.2) + version: 1.2.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/throttler@6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2))(ioredis@5.10.1)(reflect-metadata@0.2.2) '@nestjs-labs/nestjs-ioredis': specifier: ^11.0.4 - version: 11.0.4(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(ioredis@5.10.1) + version: 11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(ioredis@5.10.1) '@nestjs/bullmq': specifier: ^11.0.4 - version: 11.0.4(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(bullmq@5.71.0) + version: 11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(bullmq@5.76.0) '@nestjs/cache-manager': specifier: ^3.1.0 - version: 3.1.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2) + version: 3.1.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2) '@nestjs/common': - specifier: ^11.1.18 - version: 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + specifier: ^11.1.19 + version: 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/config': - specifier: ^4.0.3 - version: 4.0.3(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + specifier: ^4.0.4 + version: 4.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) '@nestjs/core': - specifier: ^11.1.18 - version: 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + specifier: ^11.1.19 + version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/event-emitter': specifier: ^3.0.1 - version: 3.0.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + version: 3.0.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) '@nestjs/jwt': specifier: 11.0.2 - version: 11.0.2(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)) + version: 11.0.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)) '@nestjs/mapped-types': specifier: ^2.1.1 - version: 2.1.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) + version: 2.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) '@nestjs/passport': specifier: ^11.0.5 - version: 11.0.5(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) + version: 11.0.5(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) '@nestjs/platform-fastify': - specifier: ^11.1.18 - version: 11.1.18(@fastify/static@9.0.0)(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + specifier: ^11.1.19 + version: 11.1.19(@fastify/static@9.1.3)(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) '@nestjs/platform-socket.io': - specifier: ^11.1.18 - version: 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(rxjs@7.8.2) + specifier: ^11.1.19 + version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(rxjs@7.8.2) '@nestjs/schedule': - specifier: ^6.1.1 - version: 6.1.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + specifier: ^6.1.3 + version: 6.1.3(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) '@nestjs/terminus': specifier: ^11.1.1 - version: 11.1.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/throttler': specifier: ^6.5.0 - version: 6.5.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2) + version: 6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2) '@nestjs/websockets': - specifier: ^11.1.18 - version: 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + specifier: ^11.1.19 + version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-socket.io@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@node-saml/passport-saml': specifier: ^5.1.0 version: 5.1.0 @@ -575,8 +575,8 @@ importers: specifier: ^2.14.1 version: 2.14.1 bullmq: - specifier: ^5.71.0 - version: 5.71.0 + specifier: ^5.76.0 + version: 5.76.0 cache-manager: specifier: ^7.2.8 version: 7.2.8 @@ -642,13 +642,13 @@ importers: version: 5.1.7 nestjs-cls: specifier: ^6.2.0 - version: 6.2.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 6.2.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) nestjs-kysely: specifier: ^3.1.2 - version: 3.1.2(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.14)(reflect-metadata@0.2.2) + version: 3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.14)(reflect-metadata@0.2.2) nestjs-pino: specifier: ^4.6.1 - version: 4.6.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2) + version: 4.6.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2) nodemailer: specifier: ^8.0.5 version: 8.0.5 @@ -732,14 +732,14 @@ importers: specifier: ^9.28.0 version: 9.39.4 '@nestjs/cli': - specifier: ^11.0.18 - version: 11.0.18(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@25.5.0) + specifier: ^11.0.21 + version: 11.0.21(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@25.5.0) '@nestjs/schematics': specifier: ^11.0.10 version: 11.0.10(chokidar@4.0.3)(typescript@5.9.3) '@nestjs/testing': - specifier: ^11.1.18 - version: 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + specifier: ^11.1.19 + version: 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) '@types/bcrypt': specifier: ^6.0.0 version: 6.0.0 @@ -808,7 +808,7 @@ importers: version: 29.4.6(@babel/core@7.28.5)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.28.5))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.5.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@25.5.0)(typescript@5.9.3)))(typescript@5.9.3) ts-loader: specifier: ^9.5.7 - version: 9.5.7(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5))) + version: 9.5.7(typescript@5.9.3)(webpack@5.106.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(@swc/helpers@0.5.5))(@types/node@25.5.0)(typescript@5.9.3) @@ -880,8 +880,17 @@ packages: chokidar: optional: true - '@angular-devkit/schematics-cli@19.2.23': - resolution: {integrity: sha512-M8g7Gu3Lc5bbzijd2QLcQhfdpfMVE32YXQ6FIkA8x91Kmd2gb8aVvGYPLYUN5619P+ABWhN5Dn2PKuk01zz3vg==} + '@angular-devkit/core@19.2.24': + resolution: {integrity: sha512-Kd49warf6U/EyWe5BszF/eebN3zQ3bk7tgfEljAw8q/rX95UUtriJubWvp6pgzHfzBA4jwq8f+QiNZB8eBEXPA==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^4.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular-devkit/schematics-cli@19.2.24': + resolution: {integrity: sha512-bsStZQG67J1HBqTmWxtIcobvgrn32L4UOdL7hGyOru5VxDWPNA8pRnDYavT3hnJeBkJYPoQIw8u7Dm0ecoQprw==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} hasBin: true @@ -889,6 +898,10 @@ packages: resolution: {integrity: sha512-Jzs7YM4X6azmHU7Mw5tQSPMuvaqYS8SLnZOJbtiXCy1JyuW9bm/WBBecNHMiuZ8LHXKhvQ6AVX1tKrzF6uiDmw==} engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + '@angular-devkit/schematics@19.2.24': + resolution: {integrity: sha512-lnw+ZM1Io+cJAkReC0NPDjqObL8NtKzKIkdgEEKC8CUmkhurYhedbicN8Y8NYHgG1uLd2GozW3+/QqPRZaN+Lw==} + engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} @@ -2238,8 +2251,8 @@ packages: '@fastify/merge-json-schemas@0.2.1': resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} - '@fastify/multipart@9.4.0': - resolution: {integrity: sha512-Z404bzZeLSXTBmp/trCBuoVFX28pM7rhv849Q5TsbTFZHuk1lc4QjQITTPK92DKVpXmNtJXeHSSc7GYvqFpxAQ==} + '@fastify/multipart@10.0.0': + resolution: {integrity: sha512-pUx3Z1QStY7E7kwvDTIvB6P+rF5lzP+iqPgZyJyG3yBJVPvQaZxzDHYbQD89rbY0ciXrMOyGi8ezHDVexLvJDA==} '@fastify/proxy-addr@5.0.0': resolution: {integrity: sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==} @@ -2247,8 +2260,8 @@ packages: '@fastify/send@4.1.0': resolution: {integrity: sha512-TMYeQLCBSy2TOFmV95hQWkiTYgC/SEx7vMdV+wnZVX4tt8VBLKzmH8vV9OzJehV0+XBfg+WxPMt5wp+JBUKsVw==} - '@fastify/static@9.0.0': - resolution: {integrity: sha512-r64H8Woe/vfilg5RTy7lwWlE8ZZcTrc3kebYFMEUBrMqlydhQyoiExQXdYAy2REVpST/G35+stAM8WYp1WGmMA==} + '@fastify/static@9.1.3': + resolution: {integrity: sha512-aXrYtsiryLhRxRNaxNqsn7FUISeb7rB9q4eHUPIot5aeQBLNahnz1m6thzm7JWC1poSGXS9XrX8DvuMivp2hkQ==} '@floating-ui/core@1.7.3': resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} @@ -2301,7 +2314,7 @@ packages: resolution: {integrity: sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==} engines: {node: '>=18.14.1'} peerDependencies: - hono: 4.12.12 + hono: 4.12.14 '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -2472,9 +2485,6 @@ packages: '@types/node': optional: true - '@ioredis/commands@1.5.0': - resolution: {integrity: sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==} - '@ioredis/commands@1.5.1': resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==} @@ -2860,8 +2870,8 @@ packages: keyv: '>=5' rxjs: ^7.8.1 - '@nestjs/cli@11.0.18': - resolution: {integrity: sha512-z72OS+sFrDgIkNu/e/vUhbnjHZwAYQS8fBJKXLiFyz8059IVuY2FKebV2YMxyhY+920d4LX1hBIAGL5qQNdR7g==} + '@nestjs/cli@11.0.21': + resolution: {integrity: sha512-F8mV0Sj/zVEouzR3NxBuJy08YHTUOmC5Xdcx3qIIaJWzrm8Vw86CHkhkaPBJ5ewRMHPDCShPmhsfwhpCcjts3A==} engines: {node: '>= 20.11'} hasBin: true peerDependencies: @@ -2873,8 +2883,8 @@ packages: '@swc/core': optional: true - '@nestjs/common@11.1.18': - resolution: {integrity: sha512-0sLq8Z+TIjLnz1Tqp0C/x9BpLbqpt1qEu0VcH4/fkE0y3F5JxhfK1AdKQ/SPbKhKgwqVDoY4gS8GQr2G6ujaWg==} + '@nestjs/common@11.1.19': + resolution: {integrity: sha512-qeiTt2tv+e5QyDKqG8HlVZb2wx64FEaSGFJouqTSRs+kG44iTfl3xlz1XqVped+rihx4hmjWgL5gkhtdK3E6+Q==} peerDependencies: class-transformer: '>=0.4.1' class-validator: '>=0.13.2' @@ -2886,14 +2896,14 @@ packages: class-validator: optional: true - '@nestjs/config@4.0.3': - resolution: {integrity: sha512-FQ3M3Ohqfl+nHAn5tp7++wUQw0f2nAk+SFKe8EpNRnIifPqvfJP6JQxPKtFLMOHbyer4X646prFG4zSRYEssQQ==} + '@nestjs/config@4.0.4': + resolution: {integrity: sha512-CJPjNitr0bAufSEnRe2N+JbnVmMmDoo6hvKCPzXgZoGwJSmp/dZPk9f/RMbuD/+Q1ZJPjwsRpq0vxna++Knwow==} peerDependencies: '@nestjs/common': ^10.0.0 || ^11.0.0 rxjs: ^7.1.0 - '@nestjs/core@11.1.18': - resolution: {integrity: sha512-wR3DtGyk/LUAiPtbXDuWJJwVkWElKBY0sqnTzf9d4uM3+X18FRZhK7WFc47czsIGOdWuRsMeLYV+1Z9dO4zDEQ==} + '@nestjs/core@11.1.19': + resolution: {integrity: sha512-6nJkWa2efrYi+XlU686J9y5L7OvxpLVjT0T/sxRKE7Jvpffiihelup4WSvLvRhdHDjj/5SuoWEwqReXAaaeHmw==} engines: {node: '>= 20'} peerDependencies: '@nestjs/common': ^11.0.0 @@ -2940,8 +2950,8 @@ packages: '@nestjs/common': ^10.0.0 || ^11.0.0 passport: ^0.5.0 || ^0.6.0 || ^0.7.0 - '@nestjs/platform-fastify@11.1.18': - resolution: {integrity: sha512-iJtbqQz51k7Z1vOTUEHO1mU8PsDO1WdgPSJ/6CuXBnazkrkePXoszhefFaPwJreBVn35GE3WTd/6ou7bFwnhmA==} + '@nestjs/platform-fastify@11.1.19': + resolution: {integrity: sha512-PdldJPw+xu8JM7VNE2FY+ty+qoxDMW7326h/z0MtfZvKj84FE6zuqpcSXen1CYjtyP8og+x/5XrJbKKKDNabtQ==} peerDependencies: '@fastify/static': ^8.0.0 || ^9.0.0 '@fastify/view': ^10.0.0 || ^11.0.0 @@ -2953,15 +2963,15 @@ packages: '@fastify/view': optional: true - '@nestjs/platform-socket.io@11.1.18': - resolution: {integrity: sha512-DiFRpMIdFaHqZQFwqLqGHMdNurrKVkRkMHxIrecjooPHJNNIMgrbpYZ+oJW8hpwifUyZUL4r4uXXRy4+yFEMjA==} + '@nestjs/platform-socket.io@11.1.19': + resolution: {integrity: sha512-gu1nPIEaP5Qjjg/Cl8wXyvwGpdZGzgbtK4KcH65YRAA+GTKUkIHb4BNpLJ27Ymq/wqLJKNEbCjajfzD0BEjMGA==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/websockets': ^11.0.0 rxjs: ^7.1.0 - '@nestjs/schedule@6.1.1': - resolution: {integrity: sha512-kQl1RRgi02GJ0uaUGCrXHCcwISsCsJDciCKe38ykJZgnAeeoeVWs8luWtBo4AqAAXm4nS5K8RlV0smHUJ4+2FA==} + '@nestjs/schedule@6.1.3': + resolution: {integrity: sha512-RflMFOpR16Dwd1jAUbeB4mfGTCh65fvEdL4mSjQPJChpkRGRjIXjb+6YQcK2faQrVT60c9DmLmoVR7/ONCtuYQ==} peerDependencies: '@nestjs/common': ^10.0.0 || ^11.0.0 '@nestjs/core': ^10.0.0 || ^11.0.0 @@ -3019,8 +3029,8 @@ packages: typeorm: optional: true - '@nestjs/testing@11.1.18': - resolution: {integrity: sha512-frzwNlpBgtAzI3hp/qo57DZoRO4RMTH1wST3QUYEhRTHyfPkLpzkWz3jV/mhApXjD0yT56Ptlzn6zuYPLh87Lw==} + '@nestjs/testing@11.1.19': + resolution: {integrity: sha512-/UFNWXvPEdu4v4DlC5oWLbGKmD27LehLK06b8oLzs6D6lf4vAQTdST8LRAXBadyMUQnVEQWMuBo3CtAVtlfXtQ==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3039,8 +3049,8 @@ packages: '@nestjs/core': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 reflect-metadata: ^0.1.13 || ^0.2.0 - '@nestjs/websockets@11.1.18': - resolution: {integrity: sha512-HLO/QGlJoJaMMDphgjbcIwW7/8EA8nnFQjf+qPvA+wWLLfPKoiFPUezc5m9YgN2A7jmzwo6YmEAXeHyqO9tvTw==} + '@nestjs/websockets@11.1.19': + resolution: {integrity: sha512-2qo8jtIwwwgkqAI1BtnJ02EaFLrRkKA39eYXS8IhZCHilhBHCWdjnJ5cLcFq4oF+s+KZ7LcLGD/3stxJy8ijzg==} peerDependencies: '@nestjs/common': ^11.0.0 '@nestjs/core': ^11.0.0 @@ -3223,11 +3233,11 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@posthog/core@1.24.1': - resolution: {integrity: sha512-e8AciAnc6MRFws89ux8lJKFAaI03yEon0ASDoUO7yS91FVqbUGXYekObUUR3LHplcg+pmyiJBI0jolY0SFbGRA==} + '@posthog/core@1.26.0': + resolution: {integrity: sha512-q6pSkW7V9RC3rIXjJBo7IBXOH2KPJEh8o+xIcSqw7QD4vq7OYVzTJfUIvkD38+sm54RG/61/3QaPdpQZkDnOyg==} - '@posthog/types@1.363.1': - resolution: {integrity: sha512-bFYk5XHgYEfVhQU0AwkG9MbMqq9QRbKDDJxOtYWGJ6Uw+/nLRNs/ZydXy3aMt0ldIdkNzZq+qaJ/p2Jg0+mP8g==} + '@posthog/types@1.370.0': + resolution: {integrity: sha512-Hcan3j0L1JZwyaoi8SvbZk41phzHpj5u3/BRn0dFVBlfkbvfhkgXHPETKIZP5CPzjrotOXRLYI4LNRDHp28VsA==} '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -5819,8 +5829,8 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - bullmq@5.71.0: - resolution: {integrity: sha512-aeNWh4drsafSKnAJeiNH/nZP/5O8ZdtdMbnOPZmpjXj7NZUP5YC901U3bIH41iZValm7d1i3c34ojv7q31m30w==} + bullmq@5.76.0: + resolution: {integrity: sha512-gVknzNL7wr3tsDQEf/CL6tHpi++eOWqsLN/s0hETgQmPy6GFVv6aKUQ8yvrbdTbeorC+hbbsLdyqaPD2eLAGRA==} bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} @@ -6541,8 +6551,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@3.3.3: - resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} + dompurify@3.4.1: + resolution: {integrity: sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==} domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -6563,14 +6573,14 @@ packages: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} - dotenv@17.2.3: - resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} - engines: {node: '>=12'} - dotenv@17.2.4: resolution: {integrity: sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==} engines: {node: '>=12'} + dotenv@17.4.1: + resolution: {integrity: sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==} + engines: {node: '>=12'} + duck@0.1.12: resolution: {integrity: sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==} @@ -6626,10 +6636,6 @@ packages: resolution: {integrity: sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.19.0: - resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} - engines: {node: '>=10.13.0'} - enhanced-resolve@5.20.1: resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} engines: {node: '>=10.13.0'} @@ -6927,8 +6933,8 @@ packages: fastify-plugin@5.1.0: resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} - fastify@5.8.3: - resolution: {integrity: sha512-XJXpRQ41+rsJ/GLeP9vyDC+fBXilcTlEXokMSexkdEkla4uf7ZQNaI5xl3el+kW5TZQulqYxLr659ey/KX7XmQ==} + fastify@5.8.5: + resolution: {integrity: sha512-Yqptv59pQzPgQUSIm87hMqHJmdkb1+GPxdE6vW6FRyVE9G86mt7rOghitiU4JHRaTyDUk9pfeKmDeu70lAwM4Q==} fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -7236,8 +7242,8 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} - hono@4.12.12: - resolution: {integrity: sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==} + hono@4.12.14: + resolution: {integrity: sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==} engines: {node: '>=16.9.0'} hookified@1.15.1: @@ -7266,10 +7272,6 @@ packages: htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - http-errors@2.0.1: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} @@ -7373,10 +7375,6 @@ packages: resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} - ioredis@5.9.3: - resolution: {integrity: sha512-VI5tMCdeoxZWU5vjHWsiE/Su76JGhBvWF1MJnV9ZtGltHk9BmD48oDq8Tj8haZ85aceXZMxLNDQZRVo5QKNgXA==} - engines: {node: '>=12.22.0'} - ip-address@10.1.0: resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} @@ -8023,8 +8021,8 @@ packages: resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} engines: {node: '>=20.10.0', npm: '>=10.2.3'} - langsmith@0.5.18: - resolution: {integrity: sha512-3zuZUWffTHQ+73EAwnodADtf534VNEZUpXr9jC12qyG8/IQuJET7PRsCpTb9wX2lmBspakwLUpqpj3tNm/0bVA==} + langsmith@0.5.19: + resolution: {integrity: sha512-5tFoETuFMvGkbPGsINNlIE4Ab86CsPhdPOQZCGwNt/NX0h5NDKQLKOWS/G2XcRUBOQl4mCNbrayUvUTWaIRsCg==} peerDependencies: '@opentelemetry/api': '*' '@opentelemetry/exporter-trace-otlp-proto': '*' @@ -9038,8 +9036,8 @@ packages: resolution: {integrity: sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==} engines: {node: '>=12'} - posthog-js@1.363.1: - resolution: {integrity: sha512-iaDtRxCs/FiB+RXe83uo7RZXgpLlyB6qFoNHl3bNMgRCgrPI2nkzx2m9Va1l30HHl/zA1kPOXSy2/tZC5Ql5kg==} + posthog-js@1.370.0: + resolution: {integrity: sha512-0PQCUO6EGbXaOPgXYrcafrXa9B13nDaGc91xCiuwNPK80oovqTmeHfNUNCv1r+xCpEoxw3L1FyBuuLCt5Zz7rg==} postmark@4.0.7: resolution: {integrity: sha512-DjNniUl1XNCGUKhCR98ePd5gv16rlUAVKKaU9TUqnE3hDSqfT9XDulu1idjagQmdyGscqnRtXk/puAEiYMeevg==} @@ -9754,10 +9752,6 @@ packages: standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} @@ -10450,8 +10444,8 @@ packages: resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} engines: {node: '>=10.13.0'} - webpack@5.105.4: - resolution: {integrity: sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw==} + webpack@5.106.0: + resolution: {integrity: sha512-Pkx5joZ9RrdgO5LBkyX1L2ZAJeK/Taz3vqZ9CbcP0wS5LEMx5QkKsEwLl29QJfihZ+DKRBFldzy1O30pJ1MDpA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -10776,10 +10770,21 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@angular-devkit/schematics-cli@19.2.23(@types/node@25.5.0)(chokidar@4.0.3)': + '@angular-devkit/core@19.2.24(chokidar@4.0.3)': dependencies: - '@angular-devkit/core': 19.2.23(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.23(chokidar@4.0.3) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + jsonc-parser: 3.3.1 + picomatch: 4.0.4 + rxjs: 7.8.1 + source-map: 0.7.4 + optionalDependencies: + chokidar: 4.0.3 + + '@angular-devkit/schematics-cli@19.2.24(@types/node@25.5.0)(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) '@inquirer/prompts': 7.3.2(@types/node@25.5.0) ansi-colors: 4.1.3 symbol-observable: 4.0.0 @@ -10798,6 +10803,16 @@ snapshots: transitivePeerDependencies: - chokidar + '@angular-devkit/schematics@19.2.24(chokidar@4.0.3)': + dependencies: + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + jsonc-parser: 3.3.1 + magic-string: 0.30.17 + ora: 5.4.1 + rxjs: 7.8.1 + transitivePeerDependencies: + - chokidar + '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.3.0 @@ -12496,7 +12511,7 @@ snapshots: dependencies: dequal: 2.0.3 - '@fastify/multipart@9.4.0': + '@fastify/multipart@10.0.0': dependencies: '@fastify/busboy': 3.1.1 '@fastify/deepmerge': 3.1.0 @@ -12514,10 +12529,10 @@ snapshots: '@lukeed/ms': 2.0.2 escape-html: 1.0.3 fast-decode-uri-component: 1.0.1 - http-errors: 2.0.0 + http-errors: 2.0.1 mime: 3.0.0 - '@fastify/static@9.0.0': + '@fastify/static@9.1.3': dependencies: '@fastify/accept-negotiator': 2.0.1 '@fastify/send': 4.1.0 @@ -12594,9 +12609,9 @@ snapshots: y-prosemirror: 1.3.7(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.40.0)(y-protocols@1.0.6(yjs@13.6.30))(yjs@13.6.30) yjs: 13.6.30 - '@hono/node-server@1.19.13(hono@4.12.12)': + '@hono/node-server@1.19.13(hono@4.12.14)': dependencies: - hono: 4.12.12 + hono: 4.12.14 '@humanfs/core@0.19.1': {} @@ -12759,8 +12774,6 @@ snapshots: optionalDependencies: '@types/node': 25.5.0 - '@ioredis/commands@1.5.0': {} - '@ioredis/commands@1.5.1': {} '@istanbuljs/load-nyc-config@1.1.0': @@ -13027,7 +13040,7 @@ snapshots: camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.5.18(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) + langsmith: 0.5.19(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) mustache: 4.2.0 p-queue: 6.6.2 uuid: 11.1.0 @@ -13123,7 +13136,7 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@4.3.6)': dependencies: - '@hono/node-server': 1.19.13(hono@4.12.12) + '@hono/node-server': 1.19.13(hono@4.12.14) ajv: 8.18.0 ajv-formats: 3.0.1(ajv@8.18.0) content-type: 1.0.5 @@ -13133,7 +13146,7 @@ snapshots: eventsource-parser: 3.0.6 express: 5.2.1 express-rate-limit: 8.2.2(express@5.2.1) - hono: 4.12.12 + hono: 4.12.14 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -13231,63 +13244,63 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@nest-lab/throttler-storage-redis@1.2.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/throttler@6.5.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2))(ioredis@5.10.1)(reflect-metadata@0.2.2)': + '@nest-lab/throttler-storage-redis@1.2.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/throttler@6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2))(ioredis@5.10.1)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/throttler': 6.5.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/throttler': 6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2) ioredis: 5.10.1 reflect-metadata: 0.2.2 tslib: 2.8.1 - '@nestjs-labs/nestjs-ioredis@11.0.4(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(ioredis@5.10.1)': + '@nestjs-labs/nestjs-ioredis@11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(ioredis@5.10.1)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) ioredis: 5.10.1 tslib: 2.8.1 - '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(bullmq@5.71.0)': + '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(bullmq@5.76.0)': dependencies: - '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) - bullmq: 5.71.0 + '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) + bullmq: 5.76.0 tslib: 2.8.1 - '@nestjs/cache-manager@3.1.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2)': + '@nestjs/cache-manager@3.1.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(cache-manager@7.2.8)(keyv@5.6.0)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) cache-manager: 7.2.8 keyv: 5.6.0 rxjs: 7.8.2 - '@nestjs/cli@11.0.18(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@25.5.0)': + '@nestjs/cli@11.0.21(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@25.5.0)': dependencies: - '@angular-devkit/core': 19.2.23(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.23(chokidar@4.0.3) - '@angular-devkit/schematics-cli': 19.2.23(@types/node@25.5.0)(chokidar@4.0.3) + '@angular-devkit/core': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics': 19.2.24(chokidar@4.0.3) + '@angular-devkit/schematics-cli': 19.2.24(@types/node@25.5.0)(chokidar@4.0.3) '@inquirer/prompts': 7.10.1(@types/node@25.5.0) '@nestjs/schematics': 11.0.10(chokidar@4.0.3)(typescript@5.9.3) ansis: 4.2.0 chokidar: 4.0.3 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5))) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5))) glob: 13.0.6 node-emoji: 1.11.0 ora: 5.4.1 tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.9.3 - webpack: 5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5)) + webpack: 5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) webpack-node-externals: 3.0.0 optionalDependencies: '@swc/core': 1.5.25(@swc/helpers@0.5.5) @@ -13297,7 +13310,7 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: file-type: 21.3.4 iterare: 1.2.1 @@ -13312,17 +13325,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/config@4.0.3(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': + '@nestjs/config@4.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - dotenv: 17.2.3 + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + dotenv: 17.4.1 dotenv-expand: 12.0.3 lodash: 4.18.1 rxjs: 7.8.2 - '@nestjs/core@11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -13332,41 +13345,41 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/websockets': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-socket.io@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) eventemitter2: 6.4.9 - '@nestjs/jwt@11.0.2(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))': + '@nestjs/jwt@11.0.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@types/jsonwebtoken': 9.0.10 jsonwebtoken: 9.0.3 - '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': + '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.15.1 - '@nestjs/passport@11.0.5(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': + '@nestjs/passport@11.0.5(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) passport: 0.7.0 - '@nestjs/platform-fastify@11.1.18(@fastify/static@9.0.0)(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/platform-fastify@11.1.19(@fastify/static@9.1.3)(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': dependencies: '@fastify/cors': 11.2.0 '@fastify/formbody': 8.0.2 - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) fast-querystring: 1.1.2 - fastify: 5.8.3 + fastify: 5.8.5 fastify-plugin: 5.1.0 find-my-way: 9.5.0 light-my-request: 6.6.0 @@ -13374,12 +13387,12 @@ snapshots: reusify: 1.1.0 tslib: 2.8.1 optionalDependencies: - '@fastify/static': 9.0.0 + '@fastify/static': 9.1.3 - '@nestjs/platform-socket.io@11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(rxjs@7.8.2)': + '@nestjs/platform-socket.io@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/websockets': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-socket.io@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) rxjs: 7.8.2 socket.io: 4.8.3 tslib: 2.8.1 @@ -13388,10 +13401,10 @@ snapshots: - supports-color - utf-8-validate - '@nestjs/schedule@6.1.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/schedule@6.1.3(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) cron: 4.4.0 '@nestjs/schematics@11.0.10(chokidar@4.0.3)(typescript@5.9.3)': @@ -13405,38 +13418,38 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/terminus@11.1.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/terminus@11.1.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) boxen: 5.1.2 check-disk-space: 3.4.0 reflect-metadata: 0.2.2 rxjs: 7.8.2 - '@nestjs/testing@11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/testing@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/throttler@6.5.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)': + '@nestjs/throttler@6.5.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 - '@nestjs/websockets@11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/websockets@11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(@nestjs/platform-socket.io@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) iterare: 1.2.1 object-hash: 3.0.0 reflect-metadata: 0.2.2 rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-socket.io': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(rxjs@7.8.2) + '@nestjs/platform-socket.io': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(rxjs@7.8.2) '@noble/hashes@1.8.0': {} @@ -13653,11 +13666,9 @@ snapshots: '@pkgr/core@0.2.9': {} - '@posthog/core@1.24.1': - dependencies: - cross-spawn: 7.0.6 + '@posthog/core@1.26.0': {} - '@posthog/types@1.363.1': {} + '@posthog/types@1.370.0': {} '@protobufjs/aspromise@1.1.2': {} @@ -16487,10 +16498,10 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bullmq@5.71.0: + bullmq@5.76.0: dependencies: cron-parser: 4.9.0 - ioredis: 5.9.3 + ioredis: 5.10.1 msgpackr: 1.11.5 node-abort-controller: 3.1.1 semver: 7.7.4 @@ -17229,7 +17240,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.3.3: + dompurify@3.4.1: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -17253,10 +17264,10 @@ snapshots: dotenv@16.4.7: {} - dotenv@17.2.3: {} - dotenv@17.2.4: {} + dotenv@17.4.1: {} + duck@0.1.12: dependencies: underscore: 1.13.8 @@ -17329,11 +17340,6 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.19.0: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.0 - enhanced-resolve@5.20.1: dependencies: graceful-fs: 4.2.11 @@ -17845,7 +17851,7 @@ snapshots: fastify-plugin@5.1.0: {} - fastify@5.8.3: + fastify@5.8.5: dependencies: '@fastify/ajv-compiler': 4.0.5 '@fastify/error': 4.0.0 @@ -17950,7 +17956,7 @@ snapshots: dependencies: is-callable: 1.2.7 - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5))): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 @@ -17965,7 +17971,7 @@ snapshots: semver: 7.7.4 tapable: 2.3.0 typescript: 5.9.3 - webpack: 5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5)) + webpack: 5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) form-data@4.0.5: dependencies: @@ -18182,7 +18188,7 @@ snapshots: dependencies: react-is: 16.13.1 - hono@4.12.12: {} + hono@4.12.14: {} hookified@1.15.1: {} @@ -18220,14 +18226,6 @@ snapshots: domutils: 3.2.2 entities: 4.5.0 - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - http-errors@2.0.1: dependencies: depd: 2.0.0 @@ -18339,20 +18337,6 @@ snapshots: transitivePeerDependencies: - supports-color - ioredis@5.9.3: - dependencies: - '@ioredis/commands': 1.5.0 - cluster-key-slot: 1.1.2 - debug: 4.4.3 - denque: 2.1.0 - lodash.defaults: 4.2.0 - lodash.isarguments: 3.1.0 - redis-errors: 1.2.0 - redis-parser: 3.0.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color - ip-address@10.1.0: {} ipaddr.js@1.9.1: {} @@ -19176,7 +19160,7 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - langsmith@0.5.18(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0): + langsmith@0.5.19(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0): dependencies: p-queue: 6.6.2 uuid: 10.0.0 @@ -19463,7 +19447,7 @@ snapshots: d3-sankey: 0.12.3 dagre-d3-es: 7.0.14 dayjs: 1.11.19 - dompurify: 3.3.3 + dompurify: 3.4.1 katex: 0.16.40 khroma: 2.1.0 lodash-es: 4.18.1 @@ -19585,23 +19569,23 @@ snapshots: neo-async@2.6.2: {} - nestjs-cls@6.2.0(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2): + nestjs-cls@6.2.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 rxjs: 7.8.2 - nestjs-kysely@3.1.2(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.14)(reflect-metadata@0.2.2): + nestjs-kysely@3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.14)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) kysely: 0.28.14 reflect-metadata: 0.2.2 - nestjs-pino@4.6.1(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2): + nestjs-pino@4.6.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) pino: 10.1.0 pino-http: 11.0.0 rxjs: 7.8.2 @@ -20203,17 +20187,17 @@ snapshots: postgres@3.4.8: {} - posthog-js@1.363.1: + posthog-js@1.370.0: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.208.0 '@opentelemetry/exporter-logs-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.5.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) - '@posthog/core': 1.24.1 - '@posthog/types': 1.363.1 + '@posthog/core': 1.26.0 + '@posthog/types': 1.370.0 core-js: 3.43.0 - dompurify: 3.3.3 + dompurify: 3.4.1 fflate: 0.4.8 preact: 10.28.3 query-selector-shadow-dom: 1.0.1 @@ -21144,8 +21128,6 @@ snapshots: standard-as-callback@2.1.0: {} - statuses@2.0.1: {} - statuses@2.0.2: {} stdin-discarder@0.2.2: {} @@ -21341,13 +21323,13 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - terser-webpack-plugin@5.4.0(@swc/core@1.5.25(@swc/helpers@0.5.5))(webpack@5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5))): + terser-webpack-plugin@5.4.0(@swc/core@1.5.25(@swc/helpers@0.5.5))(webpack@5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.39.0 - webpack: 5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5)) + webpack: 5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) optionalDependencies: '@swc/core': 1.5.25(@swc/helpers@0.5.5) @@ -21451,7 +21433,7 @@ snapshots: babel-jest: 30.3.0(@babel/core@7.28.5) jest-util: 30.3.0 - ts-loader@9.5.7(typescript@5.9.3)(webpack@5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5))): + ts-loader@9.5.7(typescript@5.9.3)(webpack@5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5))): dependencies: chalk: 4.1.2 enhanced-resolve: 5.20.1 @@ -21459,7 +21441,7 @@ snapshots: semver: 7.7.4 source-map: 0.7.4 typescript: 5.9.3 - webpack: 5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5)) + webpack: 5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5)) ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@25.5.0)(typescript@5.9.3): dependencies: @@ -21484,7 +21466,7 @@ snapshots: tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.19.0 + enhanced-resolve: 5.20.1 tapable: 2.3.0 tsconfig-paths: 4.2.0 @@ -21834,7 +21816,7 @@ snapshots: webpack-sources@3.3.4: {} - webpack@5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5)): + webpack@5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -21858,7 +21840,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.4.0(@swc/core@1.5.25(@swc/helpers@0.5.5))(webpack@5.105.4(@swc/core@1.5.25(@swc/helpers@0.5.5))) + terser-webpack-plugin: 5.4.0(@swc/core@1.5.25(@swc/helpers@0.5.5))(webpack@5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5))) watchpack: 2.5.1 webpack-sources: 3.3.4 transitivePeerDependencies: From ec83fc82d54bf3728eaa63b20eb4abcb5aef1d97 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:16:26 +0100 Subject: [PATCH 02/46] fix: refactor sanitize --- apps/server/package.json | 5 ++- apps/server/src/common/helpers/utils.spec.ts | Bin 0 -> 3319 bytes apps/server/src/common/helpers/utils.ts | 34 ++++++++++++++---- .../core/attachment/attachment.controller.ts | 15 +++++--- .../integrations/export/export.controller.ts | 19 +++++++--- .../import/services/import.service.ts | 5 ++- pnpm-lock.yaml | 12 +++---- 7 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 apps/server/src/common/helpers/utils.spec.ts diff --git a/apps/server/package.json b/apps/server/package.json index 97af8db7d..c36e9002f 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -110,7 +110,7 @@ "react": "^18.3.1", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.2", - "sanitize-filename-ts": "1.0.2", + "sanitize-filename": "1.6.3", "socket.io": "^4.8.3", "stripe": "^17.7.0", "tlds": "^1.261.0", @@ -165,6 +165,9 @@ "transform": { "^.+\\.(t|j)s$": "ts-jest" }, + "transformIgnorePatterns": [ + "/node_modules/(?!(\\.pnpm/)?(nanoid|uuid|image-dimensions|marked)(@|/))" + ], "collectCoverageFrom": [ "**/*.(t|j)s" ], diff --git a/apps/server/src/common/helpers/utils.spec.ts b/apps/server/src/common/helpers/utils.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..f444e007163fb39fade37d42ba08652ec0621ec3 GIT binary patch literal 3319 zcmc&$&2r;J5ayhx=t{~+24~_m>&q^?6l~!WWZ8n#{#0r#wX7+|l6GbkM}$;y;sGdL zBF~XG*(ae}e;(OM2)W>sr`0pl{q@)1v|1Orac~J%X3DAGaG^Aw$~D3jBqm=&AWllB zv<;pg9K>iNqm~#3yWYVB!ZEyf36}=|Telb!S!xHNb-9r%Jhn2y@xU2CIe{`t!*{fm zfA0dT)`dplE*!b~s}GajXI()-CyI5OjVr=-Eggc&iqgU1 z$R5I{KmV%#&;em>o&a7H7&(l4C>f8&816#e>=}=R%fG|0-}$^o=xR*m;?4WuCRE_B zxsHW3X4^nvkjgA3^dQd5rA9B}O6M}RAQOiM@(fA(I2p>tT5jt>AD^7SXf~fM zS|>{zA_SL{bpfHq#DOHOP;?eC@zWoFLza`N0mfn>jU*LqQ>VkaTXp4KJr=N#)~Tcd zsSV1wqNpi!FF5JIr3fZ39d1w4vO+Tfo5QlIzms55bg8nCqNZYjMLI{hNt*?!DJ&^n z@}dMfVWzk?sftqA@Mg?9L@3R}lS3dNp>8?R-h7w15tVDOdRlfuSAW>{29=3r?(Smm z`nP)Nw@Q14r@khc7{&d+-oei2vmO>hZ4sRa|Qtp*Y zn+Es+t^I|9dTqY{SV|pIs9qb83et*LupQ+JgBHy>{#-~Ve_l96Bpqs;a^1vZ8!vA6 zBPcVMmr;s5sSPEujkl#6^w2Em`8cH+BMg45;3pdM;OI#+#9hKLkZ0gbNyF;66QHiY zha0`z>dQD%Qc0~FHQF5jIPP2DDQeY6Bte5tH?B4V*MqYV!r!<{>w9pkCkTJ1D { + try { + return decodeURIComponent(m); + } catch { + return m; + } + }); + + const sanitized = sanitize(decoded); + if (options.preserveSpaces) { + return sanitized; + } + return sanitized.replace(/ /g, '_').replace(/#/g, '_'); } export function removeAccent(str: string): string { diff --git a/apps/server/src/core/attachment/attachment.controller.ts b/apps/server/src/core/attachment/attachment.controller.ts index 784e527e6..736058191 100644 --- a/apps/server/src/core/attachment/attachment.controller.ts +++ b/apps/server/src/core/attachment/attachment.controller.ts @@ -53,7 +53,6 @@ import { EnvironmentService } from '../../integrations/environment/environment.s import { TokenService } from '../auth/services/token.service'; import { JwtAttachmentPayload, JwtType } from '../auth/dto/jwt-payload'; import * as path from 'path'; -import { sanitize } from 'sanitize-filename-ts'; import { AttachmentInfoDto, RemoveIconDto } from './dto/attachment.dto'; import { PageAccessService } from '../page/page-access/page-access.service'; import { AuditEvent, AuditResource } from '../../common/events/audit-events'; @@ -357,13 +356,19 @@ export class AttachmentController { throw new BadRequestException('Invalid image attachment type'); } - if (!fileName || sanitize(fileName) !== fileName) { + if (!fileName) { throw new BadRequestException('Invalid file name'); } - const filenameWithoutExt = path.basename(fileName, path.extname(fileName)); - if (!isValidUUID(filenameWithoutExt)) { - throw new BadRequestException('Invalid file id'); + const ext = path.extname(fileName); + const filenameWithoutExt = path.basename(fileName, ext); + + if ( + !ext || + !isValidUUID(filenameWithoutExt) || + `${filenameWithoutExt}${ext}` !== fileName + ) { + throw new BadRequestException('Invalid file name'); } const filePath = `${getAttachmentFolderPath(attachmentType, workspace.id)}/${fileName}`; diff --git a/apps/server/src/integrations/export/export.controller.ts b/apps/server/src/integrations/export/export.controller.ts index 1ce3f8c84..140622da7 100644 --- a/apps/server/src/integrations/export/export.controller.ts +++ b/apps/server/src/integrations/export/export.controller.ts @@ -23,9 +23,12 @@ import { SpaceCaslSubject, } from '../../core/casl/interfaces/space-ability.type'; import { FastifyReply } from 'fastify'; -import { sanitize } from 'sanitize-filename-ts'; import { getExportExtension } from './utils'; -import { getMimeType, getPageTitle } from '../../common/helpers'; +import { + getMimeType, + getPageTitle, + sanitizeFileName, +} from '../../common/helpers'; import * as path from 'path'; import { AuditEvent, AuditResource } from '../../common/events/audit-events'; import { @@ -85,7 +88,9 @@ export class ExportController { if (result.type === 'file') { const ext = getExportExtension(dto.format); - const fileName = sanitize(page.title || 'untitled') + ext; + const fileName = + sanitizeFileName(page.title || 'untitled', { preserveSpaces: true }) + + ext; const contentType = getMimeType(path.extname(fileName)); res.headers({ @@ -96,7 +101,9 @@ export class ExportController { res.send(result.content); } else { - const fileName = sanitize(page.title || 'untitled') + '.zip'; + const fileName = + sanitizeFileName(page.title || 'untitled', { preserveSpaces: true }) + + '.zip'; res.headers({ 'Content-Type': 'application/zip', @@ -144,7 +151,9 @@ export class ExportController { 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="' + - encodeURIComponent(sanitize(exportFile.fileName)) + + encodeURIComponent( + sanitizeFileName(exportFile.fileName, { preserveSpaces: true }), + ) + '"', }); diff --git a/apps/server/src/integrations/import/services/import.service.ts b/apps/server/src/integrations/import/services/import.service.ts index 231a6c89a..66c575850 100644 --- a/apps/server/src/integrations/import/services/import.service.ts +++ b/apps/server/src/integrations/import/services/import.service.ts @@ -1,7 +1,6 @@ import { BadRequestException, Injectable, Logger } from '@nestjs/common'; import { PageRepo } from '@docmost/db/repos/page/page.repo'; import { MultipartFile } from '@fastify/multipart'; -import { sanitize } from 'sanitize-filename-ts'; import * as path from 'path'; import { htmlToJson, @@ -53,8 +52,8 @@ export class ImportService { const file = await filePromise; const fileBuffer = await file.toBuffer(); const fileExtension = path.extname(file.filename).toLowerCase(); - const fileName = sanitize( - path.basename(file.filename, fileExtension).slice(0, 255), + const fileName = sanitizeFileName( + path.basename(file.filename, fileExtension), ); const fileContent = fileBuffer.toString(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 56dd6d794..fe7a20429 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -697,9 +697,9 @@ importers: rxjs: specifier: ^7.8.2 version: 7.8.2 - sanitize-filename-ts: - specifier: 1.0.2 - version: 1.0.2 + sanitize-filename: + specifier: 1.6.3 + version: 1.6.3 socket.io: specifier: ^4.8.3 version: 4.8.3 @@ -9570,8 +9570,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sanitize-filename-ts@1.0.2: - resolution: {integrity: sha512-bON2VOJoappmaBHlnxvBNk5R7HkUAsirf5m1M5Kz15uZykDGbHfGPCQNcEQKR8HrQhgh9CmQ6Xe9y71yM9ywkw==} + sanitize-filename@1.6.3: + resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} sass@1.51.0: resolution: {integrity: sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA==} @@ -20900,7 +20900,7 @@ snapshots: safer-buffer@2.1.2: {} - sanitize-filename-ts@1.0.2: + sanitize-filename@1.6.3: dependencies: truncate-utf8-bytes: 1.0.2 From 8e15b22d8cdbbf511571910555ef90a1728c1a34 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:22:02 +0100 Subject: [PATCH 03/46] package updates --- apps/client/package.json | 8 +- apps/server/package.json | 6 +- apps/server/src/ee | 2 +- package.json | 7 +- pnpm-lock.yaml | 1242 +++++++++++++++++++------------------- 5 files changed, 635 insertions(+), 630 deletions(-) diff --git a/apps/client/package.json b/apps/client/package.json index bdf222097..b54b86091 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -31,8 +31,8 @@ "emoji-mart": "^5.6.0", "file-saver": "^2.0.5", "highlightjs-sap-abap": "^0.3.0", - "i18next": "^25.10.1", - "i18next-http-backend": "^3.0.2", + "i18next": "25.10.1", + "i18next-http-backend": "3.0.6", "jotai": "^2.18.1", "jotai-optics": "^0.4.0", "js-cookie": "^3.0.5", @@ -42,7 +42,7 @@ "mantine-form-zod-resolver": "^1.3.0", "mermaid": "^11.13.0", "mitt": "^3.0.1", - "posthog-js": "1.370.0", + "posthog-js": "1.372.2", "react": "^18.3.1", "react-arborist": "3.4.0", "react-clear-modal": "^2.0.18", @@ -50,7 +50,7 @@ "react-drawio": "^1.0.7", "react-error-boundary": "^6.1.1", "react-helmet-async": "^3.0.0", - "react-i18next": "^16.5.8", + "react-i18next": "16.5.8", "react-router-dom": "^7.13.1", "semver": "^7.7.4", "socket.io-client": "^4.8.3", diff --git a/apps/server/package.json b/apps/server/package.json index c36e9002f..10a13b61d 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -33,9 +33,9 @@ "@ai-sdk/google": "^3.0.52", "@ai-sdk/openai": "^3.0.47", "@ai-sdk/openai-compatible": "^2.0.37", - "@aws-sdk/client-s3": "3.1014.0", - "@aws-sdk/lib-storage": "3.1014.0", - "@aws-sdk/s3-request-presigner": "3.1014.0", + "@aws-sdk/client-s3": "3.1037.0", + "@aws-sdk/lib-storage": "3.1037.0", + "@aws-sdk/s3-request-presigner": "3.1037.0", "@clickhouse/client": "^1.18.2", "@fastify/cookie": "^11.0.2", "@fastify/multipart": "^10.0.0", diff --git a/apps/server/src/ee b/apps/server/src/ee index e703b8bf4..36d6b68b9 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit e703b8bf47c0d880a1b6acd2b4216167d8e67ff3 +Subproject commit 36d6b68b9307685c362ba9eaf6d1b8e39fee0762 diff --git a/package.json b/package.json index 6d3d97c2d..3e4b7373c 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "ms": "3.0.0-canary.1", "qrcode": "^1.5.4", "rfc6902": "5.2.0", - "uuid": "^13.0.0", + "uuid": "^14.0.0", "y-indexeddb": "^9.0.12", "y-prosemirror": "1.3.7", "yjs": "^13.6.30" @@ -128,11 +128,12 @@ "yaml@>=2.0.0 <2.8.3": "2.8.3", "path-to-regexp@^8": "8.4.0", "brace-expansion@^5": "5.0.5", - "@xmldom/xmldom": "0.8.12", + "@xmldom/xmldom": "0.8.13", "handlebars": "4.7.9", "axios": "1.15.0", "langsmith": "0.5.19", - "follow-redirects": "1.16.0" + "follow-redirects": "1.16.0", + "protobufjs": "7.5.5" }, "neverBuiltDependencies": [] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fe7a20429..73f773844 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,11 +35,12 @@ overrides: yaml@>=2.0.0 <2.8.3: 2.8.3 path-to-regexp@^8: 8.4.0 brace-expansion@^5: 5.0.5 - '@xmldom/xmldom': 0.8.12 + '@xmldom/xmldom': 0.8.13 handlebars: 4.7.9 axios: 1.15.0 langsmith: 0.5.19 follow-redirects: 1.16.0 + protobufjs: 7.5.5 patchedDependencies: react-arborist@3.4.0: @@ -210,8 +211,8 @@ importers: specifier: 5.2.0 version: 5.2.0 uuid: - specifier: ^13.0.0 - version: 13.0.0 + specifier: ^14.0.0 + version: 14.0.0 y-indexeddb: specifier: ^9.0.12 version: 9.0.12(yjs@13.6.30) @@ -310,11 +311,11 @@ importers: specifier: ^0.3.0 version: 0.3.0 i18next: - specifier: ^25.10.1 + specifier: 25.10.1 version: 25.10.1(typescript@5.9.3) i18next-http-backend: - specifier: ^3.0.2 - version: 3.0.2 + specifier: 3.0.6 + version: 3.0.6 jotai: specifier: ^2.18.1 version: 2.18.1(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@18.3.12)(react@18.3.1) @@ -343,8 +344,8 @@ importers: specifier: ^3.0.1 version: 3.0.1 posthog-js: - specifier: 1.370.0 - version: 1.370.0 + specifier: 1.372.2 + version: 1.372.2 react: specifier: ^18.3.1 version: 18.3.1 @@ -367,7 +368,7 @@ importers: specifier: ^3.0.0 version: 3.0.0(react@18.3.1) react-i18next: - specifier: ^16.5.8 + specifier: 16.5.8 version: 16.5.8(i18next@25.10.1(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) react-router-dom: specifier: ^7.13.1 @@ -467,14 +468,14 @@ importers: specifier: ^2.0.37 version: 2.0.37(zod@4.3.6) '@aws-sdk/client-s3': - specifier: 3.1014.0 - version: 3.1014.0 + specifier: 3.1037.0 + version: 3.1037.0 '@aws-sdk/lib-storage': - specifier: 3.1014.0 - version: 3.1014.0(@aws-sdk/client-s3@3.1014.0) + specifier: 3.1037.0 + version: 3.1037.0(@aws-sdk/client-s3@3.1037.0) '@aws-sdk/s3-request-presigner': - specifier: 3.1014.0 - version: 3.1014.0 + specifier: 3.1037.0 + version: 3.1037.0 '@clickhouse/client': specifier: ^1.18.2 version: 1.18.2 @@ -931,141 +932,141 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-s3@3.1014.0': - resolution: {integrity: sha512-0XLrOT4Cm3NEhhiME7l/8LbTXS4KdsbR4dSrY207KNKTcHLLTZ9EXt4ZpgnTfLvWQF3pGP2us4Zi1fYLo0N+Ow==} + '@aws-sdk/client-s3@3.1037.0': + resolution: {integrity: sha512-DBmA1jAW8ST6C4srBxeL1/RLIir/d8WOm4s4mi59mGp6mBktHM59Kwb7GuURaCO60cotuce5zr0sKpMLPcBQyA==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.973.26': - resolution: {integrity: sha512-A/E6n2W42ruU+sfWk+mMUOyVXbsSgGrY3MJ9/0Az5qUdG67y8I6HYzzoAa+e/lzxxl1uCYmEL6BTMi9ZiZnplQ==} + '@aws-sdk/core@3.974.5': + resolution: {integrity: sha512-lMPlYlYfQdNZhlkJgnkmESwrY+hNh3PljmZ+37oAqLNdJ6rnILAwFSyc6B3bJeDOtMORNnMQIej0aTRuOlDyhQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/crc64-nvme@3.972.5': - resolution: {integrity: sha512-2VbTstbjKdT+yKi8m7b3a9CiVac+pL/IY2PHJwsaGkkHmuuqkJZIErPck1h6P3T9ghQMLSdMPyW6Qp7Di5swFg==} + '@aws-sdk/crc64-nvme@3.972.7': + resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.24': - resolution: {integrity: sha512-FWg8uFmT6vQM7VuzELzwVo5bzExGaKHdubn0StjgrcU5FvuLExUe+k06kn/40uKv59rYzhez8eFNM4yYE/Yb/w==} + '@aws-sdk/credential-provider-env@3.972.31': + resolution: {integrity: sha512-X/yGB73LmDW/6MdDJGCDzZBUXnM3ys4vs9l+5ZTJmiEswDdP1OjeoAFlFjVGS9o4KB2wZWQ9KOfdVNSSK6Ep3w==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.26': - resolution: {integrity: sha512-CY4ppZ+qHYqcXqBVi//sdHST1QK3KzOEiLtpLsc9W2k2vfZPKExGaQIsOwcyvjpjUEolotitmd3mUNY56IwDEA==} + '@aws-sdk/credential-provider-http@3.972.33': + resolution: {integrity: sha512-c0ZF+lwoWVvX5iCaGKL5T/4DnIw88CGqxA0BcBs3U86mIp5EZYPVg+KSPkMXOyokmADvNewiMUfSG2uFwjRp0g==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.28': - resolution: {integrity: sha512-wXYvq3+uQcZV7k+bE4yDXCTBdzWTU9x/nMiKBfzInmv6yYK1veMK0AKvRfRBd72nGWYKcL6AxwiPg9z/pYlgpw==} + '@aws-sdk/credential-provider-ini@3.972.35': + resolution: {integrity: sha512-jsU4u/cRkKFLKQS0k918FQ27fzXLG5ENiLWQMYE6581zLeI2hWh04ptlrvZMB3wJT/5d+vSzJk74X1CMFr4y8Q==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.28': - resolution: {integrity: sha512-ZSTfO6jqUTCysbdBPtEX5OUR//3rbD0lN7jO3sQeS2Gjr/Y+DT6SbIJ0oT2cemNw3UzKu97sNONd1CwNMthuZQ==} + '@aws-sdk/credential-provider-login@3.972.35': + resolution: {integrity: sha512-5oa3j0cA50jPqgNhZ9XdJVopuzUf1klRb28/2MfLYWWiPi9DRVvbrBWT+DidbHTT36520VuXZJahQwR+YgSjrg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.29': - resolution: {integrity: sha512-clSzDcvndpFJAggLDnDb36sPdlZYyEs5Zm6zgZjjUhwsJgSWiWKwFIXUVBcbruidNyBdbpOv2tNDL9sX8y3/0g==} + '@aws-sdk/credential-provider-node@3.972.36': + resolution: {integrity: sha512-4nT2T8Z7vH8KE9EdjEsuIlHpZSlcaK2PrKbQBjuUGU46BCCzF3WvP0u0Uiosni3Ykmmn4rWLVawoOCLotUtCbg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.24': - resolution: {integrity: sha512-Q2k/XLrFXhEztPHqj4SLCNID3hEPdlhh1CDLBpNnM+1L8fq7P+yON9/9M1IGN/dA5W45v44ylERfXtDAlmMNmw==} + '@aws-sdk/credential-provider-process@3.972.31': + resolution: {integrity: sha512-eKeT4MXumpBJsrDLCYcSzIkFPVTFn/es7It2oogp2OhU/ic7P/+xzFpQx9ZhwtXS57Mc5S42BPWi7lHmvs/nYg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.28': - resolution: {integrity: sha512-IoUlmKMLEITFn1SiCTjPfR6KrE799FBo5baWyk/5Ppar2yXZoUdaRqZzJzK6TcJxx450M8m8DbpddRVYlp5R/A==} + '@aws-sdk/credential-provider-sso@3.972.35': + resolution: {integrity: sha512-bCuBdfnj0KGDMdLp6utMTLiJcFN2ek9EgZinxQZZSc3FxjJ/HSqeqab2cjbnoNfy8RM6suDCsRkmVY1izp9I+A==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.28': - resolution: {integrity: sha512-d+6h0SD8GGERzKe27v5rOzNGKOl0D+l0bWJdqrxH8WSQzHzjsQFIAPgIeOTUwBHVsKKwtSxc91K/SWax6XgswQ==} + '@aws-sdk/credential-provider-web-identity@3.972.35': + resolution: {integrity: sha512-swW6Bwvl8lanyEMtZOWE/oR6yqcRQH4HTQZUVsnDVgoXvRjRywpYpLv2BWwjUFyjPrqsdX6FeTkf4tMSe/qFTQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/lib-storage@3.1014.0': - resolution: {integrity: sha512-mM0/YpIEKKQ1hM9n1Q2HhN1ztjk3oNKqFMYP+cZ57FR3XVU4UOw9Npu7gnjfzkNrS7WTDZMe0wCMuDvvtq1Oeg==} + '@aws-sdk/lib-storage@3.1037.0': + resolution: {integrity: sha512-ZFg5Vf4RKS48xTm7DfXTeR0Rvn/Fcu6YFdRygGnvhA+gW3W0WtsRqM1CzkWevYBztdUUAsZqtGbMj9Eu0OaeEg==} engines: {node: '>=20.0.0'} peerDependencies: - '@aws-sdk/client-s3': ^3.1014.0 + '@aws-sdk/client-s3': ^3.1037.0 - '@aws-sdk/middleware-bucket-endpoint@3.972.8': - resolution: {integrity: sha512-WR525Rr2QJSETa9a050isktyWi/4yIGcmY3BQ1kpHqb0LqUglQHCS8R27dTJxxWNZvQ0RVGtEZjTCbZJpyF3Aw==} + '@aws-sdk/middleware-bucket-endpoint@3.972.10': + resolution: {integrity: sha512-Vbc2frZH7wXlMNd+ZZSXUEs/l1Sv8Jj4zUnIfwrYF5lwaLdXHZ9xx4U3rjUcaye3HRhFVc+E5DbBxpRAbB16BA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-expect-continue@3.972.8': - resolution: {integrity: sha512-5DTBTiotEES1e2jOHAq//zyzCjeMB78lEHd35u15qnrid4Nxm7diqIf9fQQ3Ov0ChH1V3Vvt13thOnrACmfGVQ==} + '@aws-sdk/middleware-expect-continue@3.972.10': + resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.974.6': - resolution: {integrity: sha512-YckB8k1ejbyCg/g36gUMFLNzE4W5cERIa4MtsdO+wpTmJEP0+TB7okWIt7d8TDOvnb7SwvxJ21E4TGOBxFpSWQ==} + '@aws-sdk/middleware-flexible-checksums@3.974.13': + resolution: {integrity: sha512-b6QUe2hQX9XsnCzp6mtzVaERhganDKeb8lmGL6pVhr7rRVH9S9keDFW7uKytuuqmcY5943FixoGqn/QL+sbUBA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-host-header@3.972.8': - resolution: {integrity: sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==} + '@aws-sdk/middleware-host-header@3.972.10': + resolution: {integrity: sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-location-constraint@3.972.8': - resolution: {integrity: sha512-KaUoFuoFPziIa98DSQsTPeke1gvGXlc5ZGMhy+b+nLxZ4A7jmJgLzjEF95l8aOQN2T/qlPP3MrAyELm8ExXucw==} + '@aws-sdk/middleware-location-constraint@3.972.10': + resolution: {integrity: sha512-rI3NZvJcEvjoD0+0PI0iUAwlPw2IlSlhyvgBK/3WkKJQE/YiKFedd9dMN2lVacdNxPNhxL/jzQaKQdrGtQagjQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-logger@3.972.8': - resolution: {integrity: sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==} + '@aws-sdk/middleware-logger@3.972.10': + resolution: {integrity: sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-recursion-detection@3.972.9': - resolution: {integrity: sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==} + '@aws-sdk/middleware-recursion-detection@3.972.11': + resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.27': - resolution: {integrity: sha512-gomO6DZwx+1D/9mbCpcqO5tPBqYBK7DtdgjTIjZ4yvfh/S7ETwAPS0XbJgP2JD8Ycr5CwVrEkV1sFtu3ShXeOw==} + '@aws-sdk/middleware-sdk-s3@3.972.34': + resolution: {integrity: sha512-/UL96JKjsjdodcRRMKl99tLQvK6Oi9ptLC9iU1yiTF/ruaDX0mtBBtnLNZDxIZRJOCVOtB49ed1YaTadqygk8Q==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-ssec@3.972.8': - resolution: {integrity: sha512-wqlK0yO/TxEC2UsY9wIlqeeutF6jjLe0f96Pbm40XscTo57nImUk9lBcw0dPgsm0sppFtAkSlDrfpK+pC30Wqw==} + '@aws-sdk/middleware-ssec@3.972.10': + resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.28': - resolution: {integrity: sha512-cfWZFlVh7Va9lRay4PN2A9ARFzaBYcA097InT5M2CdRS05ECF5yaz86jET8Wsl2WcyKYEvVr/QNmKtYtafUHtQ==} + '@aws-sdk/middleware-user-agent@3.972.35': + resolution: {integrity: sha512-hOFWNOjVmOocpRlrU04nYxjMOeoe0Obu5AXEuhB8zblMCPl3cG1hdluQCZERRKFyhMQjwZnDbhSHjoMUjetFGw==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.996.18': - resolution: {integrity: sha512-c7ZSIXrESxHKx2Mcopgd8AlzZgoXMr20fkx5ViPWPOLBvmyhw9VwJx/Govg8Ef/IhEon5R9l53Z8fdYSEmp6VA==} + '@aws-sdk/nested-clients@3.997.3': + resolution: {integrity: sha512-SivE6GP228IVgfsrr2c/vqTg95X0Qj39Yw4uIrcddpkUzIltNMoNOR62leHOLhODfjv9K8X2mPTwS69A5kT0nQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/region-config-resolver@3.972.10': - resolution: {integrity: sha512-1dq9ToC6e070QvnVhhbAs3bb5r6cQ10gTVc6cyRV5uvQe7P138TV2uG2i6+Yok4bAkVAcx5AqkTEBUvWEtBlsQ==} + '@aws-sdk/region-config-resolver@3.972.13': + resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} engines: {node: '>=20.0.0'} - '@aws-sdk/s3-request-presigner@3.1014.0': - resolution: {integrity: sha512-XEcK50lToSoLPrQztKQhONYQW45613H8oEL00mBUd/+OZgk0+3zJ8kSNDsIJioZ3H7Be+yC3CL6a22dZFIKUXQ==} + '@aws-sdk/s3-request-presigner@3.1037.0': + resolution: {integrity: sha512-rZQS8DxrqPYXzOvaoysf6L4fHmgFbndZz3GfUMhlHG1iWmcQqH7v0AGhpjyNBY3cYAX8+CAkOkD4VUrntnHNbQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.15': - resolution: {integrity: sha512-Ukw2RpqvaL96CjfH/FgfBmy/ZosHBqoHBCFsN61qGg99F33vpntIVii8aNeh65XuOja73arSduskoa4OJea9RQ==} + '@aws-sdk/signature-v4-multi-region@3.996.22': + resolution: {integrity: sha512-/rXhMXteD+BqhFd0nYprAgcZ/KtU+963uftPqd3tiFcFfooHZINXUGtOmo2SQjRVauCTNqIEzkwuSETdZFqTTA==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1021.0': - resolution: {integrity: sha512-TKY6h9spUk3OLs5v1oAgW9mAeBE3LAGNBwJokLy96wwmd4W2v/tYlXseProyed9ValDj2u1jK/4Rg1T+1NXyJA==} + '@aws-sdk/token-providers@3.1036.0': + resolution: {integrity: sha512-aNSJ6jjDYayxN9ZA1JpycVScX93Lx03kKZ1EXt3DGOTahcWVLJj3oLAlop0xKP+vP2Ga2t49p1tEaMkTbCCaZA==} engines: {node: '>=20.0.0'} - '@aws-sdk/types@3.973.6': - resolution: {integrity: sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==} + '@aws-sdk/types@3.973.8': + resolution: {integrity: sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==} engines: {node: '>=20.0.0'} '@aws-sdk/util-arn-parser@3.972.3': resolution: {integrity: sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.996.5': - resolution: {integrity: sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==} + '@aws-sdk/util-endpoints@3.996.8': + resolution: {integrity: sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-format-url@3.972.8': - resolution: {integrity: sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A==} + '@aws-sdk/util-format-url@3.972.10': + resolution: {integrity: sha512-DEKiHNJVtNxdyTeQspzY+15Po/kHm6sF0Cs4HV9Q2+lplB63+DrvdeiSoOSdWEWAoO2RcY1veoXVDz2tWxWCgQ==} engines: {node: '>=20.0.0'} '@aws-sdk/util-locate-window@3.535.0': resolution: {integrity: sha512-PHJ3SL6d2jpcgbqdgiPxkXpu7Drc2PYViwxSIqvvMKhDwzSB1W3mMvtpzwKM4IE7zLFodZo0GKjJ9AsoXndXhA==} engines: {node: '>=14.0.0'} - '@aws-sdk/util-user-agent-browser@3.972.8': - resolution: {integrity: sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==} + '@aws-sdk/util-user-agent-browser@3.972.10': + resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} - '@aws-sdk/util-user-agent-node@3.973.14': - resolution: {integrity: sha512-vNSB/DYaPOyujVZBg/zUznH9QC142MaTHVmaFlF7uzzfg3CgT9f/l4C0Yi+vU/tbBhxVcXVB90Oohk5+o+ZbWw==} + '@aws-sdk/util-user-agent-node@3.973.21': + resolution: {integrity: sha512-Av4UHTcAWgdvbN0IP9pbtf4Qa1+6LtJqQdZWj5pLn5J67w0pnJJAZZ+7JPPcj2KN3378zD2JDM9DwJKEyvyMTQ==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1073,8 +1074,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.16': - resolution: {integrity: sha512-iu2pyvaqmeatIJLURLqx9D+4jKAdTH20ntzB6BFwjyN7V960r4jK32mx0Zf7YbtOYAbmbtQfDNuL60ONinyw7A==} + '@aws-sdk/xml-builder@3.972.19': + resolution: {integrity: sha512-Cw8IOMdBUEIl8ZlhRC3Dc/E64D5B5/8JhV6vhPLiPfJwcRC84S6F8aBOIi/N4vR9ZyA4I5Cc0Ateb/9EHaJXeQ==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.3': @@ -3069,6 +3070,9 @@ packages: resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} engines: {node: '>= 20.19.0'} + '@nodable/entities@2.1.0': + resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} + '@node-saml/node-saml@5.1.0': resolution: {integrity: sha512-t3cJnZ4aC7HhPZ6MGylGZULvUtBOZ6FzuUndaHGXjmIZHXnLfC/7L8a57O9Q9V7AxJGKAiRM5zu2wNm9EsvQpw==} engines: {node: '>= 18'} @@ -3233,11 +3237,11 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@posthog/core@1.26.0': - resolution: {integrity: sha512-q6pSkW7V9RC3rIXjJBo7IBXOH2KPJEh8o+xIcSqw7QD4vq7OYVzTJfUIvkD38+sm54RG/61/3QaPdpQZkDnOyg==} + '@posthog/core@1.27.6': + resolution: {integrity: sha512-FjvgPdORywAjgjtgkZJ2/x9ED52jtOJym/RVldY4Oa7wzmlY49rxZm8gvOlocEnjP90bSbj3ko7qVjXNhftFvA==} - '@posthog/types@1.370.0': - resolution: {integrity: sha512-Hcan3j0L1JZwyaoi8SvbZk41phzHpj5u3/BRn0dFVBlfkbvfhkgXHPETKIZP5CPzjrotOXRLYI4LNRDHp28VsA==} + '@posthog/types@1.372.2': + resolution: {integrity: sha512-dx+WImdDg2NDqaDowTmW+BMNalUfPKngR+g1Iom8ULSav+fGacxexv6fSOl0uSVBwYZsDFe7qNUu0NB/rwGjEw==} '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -4254,10 +4258,6 @@ packages: '@sinonjs/fake-timers@15.1.1': resolution: {integrity: sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==} - '@smithy/abort-controller@4.2.12': - resolution: {integrity: sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q==} - engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader-native@4.2.3': resolution: {integrity: sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==} engines: {node: '>=18.0.0'} @@ -4266,56 +4266,56 @@ packages: resolution: {integrity: sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.4.13': - resolution: {integrity: sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg==} + '@smithy/config-resolver@4.4.17': + resolution: {integrity: sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.23.13': - resolution: {integrity: sha512-J+2TT9D6oGsUVXVEMvz8h2EmdVnkBiy2auCie4aSJMvKlzUtO5hqjEzXhoCUkIMo7gAYjbQcN0g/MMSXEhDs1Q==} + '@smithy/core@3.23.17': + resolution: {integrity: sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.2.12': - resolution: {integrity: sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg==} + '@smithy/credential-provider-imds@4.2.14': + resolution: {integrity: sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.2.12': - resolution: {integrity: sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA==} + '@smithy/eventstream-codec@4.2.14': + resolution: {integrity: sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.2.12': - resolution: {integrity: sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A==} + '@smithy/eventstream-serde-browser@4.2.14': + resolution: {integrity: sha512-8IelTCtTctWRbb+0Dcy+C0aICh1qa0qWXqgjcXDmMuCvPJRnv26hiDZoAau2ILOniki65mCPKqOQs/BaWvO4CQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.3.12': - resolution: {integrity: sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q==} + '@smithy/eventstream-serde-config-resolver@4.3.14': + resolution: {integrity: sha512-sqHiHpYRYo3FJlaIxD1J8PhbcmJAm7IuM16mVnwSkCToD7g00IBZzKuiLNMGmftULmEUX6/UAz8/NN5uMP8bVA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.2.12': - resolution: {integrity: sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA==} + '@smithy/eventstream-serde-node@4.2.14': + resolution: {integrity: sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.2.12': - resolution: {integrity: sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ==} + '@smithy/eventstream-serde-universal@4.2.14': + resolution: {integrity: sha512-lWyt4T2XQZUZgK3tQ3Wn0w3XBvZsK/vjTuJl6bXbnGZBHH0ZUSONTYiK9TgjTTzU54xQr3DRFwpjmhp0oLm3gg==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.15': - resolution: {integrity: sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A==} + '@smithy/fetch-http-handler@5.3.17': + resolution: {integrity: sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==} engines: {node: '>=18.0.0'} - '@smithy/hash-blob-browser@4.2.13': - resolution: {integrity: sha512-YrF4zWKh+ghLuquldj6e/RzE3xZYL8wIPfkt0MqCRphVICjyyjH8OwKD7LLlKpVEbk4FLizFfC1+gwK6XQdR3g==} + '@smithy/hash-blob-browser@4.2.15': + resolution: {integrity: sha512-0PJ4Al3fg2nM4qKrAIxyNcApgqHAXcBkN8FeizOz69z0rb26uZ6lMESYtxegaTlXB5Hj84JfwMPavMrwDMjucA==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.2.12': - resolution: {integrity: sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w==} + '@smithy/hash-node@4.2.14': + resolution: {integrity: sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==} engines: {node: '>=18.0.0'} - '@smithy/hash-stream-node@4.2.12': - resolution: {integrity: sha512-O3YbmGExeafuM/kP7Y8r6+1y0hIh3/zn6GROx0uNlB54K9oihAL75Qtc+jFfLNliTi6pxOAYZrRKD9A7iA6UFw==} + '@smithy/hash-stream-node@4.2.14': + resolution: {integrity: sha512-tw4GANWkZPb6+BdD4Fgucqzey2+r73Z/GRo9zklsCdwrnxxumUV83ZIaBDdudV4Ylazw3EPTiJZhpX42105ruQ==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.2.12': - resolution: {integrity: sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g==} + '@smithy/invalid-dependency@4.2.14': + resolution: {integrity: sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': @@ -4326,76 +4326,76 @@ packages: resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} engines: {node: '>=18.0.0'} - '@smithy/md5-js@4.2.12': - resolution: {integrity: sha512-W/oIpHCpWU2+iAkfZYyGWE+qkpuf3vEXHLxQQDx9FPNZTTdnul0dZ2d/gUFrtQ5je1G2kp4cjG0/24YueG2LbQ==} + '@smithy/md5-js@4.2.14': + resolution: {integrity: sha512-V2v0vx+h0iUSNG1Alt+GNBMSLGCrl9iVsdd+Ap67HPM9PN479x12V8LkuMoKImNZxn3MXeuyUjls+/7ZACZghA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.12': - resolution: {integrity: sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA==} + '@smithy/middleware-content-length@4.2.14': + resolution: {integrity: sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.28': - resolution: {integrity: sha512-p1gfYpi91CHcs5cBq982UlGlDrxoYUX6XdHSo91cQ2KFuz6QloHosO7Jc60pJiVmkWrKOV8kFYlGFFbQ2WUKKQ==} + '@smithy/middleware-endpoint@4.4.32': + resolution: {integrity: sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.4.46': - resolution: {integrity: sha512-SpvWNNOPOrKQGUqZbEPO+es+FRXMWvIyzUKUOYdDgdlA6BdZj/R58p4umoQ76c2oJC44PiM7mKizyyex1IJzow==} + '@smithy/middleware-retry@4.5.5': + resolution: {integrity: sha512-wnYOpB5vATFKWrY2Z9Alb0KhjZI6AbzU6Fbz3Hq2GnURdRYWB4q+qWivQtSTwXcmWUA3MZ6krfwL6Cq5MAbxsA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.16': - resolution: {integrity: sha512-beqfV+RZ9RSv+sQqor3xroUUYgRFCGRw6niGstPG8zO9LgTl0B0MCucxjmrH/2WwksQN7UUgI7KNANoZv+KALA==} + '@smithy/middleware-serde@4.2.20': + resolution: {integrity: sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.12': - resolution: {integrity: sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw==} + '@smithy/middleware-stack@4.2.14': + resolution: {integrity: sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.12': - resolution: {integrity: sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw==} + '@smithy/node-config-provider@4.3.14': + resolution: {integrity: sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.5.1': - resolution: {integrity: sha512-ejjxdAXjkPIs9lyYyVutOGNOraqUE9v/NjGMKwwFrfOM354wfSD8lmlj8hVwUzQmlLLF4+udhfCX9Exnbmvfzw==} + '@smithy/node-http-handler@4.6.1': + resolution: {integrity: sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.2.12': - resolution: {integrity: sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A==} + '@smithy/property-provider@4.2.14': + resolution: {integrity: sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==} engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.3.12': - resolution: {integrity: sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw==} + '@smithy/protocol-http@5.3.14': + resolution: {integrity: sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==} engines: {node: '>=18.0.0'} - '@smithy/querystring-builder@4.2.12': - resolution: {integrity: sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg==} + '@smithy/querystring-builder@4.2.14': + resolution: {integrity: sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.2.12': - resolution: {integrity: sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw==} + '@smithy/querystring-parser@4.2.14': + resolution: {integrity: sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.2.12': - resolution: {integrity: sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ==} + '@smithy/service-error-classification@4.3.0': + resolution: {integrity: sha512-9jKsBYQRPR0xBLgc2415RsA5PIcP2sis4oBdN9s0D13cg1B1284mNTjx9Yc+BEERXzuPm5ObktI96OxsKh8E9A==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.4.7': - resolution: {integrity: sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw==} + '@smithy/shared-ini-file-loader@4.4.9': + resolution: {integrity: sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.3.12': - resolution: {integrity: sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw==} + '@smithy/signature-v4@5.3.14': + resolution: {integrity: sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.12.8': - resolution: {integrity: sha512-aJaAX7vHe5i66smoSSID7t4rKY08PbD8EBU7DOloixvhOozfYWdcSYE4l6/tjkZ0vBZhGjheWzB2mh31sLgCMA==} + '@smithy/smithy-client@4.12.13': + resolution: {integrity: sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==} engines: {node: '>=18.0.0'} - '@smithy/types@4.13.1': - resolution: {integrity: sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==} + '@smithy/types@4.14.1': + resolution: {integrity: sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.2.12': - resolution: {integrity: sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA==} + '@smithy/url-parser@4.2.14': + resolution: {integrity: sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==} engines: {node: '>=18.0.0'} '@smithy/util-base64@4.3.2': @@ -4422,32 +4422,32 @@ packages: resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.44': - resolution: {integrity: sha512-eZg6XzaCbVr2S5cAErU5eGBDaOVTuTo1I65i4tQcHENRcZ8rMWhQy1DaIYUSLyZjsfXvmCqZrstSMYyGFocvHA==} + '@smithy/util-defaults-mode-browser@4.3.49': + resolution: {integrity: sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.48': - resolution: {integrity: sha512-FqOKTlqSaoV3nzO55pMs5NBnZX8EhoI0DGmn9kbYeXWppgHD6dchyuj2HLqp4INJDJbSrj6OFYJkAh/WhSzZPg==} + '@smithy/util-defaults-mode-node@4.2.54': + resolution: {integrity: sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.3.3': - resolution: {integrity: sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig==} + '@smithy/util-endpoints@3.4.2': + resolution: {integrity: sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg==} engines: {node: '>=18.0.0'} '@smithy/util-hex-encoding@4.2.2': resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} engines: {node: '>=18.0.0'} - '@smithy/util-middleware@4.2.12': - resolution: {integrity: sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ==} + '@smithy/util-middleware@4.2.14': + resolution: {integrity: sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.2.13': - resolution: {integrity: sha512-qQQsIvL0MGIbUjeSrg0/VlQ3jGNKyM3/2iU3FPNgy01z+Sp4OvcaxbgIoFOTvB61ZoohtutuOvOcgmhbD0katQ==} + '@smithy/util-retry@4.3.4': + resolution: {integrity: sha512-FY1UQQ1VFmMwiYp1GVS4MeaGD5O0blLNYK0xCRHU+mJgeoH/hSY8Ld8sJWKQ6uznkh14HveRGQJncgPyNl9J+A==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.5.21': - resolution: {integrity: sha512-KzSg+7KKywLnkoKejRtIBXDmwBfjGvg1U1i/etkC7XSWUyFCoLno1IohV2c74IzQqdhX5y3uE44r/8/wuK+A7Q==} + '@smithy/util-stream@4.5.25': + resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@4.2.2': @@ -4462,8 +4462,8 @@ packages: resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.2.14': - resolution: {integrity: sha512-2zqq5o/oizvMaFUlNiTyZ7dbgYv1a893aGut2uaxtbzTx/VYYnRxWzDHuD/ftgcw94ffenua+ZNLrbqwUYE+Bg==} + '@smithy/util-waiter@4.2.16': + resolution: {integrity: sha512-GtclrKoZ3Lt7jPQ7aTIYKfjY92OgceScftVnkTsG8e1KV8rkvZgN+ny6YSRhd9hxB8rZtwVbmln7NTvE5O3GmQ==} engines: {node: '>=18.0.0'} '@smithy/uuid@1.1.2': @@ -5439,8 +5439,8 @@ packages: resolution: {integrity: sha512-CJDxIgE5I0FH+ttq/Fxy6nRpxP70+e2O048EPe85J2use3XKdatVM7dDVvFNjQudd9B49NPoZ+8PG49zj4Er8Q==} engines: {node: '>= 16'} - '@xmldom/xmldom@0.8.12': - resolution: {integrity: sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==} + '@xmldom/xmldom@0.8.13': + resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} engines: {node: '>=10.0.0'} '@xtuc/ieee754@1.2.0': @@ -6168,8 +6168,8 @@ packages: engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} hasBin: true - cross-fetch@4.0.0: - resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} @@ -6916,11 +6916,11 @@ packages: fast-uri@3.0.6: resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} - fast-xml-builder@1.1.4: - resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==} + fast-xml-builder@1.1.5: + resolution: {integrity: sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==} - fast-xml-parser@5.5.8: - resolution: {integrity: sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==} + fast-xml-parser@5.7.1: + resolution: {integrity: sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==} hasBin: true fastify-ip@2.0.0: @@ -7288,8 +7288,8 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - i18next-http-backend@3.0.2: - resolution: {integrity: sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==} + i18next-http-backend@3.0.6: + resolution: {integrity: sha512-mBOqy8993jtqAoj6XaI1XeC/8/9v6EPS+681ziegrPvTB0DoaCY7PpTS0SpY56qLMoS4OI1TZEM2Zf59zNh05w==} i18next@25.10.1: resolution: {integrity: sha512-d7MZx1UDamSmjbaqFg00w+EXUTqIB8x8cmYRGsAzQqXFVyrNFprGqPItANtlF6V1tuBFyZyp+4/q2MFqODWerg==} @@ -8803,8 +8803,8 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-expression-matcher@1.2.0: - resolution: {integrity: sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==} + path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} engines: {node: '>=14.0.0'} path-is-absolute@1.0.1: @@ -9036,8 +9036,8 @@ packages: resolution: {integrity: sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==} engines: {node: '>=12'} - posthog-js@1.370.0: - resolution: {integrity: sha512-0PQCUO6EGbXaOPgXYrcafrXa9B13nDaGc91xCiuwNPK80oovqTmeHfNUNCv1r+xCpEoxw3L1FyBuuLCt5Zz7rg==} + posthog-js@1.372.2: + resolution: {integrity: sha512-FS+vKDXB1vghrVch3EDi3IRcoH5OnLQYxchHWi+8U4D4PzWQZnZLo5vyMRL1+ZUHNEZ2v599uX3UKhRZv2z6Cg==} postmark@4.0.7: resolution: {integrity: sha512-DjNniUl1XNCGUKhCR98ePd5gv16rlUAVKKaU9TUqnE3hDSqfT9XDulu1idjagQmdyGscqnRtXk/puAEiYMeevg==} @@ -9140,8 +9140,8 @@ packages: prosemirror-view@1.40.0: resolution: {integrity: sha512-2G3svX0Cr1sJjkD/DYWSe3cfV5VPVTBOxI9XQEGWJDFEpsZb/gh4MV29ctv+OJx2RFX4BLt09i+6zaGM/ldkCw==} - protobufjs@7.5.4: - resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} + protobufjs@7.5.5: + resolution: {integrity: sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==} engines: {node: '>=12.0.0'} proxy-addr@2.0.7: @@ -9846,8 +9846,8 @@ packages: resolution: {integrity: sha512-aT2BU9KkizY9SATf14WhhYVv2uOapBWX0OFWF4xvcj1mPaNotlSc2CsxpS4DS46ZueSppmCF5BX1sNYBtwBvfw==} engines: {node: '>=12.*'} - strnum@2.2.1: - resolution: {integrity: sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==} + strnum@2.2.3: + resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} strtok3@10.3.4: resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} @@ -10320,8 +10320,8 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true - uuid@13.0.0: - resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + uuid@14.0.0: + resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true v8-compile-cache-lib@3.0.1: @@ -10829,20 +10829,20 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 tslib: 2.8.1 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 tslib: 2.8.1 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 '@aws-sdk/util-locate-window': 3.535.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -10852,7 +10852,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 '@aws-sdk/util-locate-window': 3.535.0 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -10860,7 +10860,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -10869,432 +10869,435 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.1014.0': + '@aws-sdk/client-s3@3.1037.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.26 - '@aws-sdk/credential-provider-node': 3.972.29 - '@aws-sdk/middleware-bucket-endpoint': 3.972.8 - '@aws-sdk/middleware-expect-continue': 3.972.8 - '@aws-sdk/middleware-flexible-checksums': 3.974.6 - '@aws-sdk/middleware-host-header': 3.972.8 - '@aws-sdk/middleware-location-constraint': 3.972.8 - '@aws-sdk/middleware-logger': 3.972.8 - '@aws-sdk/middleware-recursion-detection': 3.972.9 - '@aws-sdk/middleware-sdk-s3': 3.972.27 - '@aws-sdk/middleware-ssec': 3.972.8 - '@aws-sdk/middleware-user-agent': 3.972.28 - '@aws-sdk/region-config-resolver': 3.972.10 - '@aws-sdk/signature-v4-multi-region': 3.996.15 - '@aws-sdk/types': 3.973.6 - '@aws-sdk/util-endpoints': 3.996.5 - '@aws-sdk/util-user-agent-browser': 3.972.8 - '@aws-sdk/util-user-agent-node': 3.973.14 - '@smithy/config-resolver': 4.4.13 - '@smithy/core': 3.23.13 - '@smithy/eventstream-serde-browser': 4.2.12 - '@smithy/eventstream-serde-config-resolver': 4.3.12 - '@smithy/eventstream-serde-node': 4.2.12 - '@smithy/fetch-http-handler': 5.3.15 - '@smithy/hash-blob-browser': 4.2.13 - '@smithy/hash-node': 4.2.12 - '@smithy/hash-stream-node': 4.2.12 - '@smithy/invalid-dependency': 4.2.12 - '@smithy/md5-js': 4.2.12 - '@smithy/middleware-content-length': 4.2.12 - '@smithy/middleware-endpoint': 4.4.28 - '@smithy/middleware-retry': 4.4.46 - '@smithy/middleware-serde': 4.2.16 - '@smithy/middleware-stack': 4.2.12 - '@smithy/node-config-provider': 4.3.12 - '@smithy/node-http-handler': 4.5.1 - '@smithy/protocol-http': 5.3.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 - '@smithy/url-parser': 4.2.12 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/credential-provider-node': 3.972.36 + '@aws-sdk/middleware-bucket-endpoint': 3.972.10 + '@aws-sdk/middleware-expect-continue': 3.972.10 + '@aws-sdk/middleware-flexible-checksums': 3.974.13 + '@aws-sdk/middleware-host-header': 3.972.10 + '@aws-sdk/middleware-location-constraint': 3.972.10 + '@aws-sdk/middleware-logger': 3.972.10 + '@aws-sdk/middleware-recursion-detection': 3.972.11 + '@aws-sdk/middleware-sdk-s3': 3.972.34 + '@aws-sdk/middleware-ssec': 3.972.10 + '@aws-sdk/middleware-user-agent': 3.972.35 + '@aws-sdk/region-config-resolver': 3.972.13 + '@aws-sdk/signature-v4-multi-region': 3.996.22 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/util-endpoints': 3.996.8 + '@aws-sdk/util-user-agent-browser': 3.972.10 + '@aws-sdk/util-user-agent-node': 3.973.21 + '@smithy/config-resolver': 4.4.17 + '@smithy/core': 3.23.17 + '@smithy/eventstream-serde-browser': 4.2.14 + '@smithy/eventstream-serde-config-resolver': 4.3.14 + '@smithy/eventstream-serde-node': 4.2.14 + '@smithy/fetch-http-handler': 5.3.17 + '@smithy/hash-blob-browser': 4.2.15 + '@smithy/hash-node': 4.2.14 + '@smithy/hash-stream-node': 4.2.14 + '@smithy/invalid-dependency': 4.2.14 + '@smithy/md5-js': 4.2.14 + '@smithy/middleware-content-length': 4.2.14 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.5 + '@smithy/middleware-serde': 4.2.20 + '@smithy/middleware-stack': 4.2.14 + '@smithy/node-config-provider': 4.3.14 + '@smithy/node-http-handler': 4.6.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.44 - '@smithy/util-defaults-mode-node': 4.2.48 - '@smithy/util-endpoints': 3.3.3 - '@smithy/util-middleware': 4.2.12 - '@smithy/util-retry': 4.2.13 - '@smithy/util-stream': 4.5.21 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 + '@smithy/util-endpoints': 3.4.2 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.4 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 - '@smithy/util-waiter': 4.2.14 + '@smithy/util-waiter': 4.2.16 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.973.26': + '@aws-sdk/core@3.974.5': dependencies: - '@aws-sdk/types': 3.973.6 - '@aws-sdk/xml-builder': 3.972.16 - '@smithy/core': 3.23.13 - '@smithy/node-config-provider': 4.3.12 - '@smithy/property-provider': 4.2.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/signature-v4': 5.3.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/xml-builder': 3.972.19 + '@smithy/core': 3.23.17 + '@smithy/node-config-provider': 4.3.14 + '@smithy/property-provider': 4.2.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/signature-v4': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 - '@smithy/util-middleware': 4.2.12 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.4 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/crc64-nvme@3.972.5': + '@aws-sdk/crc64-nvme@3.972.7': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.24': + '@aws-sdk/credential-provider-env@3.972.31': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/types': 3.973.6 - '@smithy/property-provider': 4.2.12 - '@smithy/types': 4.13.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/types': 3.973.8 + '@smithy/property-provider': 4.2.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.26': + '@aws-sdk/credential-provider-http@3.972.33': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/types': 3.973.6 - '@smithy/fetch-http-handler': 5.3.15 - '@smithy/node-http-handler': 4.5.1 - '@smithy/property-provider': 4.2.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 - '@smithy/util-stream': 4.5.21 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/types': 3.973.8 + '@smithy/fetch-http-handler': 5.3.17 + '@smithy/node-http-handler': 4.6.1 + '@smithy/property-provider': 4.2.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + '@smithy/util-stream': 4.5.25 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.28': + '@aws-sdk/credential-provider-ini@3.972.35': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/credential-provider-env': 3.972.24 - '@aws-sdk/credential-provider-http': 3.972.26 - '@aws-sdk/credential-provider-login': 3.972.28 - '@aws-sdk/credential-provider-process': 3.972.24 - '@aws-sdk/credential-provider-sso': 3.972.28 - '@aws-sdk/credential-provider-web-identity': 3.972.28 - '@aws-sdk/nested-clients': 3.996.18 - '@aws-sdk/types': 3.973.6 - '@smithy/credential-provider-imds': 4.2.12 - '@smithy/property-provider': 4.2.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/credential-provider-env': 3.972.31 + '@aws-sdk/credential-provider-http': 3.972.33 + '@aws-sdk/credential-provider-login': 3.972.35 + '@aws-sdk/credential-provider-process': 3.972.31 + '@aws-sdk/credential-provider-sso': 3.972.35 + '@aws-sdk/credential-provider-web-identity': 3.972.35 + '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/types': 3.973.8 + '@smithy/credential-provider-imds': 4.2.14 + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.28': + '@aws-sdk/credential-provider-login@3.972.35': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/nested-clients': 3.996.18 - '@aws-sdk/types': 3.973.6 - '@smithy/property-provider': 4.2.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/types': 3.973.8 + '@smithy/property-provider': 4.2.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.29': + '@aws-sdk/credential-provider-node@3.972.36': dependencies: - '@aws-sdk/credential-provider-env': 3.972.24 - '@aws-sdk/credential-provider-http': 3.972.26 - '@aws-sdk/credential-provider-ini': 3.972.28 - '@aws-sdk/credential-provider-process': 3.972.24 - '@aws-sdk/credential-provider-sso': 3.972.28 - '@aws-sdk/credential-provider-web-identity': 3.972.28 - '@aws-sdk/types': 3.973.6 - '@smithy/credential-provider-imds': 4.2.12 - '@smithy/property-provider': 4.2.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@aws-sdk/credential-provider-env': 3.972.31 + '@aws-sdk/credential-provider-http': 3.972.33 + '@aws-sdk/credential-provider-ini': 3.972.35 + '@aws-sdk/credential-provider-process': 3.972.31 + '@aws-sdk/credential-provider-sso': 3.972.35 + '@aws-sdk/credential-provider-web-identity': 3.972.35 + '@aws-sdk/types': 3.973.8 + '@smithy/credential-provider-imds': 4.2.14 + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.24': + '@aws-sdk/credential-provider-process@3.972.31': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/types': 3.973.6 - '@smithy/property-provider': 4.2.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/types': 3.973.8 + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.28': + '@aws-sdk/credential-provider-sso@3.972.35': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/nested-clients': 3.996.18 - '@aws-sdk/token-providers': 3.1021.0 - '@aws-sdk/types': 3.973.6 - '@smithy/property-provider': 4.2.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/token-providers': 3.1036.0 + '@aws-sdk/types': 3.973.8 + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.28': + '@aws-sdk/credential-provider-web-identity@3.972.35': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/nested-clients': 3.996.18 - '@aws-sdk/types': 3.973.6 - '@smithy/property-provider': 4.2.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/types': 3.973.8 + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/lib-storage@3.1014.0(@aws-sdk/client-s3@3.1014.0)': + '@aws-sdk/lib-storage@3.1037.0(@aws-sdk/client-s3@3.1037.0)': dependencies: - '@aws-sdk/client-s3': 3.1014.0 - '@smithy/abort-controller': 4.2.12 - '@smithy/middleware-endpoint': 4.4.28 - '@smithy/smithy-client': 4.12.8 + '@aws-sdk/client-s3': 3.1037.0 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/protocol-http': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: 2.8.1 - '@aws-sdk/middleware-bucket-endpoint@3.972.8': + '@aws-sdk/middleware-bucket-endpoint@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/node-config-provider': 4.3.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 + '@smithy/node-config-provider': 4.3.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-expect-continue@3.972.8': + '@aws-sdk/middleware-expect-continue@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.974.6': + '@aws-sdk/middleware-flexible-checksums@3.974.13': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.973.26 - '@aws-sdk/crc64-nvme': 3.972.5 - '@aws-sdk/types': 3.973.6 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/crc64-nvme': 3.972.7 + '@aws-sdk/types': 3.973.8 '@smithy/is-array-buffer': 4.2.2 - '@smithy/node-config-provider': 4.3.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 - '@smithy/util-middleware': 4.2.12 - '@smithy/util-stream': 4.5.21 + '@smithy/node-config-provider': 4.3.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.972.8': + '@aws-sdk/middleware-host-header@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-location-constraint@3.972.8': + '@aws-sdk/middleware-location-constraint@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.972.8': + '@aws-sdk/middleware-logger@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.972.9': + '@aws-sdk/middleware-recursion-detection@3.972.11': dependencies: - '@aws-sdk/types': 3.973.6 + '@aws-sdk/types': 3.973.8 '@aws/lambda-invoke-store': 0.2.3 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.27': + '@aws-sdk/middleware-sdk-s3@3.972.34': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/types': 3.973.6 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/types': 3.973.8 '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/core': 3.23.13 - '@smithy/node-config-provider': 4.3.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/signature-v4': 5.3.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 + '@smithy/core': 3.23.17 + '@smithy/node-config-provider': 4.3.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/signature-v4': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 - '@smithy/util-middleware': 4.2.12 - '@smithy/util-stream': 4.5.21 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-ssec@3.972.8': + '@aws-sdk/middleware-ssec@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.28': + '@aws-sdk/middleware-user-agent@3.972.35': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/types': 3.973.6 - '@aws-sdk/util-endpoints': 3.996.5 - '@smithy/core': 3.23.13 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 - '@smithy/util-retry': 4.2.13 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/util-endpoints': 3.996.8 + '@smithy/core': 3.23.17 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-retry': 4.3.4 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.996.18': + '@aws-sdk/nested-clients@3.997.3': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.26 - '@aws-sdk/middleware-host-header': 3.972.8 - '@aws-sdk/middleware-logger': 3.972.8 - '@aws-sdk/middleware-recursion-detection': 3.972.9 - '@aws-sdk/middleware-user-agent': 3.972.28 - '@aws-sdk/region-config-resolver': 3.972.10 - '@aws-sdk/types': 3.973.6 - '@aws-sdk/util-endpoints': 3.996.5 - '@aws-sdk/util-user-agent-browser': 3.972.8 - '@aws-sdk/util-user-agent-node': 3.973.14 - '@smithy/config-resolver': 4.4.13 - '@smithy/core': 3.23.13 - '@smithy/fetch-http-handler': 5.3.15 - '@smithy/hash-node': 4.2.12 - '@smithy/invalid-dependency': 4.2.12 - '@smithy/middleware-content-length': 4.2.12 - '@smithy/middleware-endpoint': 4.4.28 - '@smithy/middleware-retry': 4.4.46 - '@smithy/middleware-serde': 4.2.16 - '@smithy/middleware-stack': 4.2.12 - '@smithy/node-config-provider': 4.3.12 - '@smithy/node-http-handler': 4.5.1 - '@smithy/protocol-http': 5.3.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 - '@smithy/url-parser': 4.2.12 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/middleware-host-header': 3.972.10 + '@aws-sdk/middleware-logger': 3.972.10 + '@aws-sdk/middleware-recursion-detection': 3.972.11 + '@aws-sdk/middleware-user-agent': 3.972.35 + '@aws-sdk/region-config-resolver': 3.972.13 + '@aws-sdk/signature-v4-multi-region': 3.996.22 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/util-endpoints': 3.996.8 + '@aws-sdk/util-user-agent-browser': 3.972.10 + '@aws-sdk/util-user-agent-node': 3.973.21 + '@smithy/config-resolver': 4.4.17 + '@smithy/core': 3.23.17 + '@smithy/fetch-http-handler': 5.3.17 + '@smithy/hash-node': 4.2.14 + '@smithy/invalid-dependency': 4.2.14 + '@smithy/middleware-content-length': 4.2.14 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.5 + '@smithy/middleware-serde': 4.2.20 + '@smithy/middleware-stack': 4.2.14 + '@smithy/node-config-provider': 4.3.14 + '@smithy/node-http-handler': 4.6.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.44 - '@smithy/util-defaults-mode-node': 4.2.48 - '@smithy/util-endpoints': 3.3.3 - '@smithy/util-middleware': 4.2.12 - '@smithy/util-retry': 4.2.13 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 + '@smithy/util-endpoints': 3.4.2 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.4 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.972.10': + '@aws-sdk/region-config-resolver@3.972.13': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/config-resolver': 4.4.13 - '@smithy/node-config-provider': 4.3.12 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/config-resolver': 4.4.17 + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/s3-request-presigner@3.1014.0': + '@aws-sdk/s3-request-presigner@3.1037.0': dependencies: - '@aws-sdk/signature-v4-multi-region': 3.996.15 - '@aws-sdk/types': 3.973.6 - '@aws-sdk/util-format-url': 3.972.8 - '@smithy/middleware-endpoint': 4.4.28 - '@smithy/protocol-http': 5.3.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 + '@aws-sdk/signature-v4-multi-region': 3.996.22 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/util-format-url': 3.972.10 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/protocol-http': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.15': + '@aws-sdk/signature-v4-multi-region@3.996.22': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.27 - '@aws-sdk/types': 3.973.6 - '@smithy/protocol-http': 5.3.12 - '@smithy/signature-v4': 5.3.12 - '@smithy/types': 4.13.1 + '@aws-sdk/middleware-sdk-s3': 3.972.34 + '@aws-sdk/types': 3.973.8 + '@smithy/protocol-http': 5.3.14 + '@smithy/signature-v4': 5.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1021.0': + '@aws-sdk/token-providers@3.1036.0': dependencies: - '@aws-sdk/core': 3.973.26 - '@aws-sdk/nested-clients': 3.996.18 - '@aws-sdk/types': 3.973.6 - '@smithy/property-provider': 4.2.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@aws-sdk/core': 3.974.5 + '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/types': 3.973.8 + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.973.6': + '@aws-sdk/types@3.973.8': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 '@aws-sdk/util-arn-parser@3.972.3': dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.996.5': + '@aws-sdk/util-endpoints@3.996.8': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/types': 4.13.1 - '@smithy/url-parser': 4.2.12 - '@smithy/util-endpoints': 3.3.3 + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 + '@smithy/util-endpoints': 3.4.2 tslib: 2.8.1 - '@aws-sdk/util-format-url@3.972.8': + '@aws-sdk/util-format-url@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/querystring-builder': 4.2.12 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/querystring-builder': 4.2.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 '@aws-sdk/util-locate-window@3.535.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.972.8': + '@aws-sdk/util-user-agent-browser@3.972.10': dependencies: - '@aws-sdk/types': 3.973.6 - '@smithy/types': 4.13.1 + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.14': + '@aws-sdk/util-user-agent-node@3.973.21': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.28 - '@aws-sdk/types': 3.973.6 - '@smithy/node-config-provider': 4.3.12 - '@smithy/types': 4.13.1 + '@aws-sdk/middleware-user-agent': 3.972.35 + '@aws-sdk/types': 3.973.8 + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.16': + '@aws-sdk/xml-builder@3.972.19': dependencies: - '@smithy/types': 4.13.1 - fast-xml-parser: 5.5.8 + '@smithy/types': 4.14.1 + fast-xml-parser: 5.7.1 tslib: 2.8.1 '@aws/lambda-invoke-store@0.2.3': {} @@ -13455,6 +13458,8 @@ snapshots: '@noble/hashes@2.0.1': {} + '@nodable/entities@2.1.0': {} + '@node-saml/node-saml@5.1.0': dependencies: '@types/debug': 4.1.12 @@ -13462,7 +13467,7 @@ snapshots: '@types/xml-encryption': 1.2.4 '@types/xml2js': 0.4.14 '@xmldom/is-dom-node': 1.0.1 - '@xmldom/xmldom': 0.8.12 + '@xmldom/xmldom': 0.8.13 debug: 4.4.0 xml-crypto: 6.1.2 xml-encryption: 3.1.0 @@ -13620,7 +13625,7 @@ snapshots: '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - protobufjs: 7.5.4 + protobufjs: 7.5.5 '@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0)': dependencies: @@ -13666,9 +13671,11 @@ snapshots: '@pkgr/core@0.2.9': {} - '@posthog/core@1.26.0': {} + '@posthog/core@1.27.6': + dependencies: + '@posthog/types': 1.372.2 - '@posthog/types@1.370.0': {} + '@posthog/types@1.372.2': {} '@protobufjs/aspromise@1.1.2': {} @@ -14649,11 +14656,6 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@smithy/abort-controller@4.2.12': - dependencies: - '@smithy/types': 4.13.1 - tslib: 2.8.1 - '@smithy/chunked-blob-reader-native@4.2.3': dependencies: '@smithy/util-base64': 4.3.2 @@ -14663,97 +14665,97 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/config-resolver@4.4.13': + '@smithy/config-resolver@4.4.17': dependencies: - '@smithy/node-config-provider': 4.3.12 - '@smithy/types': 4.13.1 + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 - '@smithy/util-endpoints': 3.3.3 - '@smithy/util-middleware': 4.2.12 + '@smithy/util-endpoints': 3.4.2 + '@smithy/util-middleware': 4.2.14 tslib: 2.8.1 - '@smithy/core@3.23.13': + '@smithy/core@3.23.17': dependencies: - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 - '@smithy/url-parser': 4.2.12 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 '@smithy/util-base64': 4.3.2 '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-middleware': 4.2.12 - '@smithy/util-stream': 4.5.21 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 '@smithy/uuid': 1.1.2 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.2.12': + '@smithy/credential-provider-imds@4.2.14': dependencies: - '@smithy/node-config-provider': 4.3.12 - '@smithy/property-provider': 4.2.12 - '@smithy/types': 4.13.1 - '@smithy/url-parser': 4.2.12 + '@smithy/node-config-provider': 4.3.14 + '@smithy/property-provider': 4.2.14 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 tslib: 2.8.1 - '@smithy/eventstream-codec@4.2.12': + '@smithy/eventstream-codec@4.2.14': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 '@smithy/util-hex-encoding': 4.2.2 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.2.12': + '@smithy/eventstream-serde-browser@4.2.14': dependencies: - '@smithy/eventstream-serde-universal': 4.2.12 - '@smithy/types': 4.13.1 + '@smithy/eventstream-serde-universal': 4.2.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.3.12': + '@smithy/eventstream-serde-config-resolver@4.3.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.2.12': + '@smithy/eventstream-serde-node@4.2.14': dependencies: - '@smithy/eventstream-serde-universal': 4.2.12 - '@smithy/types': 4.13.1 + '@smithy/eventstream-serde-universal': 4.2.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.2.12': + '@smithy/eventstream-serde-universal@4.2.14': dependencies: - '@smithy/eventstream-codec': 4.2.12 - '@smithy/types': 4.13.1 + '@smithy/eventstream-codec': 4.2.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.3.15': + '@smithy/fetch-http-handler@5.3.17': dependencies: - '@smithy/protocol-http': 5.3.12 - '@smithy/querystring-builder': 4.2.12 - '@smithy/types': 4.13.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/querystring-builder': 4.2.14 + '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 tslib: 2.8.1 - '@smithy/hash-blob-browser@4.2.13': + '@smithy/hash-blob-browser@4.2.15': dependencies: '@smithy/chunked-blob-reader': 5.2.2 '@smithy/chunked-blob-reader-native': 4.2.3 - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/hash-node@4.2.12': + '@smithy/hash-node@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 '@smithy/util-buffer-from': 4.2.2 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/hash-stream-node@4.2.12': + '@smithy/hash-stream-node@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/invalid-dependency@4.2.12': + '@smithy/invalid-dependency@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': @@ -14764,126 +14766,127 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/md5-js@4.2.12': + '@smithy/md5-js@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/middleware-content-length@4.2.12': + '@smithy/middleware-content-length@4.2.14': dependencies: - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.28': + '@smithy/middleware-endpoint@4.4.32': dependencies: - '@smithy/core': 3.23.13 - '@smithy/middleware-serde': 4.2.16 - '@smithy/node-config-provider': 4.3.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 - '@smithy/url-parser': 4.2.12 - '@smithy/util-middleware': 4.2.12 + '@smithy/core': 3.23.17 + '@smithy/middleware-serde': 4.2.20 + '@smithy/node-config-provider': 4.3.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 + '@smithy/util-middleware': 4.2.14 tslib: 2.8.1 - '@smithy/middleware-retry@4.4.46': + '@smithy/middleware-retry@4.5.5': dependencies: - '@smithy/node-config-provider': 4.3.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/service-error-classification': 4.2.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 - '@smithy/util-middleware': 4.2.12 - '@smithy/util-retry': 4.2.13 + '@smithy/core': 3.23.17 + '@smithy/node-config-provider': 4.3.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/service-error-classification': 4.3.0 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.4 '@smithy/uuid': 1.1.2 tslib: 2.8.1 - '@smithy/middleware-serde@4.2.16': + '@smithy/middleware-serde@4.2.20': dependencies: - '@smithy/core': 3.23.13 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 + '@smithy/core': 3.23.17 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/middleware-stack@4.2.12': + '@smithy/middleware-stack@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/node-config-provider@4.3.12': + '@smithy/node-config-provider@4.3.14': dependencies: - '@smithy/property-provider': 4.2.12 - '@smithy/shared-ini-file-loader': 4.4.7 - '@smithy/types': 4.13.1 + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/node-http-handler@4.5.1': + '@smithy/node-http-handler@4.6.1': dependencies: - '@smithy/protocol-http': 5.3.12 - '@smithy/querystring-builder': 4.2.12 - '@smithy/types': 4.13.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/querystring-builder': 4.2.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/property-provider@4.2.12': + '@smithy/property-provider@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/protocol-http@5.3.12': + '@smithy/protocol-http@5.3.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/querystring-builder@4.2.12': + '@smithy/querystring-builder@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 '@smithy/util-uri-escape': 4.2.2 tslib: 2.8.1 - '@smithy/querystring-parser@4.2.12': + '@smithy/querystring-parser@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/service-error-classification@4.2.12': + '@smithy/service-error-classification@4.3.0': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 - '@smithy/shared-ini-file-loader@4.4.7': + '@smithy/shared-ini-file-loader@4.4.9': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/signature-v4@5.3.12': + '@smithy/signature-v4@5.3.14': dependencies: '@smithy/is-array-buffer': 4.2.2 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 '@smithy/util-hex-encoding': 4.2.2 - '@smithy/util-middleware': 4.2.12 + '@smithy/util-middleware': 4.2.14 '@smithy/util-uri-escape': 4.2.2 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@smithy/smithy-client@4.12.8': + '@smithy/smithy-client@4.12.13': dependencies: - '@smithy/core': 3.23.13 - '@smithy/middleware-endpoint': 4.4.28 - '@smithy/middleware-stack': 4.2.12 - '@smithy/protocol-http': 5.3.12 - '@smithy/types': 4.13.1 - '@smithy/util-stream': 4.5.21 + '@smithy/core': 3.23.17 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-stack': 4.2.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-stream': 4.5.25 tslib: 2.8.1 - '@smithy/types@4.13.1': + '@smithy/types@4.14.1': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.2.12': + '@smithy/url-parser@4.2.14': dependencies: - '@smithy/querystring-parser': 4.2.12 - '@smithy/types': 4.13.1 + '@smithy/querystring-parser': 4.2.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 '@smithy/util-base64@4.3.2': @@ -14914,49 +14917,49 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.44': + '@smithy/util-defaults-mode-browser@4.3.49': dependencies: - '@smithy/property-provider': 4.2.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 + '@smithy/property-provider': 4.2.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.48': + '@smithy/util-defaults-mode-node@4.2.54': dependencies: - '@smithy/config-resolver': 4.4.13 - '@smithy/credential-provider-imds': 4.2.12 - '@smithy/node-config-provider': 4.3.12 - '@smithy/property-provider': 4.2.12 - '@smithy/smithy-client': 4.12.8 - '@smithy/types': 4.13.1 + '@smithy/config-resolver': 4.4.17 + '@smithy/credential-provider-imds': 4.2.14 + '@smithy/node-config-provider': 4.3.14 + '@smithy/property-provider': 4.2.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-endpoints@3.3.3': + '@smithy/util-endpoints@3.4.2': dependencies: - '@smithy/node-config-provider': 4.3.12 - '@smithy/types': 4.13.1 + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 tslib: 2.8.1 '@smithy/util-hex-encoding@4.2.2': dependencies: tslib: 2.8.1 - '@smithy/util-middleware@4.2.12': + '@smithy/util-middleware@4.2.14': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-retry@4.2.13': + '@smithy/util-retry@4.3.4': dependencies: - '@smithy/service-error-classification': 4.2.12 - '@smithy/types': 4.13.1 + '@smithy/service-error-classification': 4.3.0 + '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-stream@4.5.21': + '@smithy/util-stream@4.5.25': dependencies: - '@smithy/fetch-http-handler': 5.3.15 - '@smithy/node-http-handler': 4.5.1 - '@smithy/types': 4.13.1 + '@smithy/fetch-http-handler': 5.3.17 + '@smithy/node-http-handler': 4.6.1 + '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 '@smithy/util-buffer-from': 4.2.2 '@smithy/util-hex-encoding': 4.2.2 @@ -14977,9 +14980,9 @@ snapshots: '@smithy/util-buffer-from': 4.2.2 tslib: 2.8.1 - '@smithy/util-waiter@4.2.14': + '@smithy/util-waiter@4.2.16': dependencies: - '@smithy/types': 4.13.1 + '@smithy/types': 4.14.1 tslib: 2.8.1 '@smithy/uuid@1.1.2': @@ -16039,7 +16042,7 @@ snapshots: '@xmldom/is-dom-node@1.0.1': {} - '@xmldom/xmldom@0.8.12': {} + '@xmldom/xmldom@0.8.13': {} '@xtuc/ieee754@1.2.0': {} @@ -16853,7 +16856,7 @@ snapshots: dependencies: cross-spawn: 7.0.6 - cross-fetch@4.0.0: + cross-fetch@4.1.0: dependencies: node-fetch: 2.7.0 transitivePeerDependencies: @@ -17833,15 +17836,16 @@ snapshots: fast-uri@3.0.6: {} - fast-xml-builder@1.1.4: + fast-xml-builder@1.1.5: dependencies: - path-expression-matcher: 1.2.0 + path-expression-matcher: 1.5.0 - fast-xml-parser@5.5.8: + fast-xml-parser@5.7.1: dependencies: - fast-xml-builder: 1.1.4 - path-expression-matcher: 1.2.0 - strnum: 2.2.1 + '@nodable/entities': 2.1.0 + fast-xml-builder: 1.1.5 + path-expression-matcher: 1.5.0 + strnum: 2.2.3 fastify-ip@2.0.0: dependencies: @@ -18250,9 +18254,9 @@ snapshots: human-signals@2.1.0: {} - i18next-http-backend@3.0.2: + i18next-http-backend@3.0.6: dependencies: - cross-fetch: 4.0.0 + cross-fetch: 4.1.0 transitivePeerDependencies: - encoding @@ -19386,7 +19390,7 @@ snapshots: mammoth@1.12.0: dependencies: - '@xmldom/xmldom': 0.8.12 + '@xmldom/xmldom': 0.8.13 argparse: 1.0.10 base64-js: 1.5.1 bluebird: 3.4.7 @@ -19942,7 +19946,7 @@ snapshots: path-exists@4.0.0: {} - path-expression-matcher@1.2.0: {} + path-expression-matcher@1.5.0: {} path-is-absolute@1.0.1: {} @@ -20187,15 +20191,15 @@ snapshots: postgres@3.4.8: {} - posthog-js@1.370.0: + posthog-js@1.372.2: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.208.0 '@opentelemetry/exporter-logs-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.5.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) - '@posthog/core': 1.26.0 - '@posthog/types': 1.370.0 + '@posthog/core': 1.27.6 + '@posthog/types': 1.372.2 core-js: 3.43.0 dompurify: 3.4.1 fflate: 0.4.8 @@ -20349,7 +20353,7 @@ snapshots: prosemirror-state: 1.4.3 prosemirror-transform: 1.10.4 - protobufjs@7.5.4: + protobufjs@7.5.5: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -21249,7 +21253,7 @@ snapshots: '@types/node': 25.5.0 qs: 6.14.2 - strnum@2.2.1: {} + strnum@2.2.3: {} strtok3@10.3.4: dependencies: @@ -21734,7 +21738,7 @@ snapshots: uuid@11.1.0: {} - uuid@13.0.0: {} + uuid@14.0.0: {} v8-compile-cache-lib@3.0.1: {} @@ -21981,12 +21985,12 @@ snapshots: xml-crypto@6.1.2: dependencies: '@xmldom/is-dom-node': 1.0.1 - '@xmldom/xmldom': 0.8.12 + '@xmldom/xmldom': 0.8.13 xpath: 0.0.33 xml-encryption@3.1.0: dependencies: - '@xmldom/xmldom': 0.8.12 + '@xmldom/xmldom': 0.8.13 escape-html: 1.0.3 xpath: 0.0.32 From 15b8908b1ae829c197211beb5605e8983c80db0f Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:23:47 +0100 Subject: [PATCH 04/46] update postcss --- apps/client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/package.json b/apps/client/package.json index b54b86091..2ddafdcf6 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -74,7 +74,7 @@ "eslint-plugin-react-refresh": "^0.5.2", "globals": "^15.13.0", "optics-ts": "^2.4.1", - "postcss": "^8.5.8", + "postcss": "^8.5.12", "postcss-preset-mantine": "^1.18.0", "postcss-simple-vars": "^7.0.1", "prettier": "^3.8.1", From fad410ef2343b9c7e9368be977fe5eb9eda532e5 Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:50:42 +0100 Subject: [PATCH 05/46] chore: add undici for oidc proxy support (#2132) --- apps/server/package.json | 1 + pnpm-lock.yaml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/apps/server/package.json b/apps/server/package.json index 10a13b61d..f9c290ac8 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -117,6 +117,7 @@ "tmp-promise": "^3.0.3", "tseep": "^1.3.1", "typesense": "^3.0.5", + "undici": "7.24.0", "ws": "^8.20.0", "yauzl": "^3.2.1", "zod": "^4.3.6" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 73f773844..3977df72e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -719,6 +719,9 @@ importers: typesense: specifier: ^3.0.5 version: 3.0.5(@babel/runtime@7.29.2) + undici: + specifier: 7.24.0 + version: 7.24.0 ws: specifier: 8.20.0 version: 8.20.0 @@ -4005,6 +4008,7 @@ packages: '@react-email/components@1.0.10': resolution: {integrity: sha512-r/BnqfAjr3apcvn/NDx2DqNRD5BP5wZLRdjn2IVHXjt4KmQ5RHWSCAvFiXAzRHys1BWQ2zgIc7cpWePUcAl+nw==} engines: {node: '>=20.0.0'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc From fe44dc92a92806ab6468f8448fc35caa529617b5 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:51:23 +0100 Subject: [PATCH 06/46] sync --- apps/server/src/ee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/server/src/ee b/apps/server/src/ee index 36d6b68b9..4101fc427 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit 36d6b68b9307685c362ba9eaf6d1b8e39fee0762 +Subproject commit 4101fc427b785e2711c0f608c377d641a2e4be78 From 980521f95792ddd382ebbc275467a8319a351bae Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Mon, 27 Apr 2026 16:06:32 +0100 Subject: [PATCH 07/46] v0.80.1 --- apps/client/package.json | 2 +- apps/server/package.json | 2 +- package.json | 2 +- pnpm-lock.yaml | 62 ++++++++++++++++++++-------------------- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/apps/client/package.json b/apps/client/package.json index 2ddafdcf6..404df47ee 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -1,7 +1,7 @@ { "name": "client", "private": true, - "version": "0.80.0", + "version": "0.80.1", "scripts": { "dev": "vite", "build": "tsc && vite build", diff --git a/apps/server/package.json b/apps/server/package.json index f9c290ac8..7c97763b7 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,6 +1,6 @@ { "name": "server", - "version": "0.80.0", + "version": "0.80.1", "description": "", "author": "", "private": true, diff --git a/package.json b/package.json index 3e4b7373c..589721623 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "docmost", "homepage": "https://docmost.com", - "version": "0.80.0", + "version": "0.80.1", "private": true, "scripts": { "build": "nx run-many -t build", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3977df72e..4ceb29771 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -415,7 +415,7 @@ importers: version: 18.3.1 '@vitejs/plugin-react': specifier: ^6.0.1 - version: 6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) eslint: specifier: ^9.28.0 version: 9.39.4(jiti@2.4.2) @@ -435,14 +435,14 @@ importers: specifier: ^2.4.1 version: 2.4.1 postcss: - specifier: ^8.5.8 - version: 8.5.8 + specifier: ^8.5.12 + version: 8.5.12 postcss-preset-mantine: specifier: ^1.18.0 - version: 1.18.0(postcss@8.5.8) + version: 1.18.0(postcss@8.5.12) postcss-simple-vars: specifier: ^7.0.1 - version: 7.0.1(postcss@8.5.8) + version: 7.0.1(postcss@8.5.12) prettier: specifier: ^3.8.1 version: 3.8.1 @@ -454,7 +454,7 @@ importers: version: 8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) vite: specifier: 8.0.5 - version: 8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) + version: 8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) apps/server: dependencies: @@ -9016,8 +9016,8 @@ packages: peerDependencies: postcss: ^8.2.1 - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + postcss@8.5.12: + resolution: {integrity: sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -15963,10 +15963,10 @@ snapshots: '@vercel/oidc@3.1.0': {} - '@vitejs/plugin-react@6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitejs/plugin-react@6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) '@webassemblyjs/ast@1.14.1': dependencies: @@ -20140,40 +20140,40 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-js@4.0.1(postcss@8.5.8): + postcss-js@4.0.1(postcss@8.5.12): dependencies: camelcase-css: 2.0.1 - postcss: 8.5.8 + postcss: 8.5.12 - postcss-mixins@12.1.2(postcss@8.5.8): + postcss-mixins@12.1.2(postcss@8.5.12): dependencies: - postcss: 8.5.8 - postcss-js: 4.0.1(postcss@8.5.8) - postcss-simple-vars: 7.0.1(postcss@8.5.8) - sugarss: 5.0.1(postcss@8.5.8) + postcss: 8.5.12 + postcss-js: 4.0.1(postcss@8.5.12) + postcss-simple-vars: 7.0.1(postcss@8.5.12) + sugarss: 5.0.1(postcss@8.5.12) tinyglobby: 0.2.15 - postcss-nested@7.0.2(postcss@8.5.8): + postcss-nested@7.0.2(postcss@8.5.12): dependencies: - postcss: 8.5.8 + postcss: 8.5.12 postcss-selector-parser: 7.1.1 - postcss-preset-mantine@1.18.0(postcss@8.5.8): + postcss-preset-mantine@1.18.0(postcss@8.5.12): dependencies: - postcss: 8.5.8 - postcss-mixins: 12.1.2(postcss@8.5.8) - postcss-nested: 7.0.2(postcss@8.5.8) + postcss: 8.5.12 + postcss-mixins: 12.1.2(postcss@8.5.12) + postcss-nested: 7.0.2(postcss@8.5.12) postcss-selector-parser@7.1.1: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-simple-vars@7.0.1(postcss@8.5.8): + postcss-simple-vars@7.0.1(postcss@8.5.12): dependencies: - postcss: 8.5.8 + postcss: 8.5.12 - postcss@8.5.8: + postcss@8.5.12: dependencies: nanoid: 3.3.8 picocolors: 1.1.1 @@ -21271,9 +21271,9 @@ snapshots: stylis@4.3.6: {} - sugarss@5.0.1(postcss@8.5.8): + sugarss@5.0.1(postcss@8.5.12): dependencies: - postcss: 8.5.8 + postcss: 8.5.12 superagent@10.3.0: dependencies: @@ -21756,11 +21756,11 @@ snapshots: vary@1.1.2: {} - vite@8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.8))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3): + vite@8.0.5(@types/node@22.19.1)(esbuild@0.27.4)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 - postcss: 8.5.8 + postcss: 8.5.12 rolldown: 1.0.0-rc.12 tinyglobby: 0.2.15 optionalDependencies: @@ -21769,7 +21769,7 @@ snapshots: fsevents: 2.3.3 jiti: 2.4.2 less: 4.2.0 - sugarss: 5.0.1(postcss@8.5.8) + sugarss: 5.0.1(postcss@8.5.12) terser: 5.39.0 tsx: 4.21.0 yaml: 2.8.3 From 3ecf27c6b0191e7adb5789e02c2995f446291052 Mon Sep 17 00:00:00 2001 From: Olivier Lambert Date: Wed, 29 Apr 2026 10:36:38 +0200 Subject: [PATCH 08/46] fix(page-permission): make people-with-access list scroll past 4 entries (#2137) The "People with access" list in the page share modal used , which caps the container height but does not make the inner viewport scroll (no fixed height is given to the viewport). Items beyond ~4 entries were rendered correctly but clipped out of view. Switches to , which is Mantine's dedicated primitive for "grow with content up to a max, then scroll". Closes #2135 --- .../ee/page-permission/components/page-permission-list.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/client/src/ee/page-permission/components/page-permission-list.tsx b/apps/client/src/ee/page-permission/components/page-permission-list.tsx index e586b9683..111bb83ff 100644 --- a/apps/client/src/ee/page-permission/components/page-permission-list.tsx +++ b/apps/client/src/ee/page-permission/components/page-permission-list.tsx @@ -140,7 +140,7 @@ export function PagePermissionList({ )} - + {sortedMembers.map((member) => ( )} - + ); } From 24be90b95f49590cbab011b707106c2dc8573ee0 Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:01:47 +0100 Subject: [PATCH 09/46] fix: duplicate PDF uploads (#2139) --- .../editor/components/attachment/upload-attachment-action.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 9f668963f..e9408891b 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 @@ -19,7 +19,9 @@ export const uploadAttachmentAction = handleAttachmentUpload({ }, validateFn: (file, allowMedia: boolean) => { if ( - (file.type.includes("image/") || file.type.includes("video/")) && + (file.type.includes("image/") || + file.type.includes("video/") || + file.type === "application/pdf") && !allowMedia ) { return false; From b16f1e5a55cd39571bcd5a323bc7aaf8fa2ca5a1 Mon Sep 17 00:00:00 2001 From: Peter Tripp Date: Thu, 30 Apr 2026 19:36:40 -0400 Subject: [PATCH 10/46] fix: ctrl-k behavior on macOS (#2052) * Improve cmd-k / ctrl-k behavior Use cmd-k on macOS/iOS for search and keep ctrl-k everywhere else. Fixes a bug where ctrl-k on macOS, which cuts to the end of the line, was also triggering the search prompt. * comment submit: cmd-enter (mac) / ctrl-enter (win/linux) --- .../src/features/comment/components/comment-editor.tsx | 3 ++- apps/client/src/features/editor/page-editor.tsx | 6 +++--- apps/client/src/features/editor/title-editor.tsx | 5 +++-- .../src/features/search/components/search-control.tsx | 3 ++- apps/client/src/lib/utils.tsx | 9 +++++++++ 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/client/src/features/comment/components/comment-editor.tsx b/apps/client/src/features/comment/components/comment-editor.tsx index 067391f48..0fdc7395e 100644 --- a/apps/client/src/features/comment/components/comment-editor.tsx +++ b/apps/client/src/features/comment/components/comment-editor.tsx @@ -10,6 +10,7 @@ import { useTranslation } from "react-i18next"; import EmojiCommand from "@/features/editor/extensions/emoji-command"; import mentionRenderItems from "@/features/editor/components/mention/mention-suggestion"; import MentionView from "@/features/editor/components/mention/mention-view"; +import { platformModifierKey } from "@/lib"; interface CommentEditorProps { defaultContent?: any; @@ -83,7 +84,7 @@ const CommentEditor = forwardRef( } } - if ((event.ctrlKey || event.metaKey) && event.key === "Enter") { + if (platformModifierKey(event) && event.code === "Enter") { event.preventDefault(); if (onSave) onSave(); diff --git a/apps/client/src/features/editor/page-editor.tsx b/apps/client/src/features/editor/page-editor.tsx index 7cc4723ac..30ccc2e48 100644 --- a/apps/client/src/features/editor/page-editor.tsx +++ b/apps/client/src/features/editor/page-editor.tsx @@ -62,7 +62,7 @@ import { useIdle } from "@/hooks/use-idle.ts"; import { queryClient } from "@/main.tsx"; import { IPage } from "@/features/page/types/page.types.ts"; import { useParams } from "react-router-dom"; -import { extractPageSlugId } from "@/lib"; +import { extractPageSlugId, platformModifierKey } from "@/lib"; import { FIVE_MINUTES } from "@/lib/constants.ts"; import { PageEditMode } from "@/features/user/types/user.types.ts"; import { jwtDecode } from "jwt-decode"; @@ -232,11 +232,11 @@ export default function PageEditor({ scrollMargin: 80, handleDOMEvents: { keydown: (_view, event) => { - if ((event.ctrlKey || event.metaKey) && event.code === "KeyS") { + if (platformModifierKey(event) && event.code === "KeyS") { event.preventDefault(); return true; } - if ((event.ctrlKey || event.metaKey) && event.code === "KeyK") { + if (platformModifierKey(event) && event.code === "KeyK") { searchSpotlight.open(); return true; } diff --git a/apps/client/src/features/editor/title-editor.tsx b/apps/client/src/features/editor/title-editor.tsx index 15c3ff028..e61d8c042 100644 --- a/apps/client/src/features/editor/title-editor.tsx +++ b/apps/client/src/features/editor/title-editor.tsx @@ -27,6 +27,7 @@ import localEmitter from "@/lib/local-emitter.ts"; import { currentUserAtom } from "@/features/user/atoms/current-user-atom.ts"; import { PageEditMode } from "@/features/user/types/user.types.ts"; import { searchSpotlight } from "@/features/search/constants.ts"; +import { platformModifierKey } from "@/lib"; export interface TitleEditorProps { pageId: string; @@ -90,11 +91,11 @@ export function TitleEditor({ editorProps: { handleDOMEvents: { keydown: (_view, event) => { - if ((event.ctrlKey || event.metaKey) && event.code === "KeyS") { + if (platformModifierKey(event) && event.code === "KeyS") { event.preventDefault(); return true; } - if ((event.ctrlKey || event.metaKey) && event.code === "KeyK") { + if (platformModifierKey(event) && event.code === "KeyK") { searchSpotlight.open(); return true; } diff --git a/apps/client/src/features/search/components/search-control.tsx b/apps/client/src/features/search/components/search-control.tsx index a98909b7b..3a689e284 100644 --- a/apps/client/src/features/search/components/search-control.tsx +++ b/apps/client/src/features/search/components/search-control.tsx @@ -13,6 +13,7 @@ import { import classes from "./search-control.module.css"; import React from "react"; import { useTranslation } from "react-i18next"; +import { platformModifierLabel } from "@/lib"; interface SearchControlProps extends BoxProps, ElementProps<"button"> {} @@ -27,7 +28,7 @@ export function SearchControl({ className, ...others }: SearchControlProps) { {t("Search")} - Ctrl + K + {platformModifierLabel} + K diff --git a/apps/client/src/lib/utils.tsx b/apps/client/src/lib/utils.tsx index 5f640d456..fe97f7189 100644 --- a/apps/client/src/lib/utils.tsx +++ b/apps/client/src/lib/utils.tsx @@ -100,6 +100,15 @@ export const normalizeUrl = (url: string): string => { return `https://${url}`; }; +const _isApple = /mac|iphone|ipad|ipod/i.test(navigator.platform ?? ""); + +/// Cmd key on Apple devices, Ctrl key everywhere else +export function platformModifierKey(event: KeyboardEvent): boolean { + return _isApple ? event.metaKey : event.ctrlKey; +} + +export const platformModifierLabel = _isApple ? "⌘" : "Ctrl"; + export function castToBoolean(value: unknown): boolean { if (value == null) { return false; From 9943e104a55196326a6d26fcccd7f24e0adde3fc Mon Sep 17 00:00:00 2001 From: Sarthak Chaturvedi <84394327+mayhemking007@users.noreply.github.com> Date: Fri, 1 May 2026 05:07:59 +0530 Subject: [PATCH 11/46] fix(i18n): Correct German column count label rendering (#2131) --- apps/client/public/locales/de-DE/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/public/locales/de-DE/translation.json b/apps/client/public/locales/de-DE/translation.json index b6caf4d61..5c9e2d44c 100644 --- a/apps/client/public/locales/de-DE/translation.json +++ b/apps/client/public/locales/de-DE/translation.json @@ -391,7 +391,7 @@ "Write anything. Enter \"/\" for commands": "Schreiben Sie etwas. Geben Sie \"/\" für Befehle ein", "Write...": "\"Schreiben...\"", "Column count": "Spaltenanzahl", - "{{count}} Columns": "{count, plural, one {# Spalte} other {# Spalten}}", + "{{count}} Columns": "{{count}} Spalten", "Equal columns": "Gleich breite Spalten", "Left sidebar": "Linke Seitenleiste", "Right sidebar": "Rechte Seitenleiste", From 09c69d7a0f21085fbd0c89d6d298537e6378d85d Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Fri, 1 May 2026 00:49:31 +0100 Subject: [PATCH 12/46] feat: properly preserve table width (#2143) --- .../editor/extensions/markdown-clipboard.ts | 93 ++++++++++++++- .../import/services/import.service.ts | 6 +- .../import/utils/import-formatter.ts | 24 +++- .../integrations/import/utils/table-utils.ts | 107 ++++++++++++++++++ 4 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 apps/server/src/integrations/import/utils/table-utils.ts diff --git a/apps/client/src/features/editor/extensions/markdown-clipboard.ts b/apps/client/src/features/editor/extensions/markdown-clipboard.ts index 230798c50..bebb567ab 100644 --- a/apps/client/src/features/editor/extensions/markdown-clipboard.ts +++ b/apps/client/src/features/editor/extensions/markdown-clipboard.ts @@ -80,10 +80,12 @@ export const MarkdownClipboard = Extension.create({ const { from, to } = view.state.selection; const parsed = markdownToHtml(text.replace(/\n+$/, "")); + const body = elementFromString(parsed); + normalizeTableColumnWidths(body); const contentNodes = DOMParser.fromSchema( this.editor.schema, - ).parseSlice(elementFromString(parsed), { + ).parseSlice(body, { preserveWhitespace: true, }); @@ -137,3 +139,92 @@ function elementFromString(value) { return new window.DOMParser().parseFromString(wrappedValue, "text/html").body; } + +const DEFAULT_PASTE_COL_WIDTH_PX = 150; + +function parsePixelWidth(el: Element): number | null { + const attr = el.getAttribute("width"); + if (attr) { + const n = parseInt(attr, 10); + if (Number.isFinite(n) && n > 0) return n; + } + const style = el.getAttribute("style") || ""; + const m = style.match(/(?:^|;)\s*width\s*:\s*([\d.]+)\s*px/i); + if (m) { + const n = parseInt(m[1], 10); + if (Number.isFinite(n) && n > 0) return n; + } + return null; +} + +function getFirstRow(table: Element): Element | null { + const tbodyRow = table.querySelector(":scope > tbody > tr"); + if (tbodyRow) return tbodyRow; + const theadRow = table.querySelector(":scope > thead > tr"); + if (theadRow) return theadRow; + return table.querySelector(":scope > tr"); +} + +function deriveColumnWidths(table: Element): (number | null)[] | null { + const cols = table.querySelectorAll(":scope > colgroup > col"); + if (cols.length > 0) { + const widths: (number | null)[] = []; + cols.forEach((col) => widths.push(parsePixelWidth(col))); + if (widths.some((w) => w !== null)) return widths; + } + + const firstRow = getFirstRow(table); + if (!firstRow) return null; + + const widths: (number | null)[] = []; + Array.from(firstRow.children) + .filter((c) => c.tagName === "TD" || c.tagName === "TH") + .forEach((cell) => { + const colspan = parseInt(cell.getAttribute("colspan") || "1", 10) || 1; + const w = parsePixelWidth(cell); + for (let i = 0; i < colspan; i++) { + widths.push(w !== null ? Math.round(w / colspan) : null); + } + }); + if (widths.length === 0 || widths.every((w) => w === null)) return null; + return widths; +} + +// Mirror of server normalizeTableColumnWidths (see import/utils/table-utils.ts): +// markdown source has no widths, so without this every pasted table renders +// at table-layout:fixed/100% and squashes columns to fit the editor instead of +// letting .tableWrapper's overflow-x: auto scroll. +export function normalizeTableColumnWidths(root: Element): void { + root.querySelectorAll("table").forEach((table) => { + const firstRow = getFirstRow(table); + if (!firstRow) return; + + let colWidths = deriveColumnWidths(table); + if (!colWidths) { + let count = 0; + Array.from(firstRow.children) + .filter((c) => c.tagName === "TD" || c.tagName === "TH") + .forEach((cell) => { + count += parseInt(cell.getAttribute("colspan") || "1", 10) || 1; + }); + if (count === 0) return; + colWidths = new Array(count).fill(DEFAULT_PASTE_COL_WIDTH_PX); + } + + let col = 0; + Array.from(firstRow.children) + .filter((c) => c.tagName === "TD" || c.tagName === "TH") + .forEach((cell) => { + if (cell.getAttribute("colwidth")) { + col += parseInt(cell.getAttribute("colspan") || "1", 10) || 1; + return; + } + const colspan = parseInt(cell.getAttribute("colspan") || "1", 10) || 1; + const slice = colWidths!.slice(col, col + colspan); + col += colspan; + if (slice.length === 0 || slice.every((w) => w === null)) return; + const values = slice.map((w) => (w == null ? 100 : w)); + cell.setAttribute("colwidth", values.join(",")); + }); + }); +} diff --git a/apps/server/src/integrations/import/services/import.service.ts b/apps/server/src/integrations/import/services/import.service.ts index 66c575850..0eb3ae40d 100644 --- a/apps/server/src/integrations/import/services/import.service.ts +++ b/apps/server/src/integrations/import/services/import.service.ts @@ -29,6 +29,8 @@ import { InjectQueue } from '@nestjs/bullmq'; import { Queue } from 'bullmq'; import { QueueJob, QueueName } from '../../queue/constants'; import { ModuleRef } from '@nestjs/core'; +import { load } from 'cheerio'; +import { normalizeImportHtml } from '../utils/import-formatter'; @Injectable() export class ImportService { @@ -136,7 +138,9 @@ export class ImportService { async processHTML(htmlInput: string): Promise { try { - return htmlToJson(htmlInput); + const $ = load(htmlInput); + normalizeImportHtml($, $.root()); + return htmlToJson($.html() || ''); } catch (err) { throw err; } diff --git a/apps/server/src/integrations/import/utils/import-formatter.ts b/apps/server/src/integrations/import/utils/import-formatter.ts index 3b0738a54..0333b75e7 100644 --- a/apps/server/src/integrations/import/utils/import-formatter.ts +++ b/apps/server/src/integrations/import/utils/import-formatter.ts @@ -5,6 +5,7 @@ import { v7 } from 'uuid'; import { InsertableBacklink } from '@docmost/db/types/entity.types'; import { Cheerio, CheerioAPI, load } from 'cheerio'; import slugify from '@sindresorhus/slugify'; +import { normalizeTableColumnWidths } from './table-utils'; // Check if text contains Unicode characters (for emojis/icons) function isUnicodeCharacter(text: string): boolean { @@ -51,9 +52,7 @@ export async function formatImportHtml(opts: { } } - notionFormatter($, $root); - xwikiFormatter($, $root); - defaultHtmlFormatter($, $root); + normalizeImportHtml($, $root); const backlinks = await rewriteInternalLinksToMentionHtml( $, @@ -73,6 +72,23 @@ export async function formatImportHtml(opts: { }; } +/** + * Contextless HTML cleanup shared by every import path. + * - notionFormatter: no-op on non-Notion HTML (class-selector-based). + * - xwikiFormatter: no-op on non-XWiki HTML (looks for #xwikicontent). + * - defaultHtmlFormatter: table column widths + provider auto-embeds. + * + * Does NOT run rewriteInternalLinksToMentionHtml — that requires zip context. + */ +export function normalizeImportHtml( + $: CheerioAPI, + $root: Cheerio, +): void { + notionFormatter($, $root); + xwikiFormatter($, $root); + defaultHtmlFormatter($, $root); +} + export function xwikiFormatter($: CheerioAPI, $root: Cheerio) { const $content = $root.find('#xwikicontent'); if ($content.length) { @@ -82,6 +98,8 @@ export function xwikiFormatter($: CheerioAPI, $root: Cheerio) { } export function defaultHtmlFormatter($: CheerioAPI, $root: Cheerio) { + normalizeTableColumnWidths($, $root); + $root.find('a[href]').each((_, el) => { const $el = $(el); const url = $el.attr('href')!; diff --git a/apps/server/src/integrations/import/utils/table-utils.ts b/apps/server/src/integrations/import/utils/table-utils.ts new file mode 100644 index 000000000..8b5240a0e --- /dev/null +++ b/apps/server/src/integrations/import/utils/table-utils.ts @@ -0,0 +1,107 @@ +import { CheerioAPI, Cheerio } from 'cheerio'; + +const DEFAULT_IMPORT_COL_WIDTH_PX = 150; + +/** + * Extracts a pixel-integer width from either the `width` attribute or + * `style="width: Npx"` on a //. Returns null when absent, + * non-numeric, or a non-px unit (em, %). + */ +function parsePixelWidth(el: Cheerio): number | null { + const attr = el.attr('width'); + if (attr) { + const n = parseInt(attr, 10); + if (Number.isFinite(n) && n > 0) return n; + } + const style = el.attr('style') || ''; + const m = style.match(/(?:^|;)\s*width\s*:\s*([\d.]+)\s*px/i); + if (m) { + const n = parseInt(m[1], 10); + if (Number.isFinite(n) && n > 0) return n; + } + return null; +} + +/** + * Derives per-column widths for a table, in visual column order. + * Priority: → first-row cells' own width style. + * Returns an array of length = number of columns, with null entries + * for columns whose width couldn't be determined. + */ +function deriveColumnWidths( + $: CheerioAPI, + table: Cheerio, +): (number | null)[] | null { + const cols = table.find('> colgroup > col'); + if (cols.length > 0) { + const widths: (number | null)[] = []; + cols.each(function () { + widths.push(parsePixelWidth($(this))); + }); + if (widths.some((w) => w !== null)) return widths; + } + + // Fallback: first row's cells. + const firstRow = table.find('> tbody > tr, > thead > tr, > tr').first(); + if (!firstRow.length) return null; + + const widths: (number | null)[] = []; + firstRow.children('td, th').each(function () { + const cell = $(this); + const colspan = parseInt(cell.attr('colspan') || '1', 10) || 1; + const w = parsePixelWidth(cell); + for (let i = 0; i < colspan; i++) { + widths.push(w !== null ? Math.round(w / colspan) : null); + } + }); + if (widths.every((w) => w === null)) return null; + return widths; +} + +/** + * Apply colwidth attributes to the first row of each table based on + * derived column widths. Accounts for colspan. Idempotent — re-running + * on already-normalized markup is a no-op. + * + * This lives upstream of tiptap's generateJSON: tiptap reads + * `colwidth="N[,N...]"` on / to build the runtime . + */ +export function normalizeTableColumnWidths( + $: CheerioAPI, + $root: Cheerio, +): void { + $root.find('table').each(function () { + const table = $(this); + const firstRow = table.find('> tbody > tr, > thead > tr, > tr').first(); + if (!firstRow.length) return; + + let colWidths = deriveColumnWidths($, table); + if (!colWidths) { + // No widths anywhere (e.g. markdown-sourced tables). Apply a default + // per-column width so the table's intrinsic width can exceed the + // editor container, letting .tableWrapper's overflow-x: auto scroll + // instead of cramming columns into the available width. + let count = 0; + firstRow.children('td, th').each(function () { + count += parseInt($(this).attr('colspan') || '1', 10) || 1; + }); + if (count === 0) return; + colWidths = new Array(count).fill(DEFAULT_IMPORT_COL_WIDTH_PX); + } + + let col = 0; + firstRow.children('td, th').each(function () { + const cell = $(this); + if (cell.attr('colwidth')) { + col += parseInt(cell.attr('colspan') || '1', 10) || 1; + return; + } + const colspan = parseInt(cell.attr('colspan') || '1', 10) || 1; + const slice = colWidths.slice(col, col + colspan); + col += colspan; + if (slice.length === 0 || slice.every((w) => w === null)) return; + const values = slice.map((w) => (w == null ? 100 : w)); + cell.attr('colwidth', values.join(',')); + }); + }); +} From a0aea43e25035b4f4aa24608674c10c8178f8d63 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Fri, 1 May 2026 11:47:03 +0100 Subject: [PATCH 13/46] feat(saml): allow disabling RequestedAuthnContext via env var Adds SAML_DISABLE_REQUESTED_AUTHN_CONTEXT env var, passed through to the SAML strategy's disableRequestedAuthnContext option. Defaults to existing behavior (element sent). Set to true to omit the element when the IdP authenticates the user with a method that does not match (e.g. MFA, FIDO, passwordless), which would otherwise cause AADSTS75011 with Microsoft Entra ID. --- apps/server/src/ee | 2 +- .../src/integrations/environment/environment.service.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/server/src/ee b/apps/server/src/ee index 4101fc427..fabe27298 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit 4101fc427b785e2711c0f608c377d641a2e4be78 +Subproject commit fabe2729879e0543518f0c42bfdb3b403afe3c4a diff --git a/apps/server/src/integrations/environment/environment.service.ts b/apps/server/src/integrations/environment/environment.service.ts index af35e9346..f0b548ab7 100644 --- a/apps/server/src/integrations/environment/environment.service.ts +++ b/apps/server/src/integrations/environment/environment.service.ts @@ -304,4 +304,11 @@ export class EnvironmentService { getClickHouseUrl(): string { return this.configService.get('CLICKHOUSE_URL'); } + + getSamlDisableRequestedAuthnContext(): boolean { + const disabled = this.configService + .get('SAML_DISABLE_REQUESTED_AUTHN_CONTEXT', 'false') + .toLowerCase(); + return disabled === 'true'; + } } From 1d2486455fb10678ca178257ad0b6b0186e7b522 Mon Sep 17 00:00:00 2001 From: Sarthak Chaturvedi <84394327+mayhemking007@users.noreply.github.com> Date: Fri, 1 May 2026 18:28:51 +0530 Subject: [PATCH 14/46] fix: prevent browser tab fallback in editor (#2123) --- apps/client/src/features/editor/page-editor.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/client/src/features/editor/page-editor.tsx b/apps/client/src/features/editor/page-editor.tsx index 30ccc2e48..c8c07bc2e 100644 --- a/apps/client/src/features/editor/page-editor.tsx +++ b/apps/client/src/features/editor/page-editor.tsx @@ -236,6 +236,14 @@ export default function PageEditor({ event.preventDefault(); return true; } + if (event.key === "Tab") { + const editor = editorRef.current; + if (!editor) return false; + event.preventDefault(); + return editor.view.someProp("handleKeyDown", (f) => + f(editor.view, event) + ); + } if (platformModifierKey(event) && event.code === "KeyK") { searchSpotlight.open(); return true; From 641ce142dfe229865b1efa130116e851c38c1eb6 Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Fri, 1 May 2026 14:53:30 +0100 Subject: [PATCH 15/46] feat(ee): SCIM (#1347) * SCIM - init (EE) * accept db transaction * sync * Content parser support for scim+json * patch scimmy * sync * return early if userIds is empty * sync * SCIM db table * fixes * scim tokens * backfill * feat(audit): add scim token events * rename scim migration * fix * fix translation * cleanup --- .../public/locales/en-US/translation.json | 34 ++++- .../layouts/global/global-app-shell.tsx | 4 +- .../components/settings/settings-queries.tsx | 8 + .../components/settings/settings-sidebar.tsx | 6 +- .../components/api-key-created-modal.tsx | 7 +- .../components/create-api-key-modal.tsx | 2 +- .../components/revoke-api-key-modal.tsx | 6 +- .../components/update-api-key-modal.tsx | 2 +- .../src/ee/api-key/queries/api-key-query.ts | 6 +- .../src/ee/audit/lib/audit-event-labels.ts | 12 ++ .../components/create-scim-token-modal.tsx | 78 ++++++++++ .../src/ee/scim/components/enable-scim.tsx | 55 +++++++ .../components/revoke-scim-token-modal.tsx | 61 ++++++++ .../components/scim-token-created-modal.tsx | 69 +++++++++ .../ee/scim/components/scim-token-table.tsx | 130 ++++++++++++++++ .../src/ee/scim/components/scim-url-panel.tsx | 30 ++++ .../components/update-scim-token-modal.tsx | 77 ++++++++++ apps/client/src/ee/scim/index.ts | 2 + .../src/ee/scim/queries/scim-token-query.ts | 96 ++++++++++++ .../ee/scim/services/scim-token-service.ts | 34 +++++ .../src/ee/scim/types/scim-token.types.ts | 27 ++++ .../security/components/sso-provider-list.tsx | 4 +- .../client/src/ee/security/pages/security.tsx | 143 +++++++++++++++++- .../workspace/types/workspace.types.ts | 1 + apps/server/package.json | 1 + apps/server/src/common/events/audit-events.ts | 6 + apps/server/src/common/helpers/utils.ts | 2 +- .../core/group/services/group-user.service.ts | 15 +- .../src/core/group/services/group.service.ts | 5 +- .../workspace/dto/update-workspace.dto.ts | 4 + .../workspace/services/workspace.service.ts | 12 +- .../migrations/20260501T092214-scim.ts | 110 ++++++++++++++ .../src/database/repos/group/group.repo.ts | 44 ++++-- .../src/database/repos/user/user.repo.ts | 4 + .../repos/workspace/workspace.repo.ts | 1 + apps/server/src/database/types/db.d.ts | 19 +++ .../server/src/database/types/entity.types.ts | 6 + apps/server/src/ee | 2 +- apps/server/src/main.ts | 16 ++ package.json | 3 +- patches/@tiptap__core.patch | 105 ------------- patches/scimmy@1.3.5.patch | 23 +++ pnpm-lock.yaml | 12 ++ 43 files changed, 1136 insertions(+), 148 deletions(-) create mode 100644 apps/client/src/ee/scim/components/create-scim-token-modal.tsx create mode 100644 apps/client/src/ee/scim/components/enable-scim.tsx create mode 100644 apps/client/src/ee/scim/components/revoke-scim-token-modal.tsx create mode 100644 apps/client/src/ee/scim/components/scim-token-created-modal.tsx create mode 100644 apps/client/src/ee/scim/components/scim-token-table.tsx create mode 100644 apps/client/src/ee/scim/components/scim-url-panel.tsx create mode 100644 apps/client/src/ee/scim/components/update-scim-token-modal.tsx create mode 100644 apps/client/src/ee/scim/index.ts create mode 100644 apps/client/src/ee/scim/queries/scim-token-query.ts create mode 100644 apps/client/src/ee/scim/services/scim-token-service.ts create mode 100644 apps/client/src/ee/scim/types/scim-token.types.ts create mode 100644 apps/server/src/database/migrations/20260501T092214-scim.ts delete mode 100644 patches/@tiptap__core.patch create mode 100644 patches/scimmy@1.3.5.patch diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index 3bfe7c9f0..56709bbe6 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -608,25 +608,21 @@ "Image exceeds 10MB limit.": "Image exceeds 10MB limit.", "Image removed successfully": "Image removed successfully", "API key": "API key", - "API key created successfully": "API key created successfully", "API keys": "API keys", "API management": "API management", - "Are you sure you want to revoke this API key": "Are you sure you want to revoke this API key", - "Create API Key": "Create API Key", "Custom expiration date": "Custom expiration date", "Enter a descriptive token name": "Enter a descriptive token name", "Expiration": "Expiration", "Expired": "Expired", "Expires": "Expires", - "I've saved my API key": "I've saved my API key", "Last use": "Last Used", "No API keys found": "No API keys found", "No expiration": "No expiration", - "Revoke API key": "Revoke API key", "Revoked successfully": "Revoked successfully", "Select expiration date": "Select expiration date", "This action cannot be undone. Any applications using this API key will stop working.": "This action cannot be undone. Any applications using this API key will stop working.", - "Update API key": "Update API key", + "Update": "Update", + "Update {{credential}}": "Update {{credential}}", "Manage API keys for all users in the workspace": "Manage API keys for all users in the workspace", "Restrict API key creation to admins": "Restrict API key creation to admins", "Only admins and owners can create new API keys. Existing member keys will continue to work.": "Only admins and owners can create new API keys. Existing member keys will continue to work.", @@ -880,5 +876,29 @@ "Try a different search term.": "Try a different search term.", "Try again": "Try again", "Untitled chat": "Untitled chat", - "What can I help you with?": "What can I help you with?" + "What can I help you with?": "What can I help you with?", + "Are you sure you want to revoke this {{credential}}": "Are you sure you want to revoke this {{credential}}", + "Automatically provision users and groups from your identity provider via SCIM.": "Automatically provision users and groups from your identity provider via SCIM.", + "Configure your identity provider with this URL to provision users and groups.": "Configure your identity provider with this URL to provision users and groups.", + "Create {{credential}}": "Create {{credential}}", + "{{credential}} created": "{{credential}} created", + "{{credential}} created successfully": "{{credential}} created successfully", + "Created by": "Created by", + "Custom": "Custom", + "Enable SCIM": "Enable SCIM", + "Enter a descriptive name": "Enter a descriptive name", + "I've saved my {{credential}}": "I've saved my {{credential}}", + "Important": "Important", + "Make sure to copy your {{credential}} now. You won't be able to see it again!": "Make sure to copy your {{credential}} now. You won't be able to see it again!", + "Never": "Never", + "Revoke {{credential}}": "Revoke {{credential}}", + "SCIM endpoint URL": "SCIM endpoint URL", + "SCIM provisioning": "SCIM provisioning", + "SCIM takes precedence over SSO group sync while enabled.": "SCIM takes precedence over SSO group sync while enabled.", + "You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.": "You have reached the maximum of {{max}} SCIM tokens. Delete an existing token to create a new one.", + "SCIM token": "SCIM token", + "SCIM tokens": "SCIM tokens", + "This action cannot be undone. Your identity provider will stop syncing immediately.": "This action cannot be undone. Your identity provider will stop syncing immediately.", + "Toggle SCIM provisioning": "Toggle SCIM provisioning", + "Token": "Token" } diff --git a/apps/client/src/components/layouts/global/global-app-shell.tsx b/apps/client/src/components/layouts/global/global-app-shell.tsx index 64bd3dde7..6e842a056 100644 --- a/apps/client/src/components/layouts/global/global-app-shell.tsx +++ b/apps/client/src/components/layouts/global/global-app-shell.tsx @@ -116,7 +116,9 @@ export default function GlobalAppShell({ {isSettingsRoute ? ( - {children} + + {children} + ) : ( children )} diff --git a/apps/client/src/components/settings/settings-queries.tsx b/apps/client/src/components/settings/settings-queries.tsx index e9562a858..892857f55 100644 --- a/apps/client/src/components/settings/settings-queries.tsx +++ b/apps/client/src/components/settings/settings-queries.tsx @@ -13,6 +13,7 @@ import { getShares } from "@/features/share/services/share-service.ts"; import { getApiKeys } from "@/ee/api-key"; import { getAuditLogs } from "@/ee/audit/services/audit-service"; import { getVerificationList } from "@/ee/page-verification/services/page-verification-service"; +import { getScimTokens } from "@/ee/scim/services/scim-token-service"; export const prefetchWorkspaceMembers = () => { const params: QueryParams = { limit: 100, query: "" }; @@ -98,3 +99,10 @@ export const prefetchVerifiedPages = () => { queryFn: () => getVerificationList(params), }); }; + +export const prefetchScimTokens = () => { + queryClient.prefetchQuery({ + queryKey: ["scim-token-list", { cursor: undefined }], + queryFn: () => getScimTokens({}), + }); +}; diff --git a/apps/client/src/components/settings/settings-sidebar.tsx b/apps/client/src/components/settings/settings-sidebar.tsx index 90d89d13e..8ea1f59f9 100644 --- a/apps/client/src/components/settings/settings-sidebar.tsx +++ b/apps/client/src/components/settings/settings-sidebar.tsx @@ -31,6 +31,7 @@ import { prefetchBilling, prefetchGroups, prefetchLicense, + prefetchScimTokens, prefetchShares, prefetchSpaces, prefetchSsoProviders, @@ -204,7 +205,10 @@ export default function SettingsSidebar() { } break; case "Security & SSO": - prefetchHandler = prefetchSsoProviders; + prefetchHandler = () => { + prefetchSsoProviders(); + prefetchScimTokens(); + }; break; case "Public sharing": prefetchHandler = prefetchShares; diff --git a/apps/client/src/ee/api-key/components/api-key-created-modal.tsx b/apps/client/src/ee/api-key/components/api-key-created-modal.tsx index 6a01ee3cf..ed44811a7 100644 --- a/apps/client/src/ee/api-key/components/api-key-created-modal.tsx +++ b/apps/client/src/ee/api-key/components/api-key-created-modal.tsx @@ -31,7 +31,7 @@ export function ApiKeyCreatedModal({ @@ -41,7 +41,8 @@ export function ApiKeyCreatedModal({ color="red" > {t( - "Make sure to copy your API key now. You won't be able to see it again!", + "Make sure to copy your {{credential}} now. You won't be able to see it again!", + { credential: t("API key") }, )} @@ -64,7 +65,7 @@ export function ApiKeyCreatedModal({ diff --git a/apps/client/src/ee/api-key/components/create-api-key-modal.tsx b/apps/client/src/ee/api-key/components/create-api-key-modal.tsx index ab19552c5..0b93c080b 100644 --- a/apps/client/src/ee/api-key/components/create-api-key-modal.tsx +++ b/apps/client/src/ee/api-key/components/create-api-key-modal.tsx @@ -105,7 +105,7 @@ export function CreateApiKeyModal({
handleSubmit(values))}> diff --git a/apps/client/src/ee/api-key/components/revoke-api-key-modal.tsx b/apps/client/src/ee/api-key/components/revoke-api-key-modal.tsx index 3092ead42..95651a4e0 100644 --- a/apps/client/src/ee/api-key/components/revoke-api-key-modal.tsx +++ b/apps/client/src/ee/api-key/components/revoke-api-key-modal.tsx @@ -30,12 +30,14 @@ export function RevokeApiKeyModal({ - {t("Are you sure you want to revoke this API key")}{" "} + {t("Are you sure you want to revoke this {{credential}}", { + credential: t("API key"), + })}{" "} {apiKey?.name}? diff --git a/apps/client/src/ee/api-key/components/update-api-key-modal.tsx b/apps/client/src/ee/api-key/components/update-api-key-modal.tsx index e4370eac7..0e66d680e 100644 --- a/apps/client/src/ee/api-key/components/update-api-key-modal.tsx +++ b/apps/client/src/ee/api-key/components/update-api-key-modal.tsx @@ -53,7 +53,7 @@ export function UpdateApiKeyModal({ handleSubmit(values))}> diff --git a/apps/client/src/ee/api-key/queries/api-key-query.ts b/apps/client/src/ee/api-key/queries/api-key-query.ts index 75f2d3514..f27492da8 100644 --- a/apps/client/src/ee/api-key/queries/api-key-query.ts +++ b/apps/client/src/ee/api-key/queries/api-key-query.ts @@ -63,7 +63,11 @@ export function useCreateApiKeyMutation() { return useMutation({ mutationFn: (data) => createApiKey(data), onSuccess: () => { - notifications.show({ message: t("API key created successfully") }); + notifications.show({ + message: t("{{credential}} created successfully", { + credential: t("API key"), + }), + }); queryClient.invalidateQueries({ predicate: (item) => ["api-key-list"].includes(item.queryKey[0] as string), diff --git a/apps/client/src/ee/audit/lib/audit-event-labels.ts b/apps/client/src/ee/audit/lib/audit-event-labels.ts index 76d08295a..7fc55b3d0 100644 --- a/apps/client/src/ee/audit/lib/audit-event-labels.ts +++ b/apps/client/src/ee/audit/lib/audit-event-labels.ts @@ -33,6 +33,10 @@ export const auditEventLabels: Record = { "api_key.updated": "Updated API key", "api_key.deleted": "Deleted API key", + "scim_token.created": "Created SCIM token", + "scim_token.updated": "Updated SCIM token", + "scim_token.deleted": "Deleted SCIM token", + "space.created": "Created space", "space.updated": "Updated space", "space.deleted": "Deleted space", @@ -174,6 +178,14 @@ export const eventFilterOptions: EventGroup[] = [ { value: "api_key.deleted", label: "Deleted API key" }, ], }, + { + group: "SCIM token", + items: [ + { value: "scim_token.created", label: "Created SCIM token" }, + { value: "scim_token.updated", label: "Updated SCIM token" }, + { value: "scim_token.deleted", label: "Deleted SCIM token" }, + ], + }, { group: "License", items: [ diff --git a/apps/client/src/ee/scim/components/create-scim-token-modal.tsx b/apps/client/src/ee/scim/components/create-scim-token-modal.tsx new file mode 100644 index 000000000..c0dfa35c3 --- /dev/null +++ b/apps/client/src/ee/scim/components/create-scim-token-modal.tsx @@ -0,0 +1,78 @@ +import { Modal, TextInput, Button, Group, Stack } from "@mantine/core"; +import { useForm } from "@mantine/form"; +import { zod4Resolver } from "mantine-form-zod-resolver"; +import { z } from "zod/v4"; +import { useTranslation } from "react-i18next"; +import { useCreateScimTokenMutation } from "@/ee/scim/queries/scim-token-query"; +import { IScimToken } from "@/ee/scim/types/scim-token.types"; + +interface CreateScimTokenModalProps { + opened: boolean; + onClose: () => void; + onSuccess: (response: IScimToken) => void; +} + +const formSchema = z.object({ + name: z.string().min(1, "Name is required"), +}); +type FormValues = z.infer; + +export function CreateScimTokenModal({ + opened, + onClose, + onSuccess, +}: CreateScimTokenModalProps) { + const { t } = useTranslation(); + const createMutation = useCreateScimTokenMutation(); + + const form = useForm({ + validate: zod4Resolver(formSchema), + initialValues: { name: "" }, + }); + + const handleSubmit = async (data: FormValues) => { + try { + const created = await createMutation.mutateAsync({ name: data.name }); + onSuccess(created); + form.reset(); + onClose(); + } catch (err) { + // + } + }; + + const handleClose = () => { + form.reset(); + onClose(); + }; + + return ( + + handleSubmit(values))}> + + + + + + + + + + + ); +} diff --git a/apps/client/src/ee/scim/components/enable-scim.tsx b/apps/client/src/ee/scim/components/enable-scim.tsx new file mode 100644 index 000000000..0f8204ebc --- /dev/null +++ b/apps/client/src/ee/scim/components/enable-scim.tsx @@ -0,0 +1,55 @@ +import { Group, Text, Switch, Tooltip } from "@mantine/core"; +import { useAtom } from "jotai"; +import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts"; +import { notifications } from "@mantine/notifications"; +import { useHasFeature } from "@/ee/hooks/use-feature.ts"; +import { Feature } from "@/ee/features.ts"; +import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label.ts"; + +export default function EnableScim() { + const { t } = useTranslation(); + const [workspace, setWorkspace] = useAtom(workspaceAtom); + const [checked, setChecked] = useState(workspace?.isScimEnabled ?? false); + const hasAccess = useHasFeature(Feature.SCIM); + const upgradeLabel = useUpgradeLabel(); + + const handleChange = async (event: React.ChangeEvent) => { + const value = event.currentTarget.checked; + try { + const updatedWorkspace = await updateWorkspace({ isScimEnabled: value }); + setChecked(value); + setWorkspace(updatedWorkspace); + } catch (err) { + notifications.show({ + message: err?.response?.data?.message, + color: "red", + }); + } + }; + + return ( + +
+ {t("Enable SCIM")} + + {t( + "Automatically provision users and groups from your identity provider via SCIM.", + )} + +
+ + + + +
+ ); +} diff --git a/apps/client/src/ee/scim/components/revoke-scim-token-modal.tsx b/apps/client/src/ee/scim/components/revoke-scim-token-modal.tsx new file mode 100644 index 000000000..c69878459 --- /dev/null +++ b/apps/client/src/ee/scim/components/revoke-scim-token-modal.tsx @@ -0,0 +1,61 @@ +import { Modal, Text, Button, Group, Stack } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import { useRevokeScimTokenMutation } from "@/ee/scim/queries/scim-token-query"; +import { IScimToken } from "@/ee/scim/types/scim-token.types"; + +interface RevokeScimTokenModalProps { + opened: boolean; + onClose: () => void; + scimToken: IScimToken | null; +} + +export function RevokeScimTokenModal({ + opened, + onClose, + scimToken, +}: RevokeScimTokenModalProps) { + const { t } = useTranslation(); + const revokeMutation = useRevokeScimTokenMutation(); + + const handleRevoke = async () => { + if (!scimToken) return; + await revokeMutation.mutateAsync({ tokenId: scimToken.id }); + onClose(); + }; + + return ( + + + + {t("Are you sure you want to revoke this {{credential}}", { + credential: t("SCIM token"), + })}{" "} + {scimToken?.name}? + + + {t( + "This action cannot be undone. Your identity provider will stop syncing immediately.", + )} + + + + + + + + + ); +} diff --git a/apps/client/src/ee/scim/components/scim-token-created-modal.tsx b/apps/client/src/ee/scim/components/scim-token-created-modal.tsx new file mode 100644 index 000000000..591a30e39 --- /dev/null +++ b/apps/client/src/ee/scim/components/scim-token-created-modal.tsx @@ -0,0 +1,69 @@ +import { + Modal, + Text, + Stack, + Alert, + Group, + Button, + TextInput, +} from "@mantine/core"; +import { IconAlertTriangle } from "@tabler/icons-react"; +import { useTranslation } from "react-i18next"; +import CopyTextButton from "@/components/common/copy.tsx"; +import { IScimToken } from "@/ee/scim/types/scim-token.types"; + +interface ScimTokenCreatedModalProps { + opened: boolean; + onClose: () => void; + scimToken: IScimToken | null; +} + +export function ScimTokenCreatedModal({ + opened, + onClose, + scimToken, +}: ScimTokenCreatedModalProps) { + const { t } = useTranslation(); + if (!scimToken) return null; + + return ( + + + } + title={t("Important")} + color="red" + > + {t( + "Make sure to copy your {{credential}} now. You won't be able to see it again!", + { credential: t("SCIM token") }, + )} + + +
+ + {t("SCIM token")} + + + + + +
+ + +
+
+ ); +} diff --git a/apps/client/src/ee/scim/components/scim-token-table.tsx b/apps/client/src/ee/scim/components/scim-token-table.tsx new file mode 100644 index 000000000..81b596ee7 --- /dev/null +++ b/apps/client/src/ee/scim/components/scim-token-table.tsx @@ -0,0 +1,130 @@ +import { ActionIcon, Group, Menu, Table, Text } from "@mantine/core"; +import { IconDots, IconEdit, IconTrash } from "@tabler/icons-react"; +import { format } from "date-fns"; +import { useTranslation } from "react-i18next"; +import { CustomAvatar } from "@/components/ui/custom-avatar.tsx"; +import React from "react"; +import NoTableResults from "@/components/common/no-table-results"; +import { IScimToken } from "@/ee/scim/types/scim-token.types"; + +interface ScimTokenTableProps { + tokens: IScimToken[]; + isLoading?: boolean; + onUpdate?: (token: IScimToken) => void; + onRevoke?: (token: IScimToken) => void; +} + +export function ScimTokenTable({ + tokens, + isLoading, + onUpdate, + onRevoke, +}: ScimTokenTableProps) { + const { t } = useTranslation(); + + const formatDate = (date: Date | string | null) => { + if (!date) return t("Never"); + return format(new Date(date), "MMM dd, yyyy"); + }; + + return ( + + + + + {t("Name")} + {t("Token")} + {t("Created by")} + {t("Last used")} + {t("Created")} + + + + + + {tokens && tokens.length > 0 ? ( + tokens.map((token) => ( + + + + {token.name} + + + + + + ••••{token.tokenLastFour} + + + + {token.creator ? ( + + + + + {token.creator.name} + + + + ) : ( + + + — + + + )} + + + + {formatDate(token.lastUsedAt)} + + + + + + {formatDate(token.createdAt)} + + + + + + + + + + + + {onUpdate && ( + } + onClick={() => onUpdate(token)} + > + {t("Rename")} + + )} + {onRevoke && ( + } + color="red" + onClick={() => onRevoke(token)} + > + {t("Revoke")} + + )} + + + + + )) + ) : ( + + )} + +
+
+ ); +} diff --git a/apps/client/src/ee/scim/components/scim-url-panel.tsx b/apps/client/src/ee/scim/components/scim-url-panel.tsx new file mode 100644 index 000000000..6aa78820c --- /dev/null +++ b/apps/client/src/ee/scim/components/scim-url-panel.tsx @@ -0,0 +1,30 @@ +import { Group, Stack, Text, TextInput } from "@mantine/core"; +import { useTranslation } from "react-i18next"; +import CopyTextButton from "@/components/common/copy.tsx"; + +export function ScimUrlPanel() { + const { t } = useTranslation(); + const scimUrl = `${window.location.origin}/api/scim/v2`; + + return ( + + + {t("SCIM endpoint URL")} + + + {t( + "Configure your identity provider with this URL to provision users and groups.", + )} + + + + + + + ); +} diff --git a/apps/client/src/ee/scim/components/update-scim-token-modal.tsx b/apps/client/src/ee/scim/components/update-scim-token-modal.tsx new file mode 100644 index 000000000..104e215ff --- /dev/null +++ b/apps/client/src/ee/scim/components/update-scim-token-modal.tsx @@ -0,0 +1,77 @@ +import { Modal, TextInput, Button, Group, Stack } from "@mantine/core"; +import { useForm } from "@mantine/form"; +import { zod4Resolver } from "mantine-form-zod-resolver"; +import { z } from "zod/v4"; +import { useTranslation } from "react-i18next"; +import { useEffect } from "react"; +import { useUpdateScimTokenMutation } from "@/ee/scim/queries/scim-token-query"; +import { IScimToken } from "@/ee/scim/types/scim-token.types"; + +const formSchema = z.object({ + name: z.string().min(1, "Name is required"), +}); +type FormValues = z.infer; + +interface UpdateScimTokenModalProps { + opened: boolean; + onClose: () => void; + scimToken: IScimToken | null; +} + +export function UpdateScimTokenModal({ + opened, + onClose, + scimToken, +}: UpdateScimTokenModalProps) { + const { t } = useTranslation(); + const updateMutation = useUpdateScimTokenMutation(); + + const form = useForm({ + validate: zod4Resolver(formSchema), + initialValues: { name: "" }, + }); + + useEffect(() => { + if (opened && scimToken) { + form.setValues({ name: scimToken.name }); + } + }, [opened, scimToken]); + + const handleSubmit = async (data: FormValues) => { + if (!scimToken) return; + await updateMutation.mutateAsync({ + tokenId: scimToken.id, + name: data.name, + }); + onClose(); + }; + + return ( + +
handleSubmit(values))}> + + + + + + + + +
+
+ ); +} diff --git a/apps/client/src/ee/scim/index.ts b/apps/client/src/ee/scim/index.ts new file mode 100644 index 000000000..e246200d0 --- /dev/null +++ b/apps/client/src/ee/scim/index.ts @@ -0,0 +1,2 @@ +export * from "./types/scim-token.types"; +export * from "./services/scim-token-service"; diff --git a/apps/client/src/ee/scim/queries/scim-token-query.ts b/apps/client/src/ee/scim/queries/scim-token-query.ts new file mode 100644 index 000000000..999f4d200 --- /dev/null +++ b/apps/client/src/ee/scim/queries/scim-token-query.ts @@ -0,0 +1,96 @@ +import { IPagination, QueryParams } from "@/lib/types.ts"; +import { + keepPreviousData, + useMutation, + useQuery, + useQueryClient, + UseQueryResult, +} from "@tanstack/react-query"; +import { + createScimToken, + getScimTokens, + revokeScimToken, + updateScimToken, +} from "@/ee/scim/services/scim-token-service"; +import { + IScimToken, + ICreateScimTokenRequest, + IRevokeScimTokenRequest, + IUpdateScimTokenRequest, +} from "@/ee/scim/types/scim-token.types"; +import { notifications } from "@mantine/notifications"; +import { useTranslation } from "react-i18next"; + +export function useGetScimTokensQuery( + params?: QueryParams, +): UseQueryResult, Error> { + return useQuery({ + queryKey: ["scim-token-list", params], + queryFn: () => getScimTokens(params), + placeholderData: keepPreviousData, + }); +} + +export function useCreateScimTokenMutation() { + const queryClient = useQueryClient(); + const { t } = useTranslation(); + + return useMutation({ + mutationFn: (data) => createScimToken(data), + onSuccess: () => { + notifications.show({ + message: t("{{credential}} created successfully", { + credential: t("SCIM token"), + }), + }); + queryClient.invalidateQueries({ + predicate: (item) => + ["scim-token-list"].includes(item.queryKey[0] as string), + }); + }, + onError: (error) => { + const errorMessage = error["response"]?.data?.message; + notifications.show({ message: errorMessage, color: "red" }); + }, + }); +} + +export function useUpdateScimTokenMutation() { + const queryClient = useQueryClient(); + const { t } = useTranslation(); + + return useMutation({ + mutationFn: (data) => updateScimToken(data), + onSuccess: () => { + notifications.show({ message: t("Updated successfully") }); + queryClient.invalidateQueries({ + predicate: (item) => + ["scim-token-list"].includes(item.queryKey[0] as string), + }); + }, + onError: (error) => { + const errorMessage = error["response"]?.data?.message; + notifications.show({ message: errorMessage, color: "red" }); + }, + }); +} + +export function useRevokeScimTokenMutation() { + const queryClient = useQueryClient(); + const { t } = useTranslation(); + + return useMutation({ + mutationFn: (data) => revokeScimToken(data), + onSuccess: () => { + notifications.show({ message: t("Revoked successfully") }); + queryClient.invalidateQueries({ + predicate: (item) => + ["scim-token-list"].includes(item.queryKey[0] as string), + }); + }, + onError: (error) => { + const errorMessage = error["response"]?.data?.message; + notifications.show({ message: errorMessage, color: "red" }); + }, + }); +} diff --git a/apps/client/src/ee/scim/services/scim-token-service.ts b/apps/client/src/ee/scim/services/scim-token-service.ts new file mode 100644 index 000000000..27e730358 --- /dev/null +++ b/apps/client/src/ee/scim/services/scim-token-service.ts @@ -0,0 +1,34 @@ +import api from "@/lib/api-client"; +import { + IScimToken, + ICreateScimTokenRequest, + IRevokeScimTokenRequest, + IUpdateScimTokenRequest, +} from "@/ee/scim/types/scim-token.types"; +import { IPagination, QueryParams } from "@/lib/types.ts"; + +export async function getScimTokens( + params?: QueryParams, +): Promise> { + const req = await api.post("/scim-tokens", { ...params }); + return req.data; +} + +export async function createScimToken( + data: ICreateScimTokenRequest, +): Promise { + const req = await api.post("/scim-tokens/create", data); + return req.data; +} + +export async function updateScimToken( + data: IUpdateScimTokenRequest, +): Promise { + await api.post("/scim-tokens/update", data); +} + +export async function revokeScimToken( + data: IRevokeScimTokenRequest, +): Promise { + await api.post("/scim-tokens/revoke", data); +} diff --git a/apps/client/src/ee/scim/types/scim-token.types.ts b/apps/client/src/ee/scim/types/scim-token.types.ts new file mode 100644 index 000000000..076501291 --- /dev/null +++ b/apps/client/src/ee/scim/types/scim-token.types.ts @@ -0,0 +1,27 @@ +import { IUser } from "@/features/user/types/user.types.ts"; + +export interface IScimToken { + id: string; + name: string; + token?: string; + tokenLastFour: string; + isEnabled: boolean; + creatorId: string; + workspaceId: string; + lastUsedAt: string | null; + createdAt: string; + creator?: Partial; +} + +export interface ICreateScimTokenRequest { + name: string; +} + +export interface IUpdateScimTokenRequest { + tokenId: string; + name: string; +} + +export interface IRevokeScimTokenRequest { + tokenId: string; +} diff --git a/apps/client/src/ee/security/components/sso-provider-list.tsx b/apps/client/src/ee/security/components/sso-provider-list.tsx index 7aac7d117..3603f9598 100644 --- a/apps/client/src/ee/security/components/sso-provider-list.tsx +++ b/apps/client/src/ee/security/components/sso-provider-list.tsx @@ -69,8 +69,8 @@ export default function SsoProviderList() { return ( <> - - + +
{t("Name")} diff --git a/apps/client/src/ee/security/pages/security.tsx b/apps/client/src/ee/security/pages/security.tsx index 254809c74..ee6343516 100644 --- a/apps/client/src/ee/security/pages/security.tsx +++ b/apps/client/src/ee/security/pages/security.tsx @@ -1,8 +1,18 @@ import { Helmet } from "react-helmet-async"; import { getAppName, isCloud } from "@/lib/config.ts"; import SettingsTitle from "@/components/settings/settings-title.tsx"; -import { Divider, Title } from "@mantine/core"; -import React from "react"; +import { + Alert, + Button, + Card, + Divider, + Group, + Space, + Title, + Tooltip, +} from "@mantine/core"; +import { IconInfoCircle } from "@tabler/icons-react"; +import React, { useState } from "react"; import useUserRole from "@/hooks/use-user-role.tsx"; import SsoProviderList from "@/ee/security/components/sso-provider-list.tsx"; import CreateSsoProvider from "@/ee/security/components/create-sso-provider.tsx"; @@ -12,16 +22,41 @@ import { useTranslation } from "react-i18next"; import EnforceMfa from "@/ee/security/components/enforce-mfa.tsx"; import DisablePublicSharing from "@/ee/security/components/disable-public-sharing.tsx"; import TrashRetention from "@/ee/security/components/trash-retention.tsx"; - +import { useAtom } from "jotai"; +import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; import { useHasFeature } from "@/ee/hooks/use-feature"; import { Feature } from "@/ee/features"; +import { useGetScimTokensQuery } from "@/ee/scim/queries/scim-token-query"; +import { ScimUrlPanel } from "@/ee/scim/components/scim-url-panel"; +import { ScimTokenTable } from "@/ee/scim/components/scim-token-table"; +import { CreateScimTokenModal } from "@/ee/scim/components/create-scim-token-modal"; +import { ScimTokenCreatedModal } from "@/ee/scim/components/scim-token-created-modal"; +import { RevokeScimTokenModal } from "@/ee/scim/components/revoke-scim-token-modal"; +import { UpdateScimTokenModal } from "@/ee/scim/components/update-scim-token-modal"; +import EnableScim from "@/ee/scim/components/enable-scim"; +import { useCursorPaginate } from "@/hooks/use-cursor-paginate"; +import Paginate from "@/components/common/paginate"; +import { IScimToken } from "@/ee/scim/types/scim-token.types"; + +const SCIM_TOKEN_LIMIT = 5; export default function Security() { const { t } = useTranslation(); const { isAdmin } = useUserRole(); const hasCustomSso = useHasFeature(Feature.SSO_CUSTOM); - const hasRetention = useHasFeature(Feature.RETENTION); - const hasSharingControls = useHasFeature(Feature.SHARING_CONTROLS); + const hasScim = useHasFeature(Feature.SCIM); + const [workspace] = useAtom(workspaceAtom); + const isScimEnabled = workspace?.isScimEnabled ?? false; + + const { cursor, goNext, goPrev } = useCursorPaginate(); + const { data: scimData, isLoading: scimLoading } = useGetScimTokensQuery( + hasScim && isScimEnabled ? { cursor } : undefined, + ); + + const [createOpen, setCreateOpen] = useState(false); + const [createdToken, setCreatedToken] = useState(null); + const [updateTarget, setUpdateTarget] = useState(null); + const [revokeTarget, setRevokeTarget] = useState(null); if (!isAdmin) { return null; @@ -45,7 +80,7 @@ export default function Security() { - Single sign-on (SSO) + {t("Single sign-on (SSO)")} @@ -66,6 +101,102 @@ export default function Security() { )} + + {hasScim && ( + <> + + + + {t("SCIM provisioning")} + + + } + color="blue" + variant="light" + mb="md" + > + {t("SCIM takes precedence over SSO group sync while enabled.")} + + + + + + + + + {isScimEnabled && ( + <> + + + + {t("SCIM tokens")} + + + + + + + + + + + + {scimData?.items.length > 0 && ( + goNext(scimData?.meta?.nextCursor)} + onPrev={goPrev} + /> + )} + + setCreateOpen(false)} + onSuccess={setCreatedToken} + /> + + setCreatedToken(null)} + scimToken={createdToken} + /> + + setUpdateTarget(null)} + scimToken={updateTarget} + /> + + setRevokeTarget(null)} + scimToken={revokeTarget} + /> + + )} + + )} ); } diff --git a/apps/client/src/features/workspace/types/workspace.types.ts b/apps/client/src/features/workspace/types/workspace.types.ts index f733f73a0..eda89dd56 100644 --- a/apps/client/src/features/workspace/types/workspace.types.ts +++ b/apps/client/src/features/workspace/types/workspace.types.ts @@ -28,6 +28,7 @@ export interface IWorkspace { trashRetentionDays?: number; restrictApiToAdmins?: boolean; allowMemberTemplates?: boolean; + isScimEnabled?: boolean; } export interface IWorkspaceSettings { diff --git a/apps/server/package.json b/apps/server/package.json index 7c97763b7..794924876 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -111,6 +111,7 @@ "reflect-metadata": "^0.2.2", "rxjs": "^7.8.2", "sanitize-filename": "1.6.3", + "scimmy": "1.3.5", "socket.io": "^4.8.3", "stripe": "^17.7.0", "tlds": "^1.261.0", diff --git a/apps/server/src/common/events/audit-events.ts b/apps/server/src/common/events/audit-events.ts index 955a6ba5a..d8be76f83 100644 --- a/apps/server/src/common/events/audit-events.ts +++ b/apps/server/src/common/events/audit-events.ts @@ -23,6 +23,11 @@ export const AuditEvent = { API_KEY_UPDATED: 'api_key.updated', API_KEY_DELETED: 'api_key.deleted', + // SCIM Tokens + SCIM_TOKEN_CREATED: 'scim_token.created', + SCIM_TOKEN_UPDATED: 'scim_token.updated', + SCIM_TOKEN_DELETED: 'scim_token.deleted', + // Space SPACE_CREATED: 'space.created', SPACE_UPDATED: 'space.updated', @@ -119,6 +124,7 @@ export const AuditResource = { COMMENT: 'comment', SHARE: 'share', API_KEY: 'api_key', + SCIM_TOKEN: 'scim_token', SSO_PROVIDER: 'sso_provider', WORKSPACE_INVITATION: 'workspace_invitation', ATTACHMENT: 'attachment', diff --git a/apps/server/src/common/helpers/utils.ts b/apps/server/src/common/helpers/utils.ts index f65067e1a..21475c143 100644 --- a/apps/server/src/common/helpers/utils.ts +++ b/apps/server/src/common/helpers/utils.ts @@ -110,7 +110,7 @@ export function extractBearerTokenFromHeader( request: FastifyRequest, ): string | undefined { const [type, token] = request.headers.authorization?.split(' ') ?? []; - return type === 'Bearer' ? token : undefined; + return type?.toLowerCase() === 'bearer' ? token : undefined; } /** diff --git a/apps/server/src/core/group/services/group-user.service.ts b/apps/server/src/core/group/services/group-user.service.ts index 58ca8a892..2857f70f8 100644 --- a/apps/server/src/core/group/services/group-user.service.ts +++ b/apps/server/src/core/group/services/group-user.service.ts @@ -7,7 +7,7 @@ import { } from '@nestjs/common'; import { PaginationOptions } from '@docmost/db/pagination/pagination-options'; import { GroupService } from './group.service'; -import { KyselyDB } from '@docmost/db/types/kysely.types'; +import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types'; import { InjectKysely } from 'nestjs-kysely'; import { GroupUserRepo } from '@docmost/db/repos/group/group-user.repo'; import { SpaceMemberRepo } from '@docmost/db/repos/space/space-member.repo'; @@ -20,6 +20,7 @@ import { AUDIT_SERVICE, IAuditService, } from '../../../integrations/audit/audit.service'; +import { dbOrTx } from '@docmost/db/utils'; @Injectable() export class GroupUserService { @@ -54,17 +55,23 @@ export class GroupUserService { userIds: string[], groupId: string, workspaceId: string, + trx?: KyselyTransaction, ): Promise { - await this.groupService.findAndValidateGroup(groupId, workspaceId); + const db = dbOrTx(this.db, trx); + await this.groupService.findAndValidateGroup(groupId, workspaceId, trx); + + if (userIds.length === 0) return; // make sure we have valid workspace users - const validUsers = await this.db + const validUsers = await db .selectFrom('users') .select(['id', 'name']) .where('users.id', 'in', userIds) .where('users.workspaceId', '=', workspaceId) .execute(); + if (validUsers.length === 0) return; + // prepare users to add to group const groupUsersToInsert = []; for (const user of validUsers) { @@ -75,7 +82,7 @@ export class GroupUserService { } // batch insert new group users - await this.db + await db .insertInto('groupUsers') .values(groupUsersToInsert) .onConflict((oc) => oc.columns(['userId', 'groupId']).doNothing()) diff --git a/apps/server/src/core/group/services/group.service.ts b/apps/server/src/core/group/services/group.service.ts index 838376385..47de46936 100644 --- a/apps/server/src/core/group/services/group.service.ts +++ b/apps/server/src/core/group/services/group.service.ts @@ -216,8 +216,11 @@ export class GroupService { async findAndValidateGroup( groupId: string, workspaceId: string, + trx?: KyselyTransaction, ): Promise { - const group = await this.groupRepo.findById(groupId, workspaceId); + const group = await this.groupRepo.findById(groupId, workspaceId, { + trx, + }); if (!group) { throw new NotFoundException('Group not found'); } diff --git a/apps/server/src/core/workspace/dto/update-workspace.dto.ts b/apps/server/src/core/workspace/dto/update-workspace.dto.ts index a08b1e524..25697a4b9 100644 --- a/apps/server/src/core/workspace/dto/update-workspace.dto.ts +++ b/apps/server/src/core/workspace/dto/update-workspace.dto.ts @@ -41,6 +41,10 @@ export class UpdateWorkspaceDto extends PartialType(CreateWorkspaceDto) { @IsBoolean() mcpEnabled: boolean; + @IsOptional() + @IsBoolean() + isScimEnabled: boolean; + @IsOptional() @IsBoolean() aiChat: boolean; diff --git a/apps/server/src/core/workspace/services/workspace.service.ts b/apps/server/src/core/workspace/services/workspace.service.ts index 726089518..267eb13b7 100644 --- a/apps/server/src/core/workspace/services/workspace.service.ts +++ b/apps/server/src/core/workspace/services/workspace.service.ts @@ -331,7 +331,8 @@ export class WorkspaceService { typeof updateWorkspaceDto.trashRetentionDays !== 'undefined' || typeof updateWorkspaceDto.mcpEnabled !== 'undefined' || typeof updateWorkspaceDto.restrictApiToAdmins !== 'undefined' || - typeof updateWorkspaceDto.allowMemberTemplates !== 'undefined' + typeof updateWorkspaceDto.allowMemberTemplates !== 'undefined' || + typeof updateWorkspaceDto.isScimEnabled !== 'undefined' ) { const ws = await this.db .selectFrom('workspaces') @@ -351,6 +352,14 @@ export class WorkspaceService { } } + if (typeof updateWorkspaceDto.isScimEnabled !== 'undefined') { + if (!this.licenseCheckService.hasFeature(ws.licenseKey, Feature.SCIM, ws.plan)) { + throw new ForbiddenException( + 'This feature requires a valid license', + ); + } + } + if ( typeof updateWorkspaceDto.disablePublicSharing !== 'undefined' || typeof updateWorkspaceDto.trashRetentionDays !== 'undefined' || @@ -535,6 +544,7 @@ export class WorkspaceService { 'enforceSso', 'enforceMfa', 'emailDomains', + 'isScimEnabled', ], updateWorkspaceDto, workspaceBefore, diff --git a/apps/server/src/database/migrations/20260501T092214-scim.ts b/apps/server/src/database/migrations/20260501T092214-scim.ts new file mode 100644 index 000000000..69e4bf566 --- /dev/null +++ b/apps/server/src/database/migrations/20260501T092214-scim.ts @@ -0,0 +1,110 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await db.schema + .createTable('scim_tokens') + .addColumn('id', 'uuid', (col) => + col.primaryKey().defaultTo(sql`gen_uuid_v7()`), + ) + .addColumn('name', 'varchar', (col) => col.notNull()) + .addColumn('token_hash', 'varchar', (col) => col.notNull()) + .addColumn('token_last_four', 'varchar(4)', (col) => col.notNull()) + .addColumn('last_used_at', 'timestamptz') + .addColumn('is_enabled', 'boolean', (col) => col.notNull().defaultTo(true)) + .addColumn('creator_id', 'uuid', (col) => + col.references('users.id').onDelete('set null'), + ) + .addColumn('workspace_id', 'uuid', (col) => + col.references('workspaces.id').onDelete('cascade').notNull(), + ) + .addColumn('created_at', 'timestamptz', (col) => + col.notNull().defaultTo(sql`now()`), + ) + .addColumn('updated_at', 'timestamptz', (col) => + col.notNull().defaultTo(sql`now()`), + ) + .addColumn('deleted_at', 'timestamptz') + .execute(); + + await db.schema + .createIndex('idx_scim_tokens_token_hash') + .ifNotExists() + .on('scim_tokens') + .column('token_hash') + .execute(); + + await db.schema + .createIndex('idx_scim_tokens_workspace_id') + .ifNotExists() + .on('scim_tokens') + .column('workspace_id') + .execute(); + + await db.schema + .alterTable('users') + .addColumn('scim_external_id', 'text') + .execute(); + + await db.schema + .createIndex('idx_users_workspace_scim_external_id') + .ifNotExists() + .on('users') + .columns(['workspace_id', 'scim_external_id']) + .where('scim_external_id', 'is not', null) + .unique() + .execute(); + + await db.schema + .alterTable('groups') + .addColumn('scim_external_id', 'text') + .execute(); + + await db.schema + .createIndex('idx_groups_workspace_scim_external_id') + .ifNotExists() + .on('groups') + .columns(['workspace_id', 'scim_external_id']) + .where('scim_external_id', 'is not', null) + .unique() + .execute(); + + await db.schema + .alterTable('groups') + .addColumn('is_external', 'boolean', (col) => + col.notNull().defaultTo(false), + ) + .execute(); + + // Backfill: mark all non-default groups as external in workspaces with SSO group sync enabled + await sql` + UPDATE groups SET is_external = true + WHERE is_default = false + AND workspace_id IN ( + SELECT workspace_id FROM auth_providers WHERE group_sync = true + ) + `.execute(db); + + await db.schema + .alterTable('workspaces') + .addColumn('is_scim_enabled', 'boolean', (col) => + col.notNull().defaultTo(false), + ) + .execute(); +} + +export async function down(db: Kysely): Promise { + await db.schema.dropTable('scim_tokens').execute(); + + await db.schema.dropIndex('idx_users_workspace_scim_external_id').execute(); + await db.schema.alterTable('users').dropColumn('scim_external_id').execute(); + + await db.schema.dropIndex('idx_groups_workspace_scim_external_id').execute(); + await db.schema.alterTable('groups').dropColumn('scim_external_id').execute(); + + await db.schema.alterTable('groups').dropColumn('is_external').execute(); + + await db.schema + .alterTable('workspaces') + .dropColumn('is_scim_enabled') + .execute(); +} diff --git a/apps/server/src/database/repos/group/group.repo.ts b/apps/server/src/database/repos/group/group.repo.ts index 3b8c1ea76..219a9077f 100644 --- a/apps/server/src/database/repos/group/group.repo.ts +++ b/apps/server/src/database/repos/group/group.repo.ts @@ -9,7 +9,7 @@ import { } from '@docmost/db/types/entity.types'; import { ExpressionBuilder, sql } from 'kysely'; import { PaginationOptions } from '../../pagination/pagination-options'; -import { DB } from '@docmost/db/types/db'; +import { DB, Groups } from '@docmost/db/types/db'; import { DefaultGroup } from '../../../core/group/dto/create-group.dto'; import { executeWithCursorPagination } from '@docmost/db/pagination/cursor-pagination'; @@ -17,16 +17,34 @@ import { executeWithCursorPagination } from '@docmost/db/pagination/cursor-pagin export class GroupRepo { constructor(@InjectKysely() private readonly db: KyselyDB) {} + private baseFields: Array = [ + 'id', + 'name', + 'description', + 'isDefault', + 'isExternal', + 'creatorId', + 'workspaceId', + 'createdAt', + 'updatedAt', + 'deletedAt', + ]; + async findById( groupId: string, workspaceId: string, - opts?: { includeMemberCount?: boolean; trx?: KyselyTransaction }, + opts?: { + includeMemberCount?: boolean; + includeScimExternalId?: boolean; + trx?: KyselyTransaction; + }, ): Promise { const db = dbOrTx(this.db, opts?.trx); return db .selectFrom('groups') - .selectAll('groups') + .select(this.baseFields) .$if(opts?.includeMemberCount, (qb) => qb.select(this.withMemberCount)) + .$if(opts?.includeScimExternalId, (qb) => qb.select('scimExternalId')) .where('id', '=', groupId) .where('workspaceId', '=', workspaceId) .executeTakeFirst(); @@ -35,13 +53,18 @@ export class GroupRepo { async findByName( groupName: string, workspaceId: string, - opts?: { includeMemberCount?: boolean; trx?: KyselyTransaction }, + opts?: { + includeMemberCount?: boolean; + includeScimExternalId?: boolean; + trx?: KyselyTransaction; + }, ): Promise { const db = dbOrTx(this.db, opts?.trx); return db .selectFrom('groups') - .selectAll('groups') + .select(this.baseFields) .$if(opts?.includeMemberCount, (qb) => qb.select(this.withMemberCount)) + .$if(opts?.includeScimExternalId, (qb) => qb.select('scimExternalId')) .where(sql`LOWER(name)`, '=', sql`LOWER(${groupName})`) .where('workspaceId', '=', workspaceId) .executeTakeFirst(); @@ -51,8 +74,11 @@ export class GroupRepo { updatableGroup: UpdatableGroup, groupId: string, workspaceId: string, + trx?: KyselyTransaction, ): Promise { - await this.db + const db = dbOrTx(this.db, trx); + + await db .updateTable('groups') .set({ ...updatableGroup, updatedAt: new Date() }) .where('id', '=', groupId) @@ -68,7 +94,7 @@ export class GroupRepo { return db .insertInto('groups') .values(insertableGroup) - .returningAll() + .returning(this.baseFields) .executeTakeFirst(); } @@ -80,7 +106,7 @@ export class GroupRepo { return ( db .selectFrom('groups') - .selectAll() + .select(this.baseFields) // .select((eb) => this.withMemberCount(eb)) .where('isDefault', '=', true) .where('workspaceId', '=', workspaceId) @@ -106,7 +132,7 @@ export class GroupRepo { async getGroupsPaginated(workspaceId: string, pagination: PaginationOptions) { let baseQuery = this.db .selectFrom('groups') - .selectAll('groups') + .select(this.baseFields) .select((eb) => this.withMemberCount(eb)) .where('workspaceId', '=', workspaceId); diff --git a/apps/server/src/database/repos/user/user.repo.ts b/apps/server/src/database/repos/user/user.repo.ts index eaaa318ef..6f9f51cf4 100644 --- a/apps/server/src/database/repos/user/user.repo.ts +++ b/apps/server/src/database/repos/user/user.repo.ts @@ -44,6 +44,7 @@ export class UserRepo { opts?: { includePassword?: boolean; includeUserMfa?: boolean; + includeScimExternalId?: boolean; trx?: KyselyTransaction; }, ): Promise { @@ -53,6 +54,7 @@ export class UserRepo { .select(this.baseFields) .$if(opts?.includePassword, (qb) => qb.select('password')) .$if(opts?.includeUserMfa, (qb) => qb.select(this.withUserMfa)) + .$if(opts?.includeScimExternalId, (qb) => qb.select('scimExternalId')) .where('id', '=', userId) .where('workspaceId', '=', workspaceId) .executeTakeFirst(); @@ -64,6 +66,7 @@ export class UserRepo { opts?: { includePassword?: boolean; includeUserMfa?: boolean; + includeScimExternalId?: boolean; trx?: KyselyTransaction; }, ): Promise { @@ -73,6 +76,7 @@ export class UserRepo { .select(this.baseFields) .$if(opts?.includePassword, (qb) => qb.select('password')) .$if(opts?.includeUserMfa, (qb) => qb.select(this.withUserMfa)) + .$if(opts?.includeScimExternalId, (qb) => qb.select('scimExternalId')) .where(sql`LOWER(email)`, '=', sql`LOWER(${email})`) .where('workspaceId', '=', workspaceId) .executeTakeFirst(); diff --git a/apps/server/src/database/repos/workspace/workspace.repo.ts b/apps/server/src/database/repos/workspace/workspace.repo.ts index 4e3990110..408c46ba9 100644 --- a/apps/server/src/database/repos/workspace/workspace.repo.ts +++ b/apps/server/src/database/repos/workspace/workspace.repo.ts @@ -34,6 +34,7 @@ export class WorkspaceRepo { 'plan', 'enforceMfa', 'trashRetentionDays', + 'isScimEnabled', ]; constructor(@InjectKysely() private readonly db: KyselyDB) {} diff --git a/apps/server/src/database/types/db.d.ts b/apps/server/src/database/types/db.d.ts index 0890df93b..ef2c02a00 100644 --- a/apps/server/src/database/types/db.d.ts +++ b/apps/server/src/database/types/db.d.ts @@ -213,7 +213,9 @@ export interface Groups { description: string | null; id: Generated; isDefault: boolean; + isExternal: Generated; name: string; + scimExternalId: string | null; updatedAt: Generated; workspaceId: string; } @@ -338,6 +340,7 @@ export interface Users { name: string | null; password: string | null; role: string | null; + scimExternalId: string | null; settings: Json | null; timezone: string | null; updatedAt: Generated; @@ -381,6 +384,7 @@ export interface Workspaces { enforceMfa: Generated; enforceSso: Generated; hostname: string | null; + isScimEnabled: Generated; id: Generated; licenseKey: string | null; logo: string | null; @@ -410,6 +414,20 @@ export interface Notifications { createdAt: Generated; } +export interface ScimTokens { + createdAt: Generated; + deletedAt: Timestamp | null; + id: Generated; + isEnabled: Generated; + lastUsedAt: Timestamp | null; + name: string; + tokenHash: string; + tokenLastFour: string; + creatorId: string | null; + updatedAt: Generated; + workspaceId: string; +} + export interface Watchers { id: Generated; userId: string; @@ -558,6 +576,7 @@ export interface DB { pageVerifications: PageVerifications; pageVerifiers: PageVerifiers; pages: Pages; + scimTokens: ScimTokens; shares: Shares; spaceMembers: SpaceMembers; spaces: Spaces; diff --git a/apps/server/src/database/types/entity.types.ts b/apps/server/src/database/types/entity.types.ts index 481321bc4..ffac8406d 100644 --- a/apps/server/src/database/types/entity.types.ts +++ b/apps/server/src/database/types/entity.types.ts @@ -29,6 +29,7 @@ import { UserMfa as _UserMFA, UserSessions, ApiKeys, + ScimTokens, Watchers, Audit as _Audit, Templates, @@ -159,6 +160,11 @@ export type ApiKey = Selectable; export type InsertableApiKey = Insertable; export type UpdatableApiKey = Updateable>; +// Scim Tokens +export type ScimToken = Selectable; +export type InsertableScimToken = Insertable; +export type UpdatableScimToken = Updateable>; + // Page Embedding export type PageEmbedding = Selectable; export type InsertablePageEmbedding = Insertable; diff --git a/apps/server/src/ee b/apps/server/src/ee index fabe27298..109829076 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit fabe2729879e0543518f0c42bfdb3b403afe3c4a +Subproject commit 109829076c8d81f6d77836820a5caa63ae8d073f diff --git a/apps/server/src/main.ts b/apps/server/src/main.ts index d47bf547e..7e82b6d92 100644 --- a/apps/server/src/main.ts +++ b/apps/server/src/main.ts @@ -50,6 +50,22 @@ async function bootstrap() { await app.register(fastifyMultipart); await app.register(fastifyCookie); + app + .getHttpAdapter() + .getInstance() + .addContentTypeParser( + 'application/scim+json', + { parseAs: 'string' }, + (_, body, done) => { + try { + const json = JSON.parse(body.toString()); + done(null, json); + } catch (err: any) { + done(err); + } + }, + ); + app .getHttpAdapter() .getInstance() diff --git a/package.json b/package.json index 589721623..cd2fb1279 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,8 @@ "packageManager": "pnpm@10.4.0", "pnpm": { "patchedDependencies": { - "react-arborist@3.4.0": "patches/react-arborist@3.4.0.patch" + "react-arborist@3.4.0": "patches/react-arborist@3.4.0.patch", + "scimmy@1.3.5": "patches/scimmy@1.3.5.patch" }, "overrides": { "prosemirror-changeset": "2.4.0", diff --git a/patches/@tiptap__core.patch b/patches/@tiptap__core.patch deleted file mode 100644 index 58f580c8a..000000000 --- a/patches/@tiptap__core.patch +++ /dev/null @@ -1,105 +0,0 @@ -diff --git a/dist/index.cjs b/dist/index.cjs -index 01d6999642c5ae990083798a1bf0ef87068e4192..891b13c6901f28a6ab413c6dbae0ea726a76a196 100644 ---- a/dist/index.cjs -+++ b/dist/index.cjs -@@ -5463,7 +5463,10 @@ var ResizableNodeView = class { - this.container.classList.remove(this.classNames.resizing); - } - document.removeEventListener("mousemove", this.handleMouseMove); -+ document.removeEventListener("touchmove", this.handleTouchMove); - document.removeEventListener("mouseup", this.handleMouseUp); -+ document.removeEventListener("touchend", this.handleMouseUp); -+ window.removeEventListener("blur", this.handleMouseUp); - document.removeEventListener("keydown", this.handleKeyDown); - document.removeEventListener("keyup", this.handleKeyUp); - }; -@@ -5593,7 +5596,10 @@ var ResizableNodeView = class { - this.container.classList.remove(this.classNames.resizing); - } - document.removeEventListener("mousemove", this.handleMouseMove); -+ document.removeEventListener("touchmove", this.handleTouchMove); - document.removeEventListener("mouseup", this.handleMouseUp); -+ document.removeEventListener("touchend", this.handleMouseUp); -+ window.removeEventListener("blur", this.handleMouseUp); - document.removeEventListener("keydown", this.handleKeyDown); - document.removeEventListener("keyup", this.handleKeyUp); - this.isResizing = false; -@@ -5796,6 +5802,8 @@ var ResizableNodeView = class { - document.addEventListener("mousemove", this.handleMouseMove); - document.addEventListener("touchmove", this.handleTouchMove); - document.addEventListener("mouseup", this.handleMouseUp); -+ document.addEventListener("touchend", this.handleMouseUp); -+ window.addEventListener("blur", this.handleMouseUp); - document.addEventListener("keydown", this.handleKeyDown); - document.addEventListener("keyup", this.handleKeyUp); - } -diff --git a/dist/index.js b/dist/index.js -index 6f357a03b038abeb5ed86967b7fc7c3e5eb1d2d6..2d2742532860821984e1ba82625821504538ebbe 100644 ---- a/dist/index.js -+++ b/dist/index.js -@@ -5330,7 +5330,10 @@ var ResizableNodeView = class { - this.container.classList.remove(this.classNames.resizing); - } - document.removeEventListener("mousemove", this.handleMouseMove); -+ document.removeEventListener("touchmove", this.handleTouchMove); - document.removeEventListener("mouseup", this.handleMouseUp); -+ document.removeEventListener("touchend", this.handleMouseUp); -+ window.removeEventListener("blur", this.handleMouseUp); - document.removeEventListener("keydown", this.handleKeyDown); - document.removeEventListener("keyup", this.handleKeyUp); - }; -@@ -5460,7 +5463,10 @@ var ResizableNodeView = class { - this.container.classList.remove(this.classNames.resizing); - } - document.removeEventListener("mousemove", this.handleMouseMove); -+ document.removeEventListener("touchmove", this.handleTouchMove); - document.removeEventListener("mouseup", this.handleMouseUp); -+ document.removeEventListener("touchend", this.handleMouseUp); -+ window.removeEventListener("blur", this.handleMouseUp); - document.removeEventListener("keydown", this.handleKeyDown); - document.removeEventListener("keyup", this.handleKeyUp); - this.isResizing = false; -@@ -5663,6 +5669,8 @@ var ResizableNodeView = class { - document.addEventListener("mousemove", this.handleMouseMove); - document.addEventListener("touchmove", this.handleTouchMove); - document.addEventListener("mouseup", this.handleMouseUp); -+ document.addEventListener("touchend", this.handleMouseUp); -+ window.addEventListener("blur", this.handleMouseUp); - document.addEventListener("keydown", this.handleKeyDown); - document.addEventListener("keyup", this.handleKeyUp); - } -diff --git a/src/lib/ResizableNodeView.ts b/src/lib/ResizableNodeView.ts -index f13e210b0aa46aefe7c31105deee3d2aa8a26cd5..9bac138dbf17c6ae6c3c129cbedb3a81bd39b60c 100644 ---- a/src/lib/ResizableNodeView.ts -+++ b/src/lib/ResizableNodeView.ts -@@ -523,7 +523,10 @@ export class ResizableNodeView { - } - - document.removeEventListener('mousemove', this.handleMouseMove) -+ document.removeEventListener('touchmove', this.handleTouchMove) - document.removeEventListener('mouseup', this.handleMouseUp) -+ document.removeEventListener('touchend', this.handleMouseUp) -+ window.removeEventListener('blur', this.handleMouseUp) - document.removeEventListener('keydown', this.handleKeyDown) - document.removeEventListener('keyup', this.handleKeyUp) - this.isResizing = false -@@ -774,6 +777,8 @@ export class ResizableNodeView { - document.addEventListener('mousemove', this.handleMouseMove) - document.addEventListener('touchmove', this.handleTouchMove) - document.addEventListener('mouseup', this.handleMouseUp) -+ document.addEventListener('touchend', this.handleMouseUp) -+ window.addEventListener('blur', this.handleMouseUp) - document.addEventListener('keydown', this.handleKeyDown) - document.addEventListener('keyup', this.handleKeyUp) - } -@@ -859,7 +864,10 @@ export class ResizableNodeView { - - // Clean up document-level listeners - document.removeEventListener('mousemove', this.handleMouseMove) -+ document.removeEventListener('touchmove', this.handleTouchMove) - document.removeEventListener('mouseup', this.handleMouseUp) -+ document.removeEventListener('touchend', this.handleMouseUp) -+ window.removeEventListener('blur', this.handleMouseUp) - document.removeEventListener('keydown', this.handleKeyDown) - document.removeEventListener('keyup', this.handleKeyUp) - } diff --git a/patches/scimmy@1.3.5.patch b/patches/scimmy@1.3.5.patch new file mode 100644 index 000000000..fd2060346 --- /dev/null +++ b/patches/scimmy@1.3.5.patch @@ -0,0 +1,23 @@ +diff --git a/dist/cjs/lib/messages.cjs b/dist/cjs/lib/messages.cjs +index e74b8f52137e3267f3d065c4210a1114c4f32dd1..5740606b18851c0ac4f55cfa333152359e0ad135 100644 +--- a/dist/cjs/lib/messages.cjs ++++ b/dist/cjs/lib/messages.cjs +@@ -502,10 +502,15 @@ class PatchOp { + } + } + } +- ++ ++ /** Reason: Commented out to avoid failing patch requests when filters don't match. ++ * Some IdPs send patch paths like `addresses[type eq "work"].country` even if no such address exists. We can't always decide what the end user IdPs send. ++ * Since we manually control patch application, we safely ignore these cases. ++ * example error: "noTarget","detail":"Filter 'addresses[type eq \"work\"].country' does not match any values for 'add' op of operation 5 in PatchOp request body ++ */ + // No targets, bail out! +- if (targets.length === 0 && op !== "remove") +- throw new lib_types.default.Error(400, "noTarget", `Filter '${path}' does not match any values for '${op}' op of operation ${index} in PatchOp request body`); ++ // if (targets.length === 0 && op !== "remove") ++ // throw new lib_types.default.Error(400, "noTarget", `Filter '${path}' does not match any values for '${op}' op of operation ${index} in PatchOp request body`); + + /** + * @typedef {Object} PatchOpDetails diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4ceb29771..3985bc750 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,6 +46,9 @@ patchedDependencies: react-arborist@3.4.0: hash: 419b3b02e24afe928cc006a006f6e906666aff19aa6fd7daaa788ccc2202678a path: patches/react-arborist@3.4.0.patch + scimmy@1.3.5: + hash: 775d80f86830b2c5dd1a250c9802c10f8fc3da3c7898373de5aa0c23993d1673 + path: patches/scimmy@1.3.5.patch importers: @@ -701,6 +704,9 @@ importers: sanitize-filename: specifier: 1.6.3 version: 1.6.3 + scimmy: + specifier: 1.3.5 + version: 1.3.5(patch_hash=775d80f86830b2c5dd1a250c9802c10f8fc3da3c7898373de5aa0c23993d1673) socket.io: specifier: ^4.8.3 version: 4.8.3 @@ -9604,6 +9610,10 @@ packages: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} + scimmy@1.3.5: + resolution: {integrity: sha512-JTrUOoqH1gMH2zZhgk01hGgY7cH9v4qUli5b3OGVVOzjAwY8h4Z2mSNH8kXjW2pz8ypzpiRuMEtFGBaWQWJz7w==} + engines: {node: '>=16'} + secure-json-parse@4.0.0: resolution: {integrity: sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==} @@ -20944,6 +20954,8 @@ snapshots: ajv-formats: 2.1.1(ajv@8.18.0) ajv-keywords: 5.1.0(ajv@8.18.0) + scimmy@1.3.5(patch_hash=775d80f86830b2c5dd1a250c9802c10f8fc3da3c7898373de5aa0c23993d1673): {} + secure-json-parse@4.0.0: {} selderee@0.11.0: From c247d4c1e33baec9772d4497a7b452dc16f2e91f Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Fri, 1 May 2026 14:56:39 +0100 Subject: [PATCH 16/46] feat(ee): PDF import (#2142) * feat: replace pdfjs-dist with firecrawl-pdf-inspector * use modified firecrawl-pdf-inspector * feat: pdf import * increase single file upload size limit * use npm package * sync * update package --- apps/client/src/ee/features.ts | 1 + .../page/components/page-import-modal.tsx | 30 +++- apps/server/package.json | 2 +- apps/server/src/common/features.ts | 1 + .../integrations/import/import.controller.ts | 5 +- .../import/services/import.service.ts | 51 +++++- pnpm-lock.yaml | 145 ++---------------- 7 files changed, 93 insertions(+), 142 deletions(-) diff --git a/apps/client/src/ee/features.ts b/apps/client/src/ee/features.ts index a9ab8b0d5..cacf851f2 100644 --- a/apps/client/src/ee/features.ts +++ b/apps/client/src/ee/features.ts @@ -8,6 +8,7 @@ export const Feature = { AI: 'ai', CONFLUENCE_IMPORT: 'import:confluence', DOCX_IMPORT: 'import:docx', + PDF_IMPORT: 'import:pdf', ATTACHMENT_INDEXING: 'attachment:indexing', SECURITY_SETTINGS: 'security:settings', MCP: 'mcp', diff --git a/apps/client/src/features/page/components/page-import-modal.tsx b/apps/client/src/features/page/components/page-import-modal.tsx index df6691d55..c1c12dc43 100644 --- a/apps/client/src/features/page/components/page-import-modal.tsx +++ b/apps/client/src/features/page/components/page-import-modal.tsx @@ -12,6 +12,7 @@ import { IconCheck, IconFileCode, IconFileTypeDocx, + IconFileTypePdf, IconFileTypeZip, IconMarkdown, IconX, @@ -90,12 +91,14 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) { const markdownFileRef = useRef<() => void>(null); const htmlFileRef = useRef<() => void>(null); const docxFileRef = useRef<() => void>(null); + const pdfFileRef = useRef<() => void>(null); const notionFileRef = useRef<() => void>(null); const confluenceFileRef = useRef<() => void>(null); const zipFileRef = useRef<() => void>(null); const canUseConfluence = useHasFeature(Feature.CONFLUENCE_IMPORT); const canUseDocx = useHasFeature(Feature.DOCX_IMPORT); + const canUsePdf = useHasFeature(Feature.PDF_IMPORT); const upgradeLabel = useUpgradeLabel(); const handleZipUpload = async (selectedFile: File, source: string) => { @@ -244,7 +247,7 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) { }, 3000); }, [fileTaskId]); - const maxSingleFileSize = bytes("20mb"); + const maxSingleFileSize = bytes("30mb"); const handleFileUpload = async (selectedFiles: File[]) => { if (!selectedFiles) { @@ -298,6 +301,7 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) { if (markdownFileRef.current) markdownFileRef.current(); if (htmlFileRef.current) htmlFileRef.current(); if (docxFileRef.current) docxFileRef.current(); + if (pdfFileRef.current) pdfFileRef.current(); const pageCountText = pageCount === 1 ? `1 ${t("page")}` : `${pageCount} ${t("pages")}`; @@ -378,6 +382,30 @@ function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) { )} + + {(props) => ( + + + + )} + + handleZipUpload(file, "notion")} accept="application/zip" diff --git a/apps/server/package.json b/apps/server/package.json index 794924876..c0eeddf33 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -37,6 +37,7 @@ "@aws-sdk/lib-storage": "3.1037.0", "@aws-sdk/s3-request-presigner": "3.1037.0", "@clickhouse/client": "^1.18.2", + "@docmost/pdf-inspector": "1.9.4", "@fastify/cookie": "^11.0.2", "@fastify/multipart": "^10.0.0", "@fastify/static": "^9.1.3", @@ -100,7 +101,6 @@ "p-limit": "^7.3.0", "passport-google-oauth20": "^2.0.0", "passport-jwt": "^4.0.1", - "pdfjs-dist": "^5.5.207", "pg-tsquery": "^8.4.2", "pgvector": "^0.2.1", "pino-http": "^11.0.0", diff --git a/apps/server/src/common/features.ts b/apps/server/src/common/features.ts index 38f226a86..c5fd9a200 100644 --- a/apps/server/src/common/features.ts +++ b/apps/server/src/common/features.ts @@ -8,6 +8,7 @@ export const Feature = { AI: 'ai', CONFLUENCE_IMPORT: 'import:confluence', DOCX_IMPORT: 'import:docx', + PDF_IMPORT: 'import:pdf', ATTACHMENT_INDEXING: 'attachment:indexing', SECURITY_SETTINGS: 'security:settings', MCP: 'mcp', diff --git a/apps/server/src/integrations/import/import.controller.ts b/apps/server/src/integrations/import/import.controller.ts index 7ee325e5f..cd2341ea5 100644 --- a/apps/server/src/integrations/import/import.controller.ts +++ b/apps/server/src/integrations/import/import.controller.ts @@ -51,9 +51,9 @@ export class ImportController { @AuthUser() user: User, @AuthWorkspace() workspace: Workspace, ) { - const validFileExtensions = ['.md', '.html', '.docx']; + const validFileExtensions = ['.md', '.html', '.docx', '.pdf']; - const maxFileSize = bytes('20mb'); + const maxFileSize = bytes('30mb'); let file = null; try { @@ -102,6 +102,7 @@ export class ImportController { '.md': 'markdown', '.html': 'html', '.docx': 'docx', + '.pdf': 'pdf', }; if (createdPage) { diff --git a/apps/server/src/integrations/import/services/import.service.ts b/apps/server/src/integrations/import/services/import.service.ts index 0eb3ae40d..1eb10ca80 100644 --- a/apps/server/src/integrations/import/services/import.service.ts +++ b/apps/server/src/integrations/import/services/import.service.ts @@ -63,7 +63,10 @@ export class ImportService { let createdPage = null; // For DOCX, we need the page ID upfront so images can reference it - const pageId = fileExtension === '.docx' ? uuid7() : undefined; + const pageId = + fileExtension === '.docx' || fileExtension === '.pdf' + ? uuid7() + : undefined; try { if (fileExtension.endsWith('.md')) { @@ -78,6 +81,14 @@ export class ImportService { pageId, userId, ); + } else if (fileExtension.endsWith('.pdf')) { + prosemirrorState = await this.processPdf( + fileBuffer, + workspaceId, + spaceId, + pageId, + userId, + ); } } catch (err) { const message = 'Error processing file content'; @@ -156,7 +167,7 @@ export class ImportService { let DocxImportModule: any; try { // eslint-disable-next-line @typescript-eslint/no-require-imports - DocxImportModule = require('./../../../ee/docx-import/docx-import.service'); + DocxImportModule = require('./../../../ee/document-import/docx-import.service'); } catch (err) { this.logger.error( 'DOCX import requested but EE module not bundled in this build', @@ -182,6 +193,42 @@ export class ImportService { return this.processHTML(html); } + async processPdf( + fileBuffer: Buffer, + workspaceId: string, + spaceId: string, + pageId: string, + userId: string, + ): Promise { + let PdfImportModule: any; + try { + // eslint-disable-next-line @typescript-eslint/no-require-imports + PdfImportModule = require('./../../../ee/document-import/pdf-import.service'); + } catch (err) { + this.logger.error( + 'PDF import requested but EE module not bundled in this build', + ); + throw new BadRequestException( + 'This feature requires a valid enterprise license.', + ); + } + + const pdfImportService = this.moduleRef.get( + PdfImportModule.PdfImportService, + { strict: false }, + ); + + const html = await pdfImportService.convertPdfToHtml( + fileBuffer, + workspaceId, + spaceId, + pageId, + userId, + ); + + return this.processHTML(html); + } + async createYdoc(prosemirrorJson: any): Promise { if (prosemirrorJson) { // this.logger.debug(`Converting prosemirror json state to ydoc`); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3985bc750..f6e1a7572 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -482,6 +482,9 @@ importers: '@clickhouse/client': specifier: ^1.18.2 version: 1.18.2 + '@docmost/pdf-inspector': + specifier: 1.9.4 + version: 1.9.4 '@fastify/cookie': specifier: ^11.0.2 version: 11.0.2 @@ -671,9 +674,6 @@ importers: passport-jwt: specifier: ^4.0.1 version: 4.0.1 - pdfjs-dist: - specifier: ^5.5.207 - version: 5.5.207 pg-tsquery: specifier: ^8.4.2 version: 8.4.2 @@ -1826,6 +1826,9 @@ packages: resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} engines: {node: '>=18'} + '@docmost/pdf-inspector@1.9.4': + resolution: {integrity: sha512-G5DNyDtLNxybTXWakqi7PuOEuSb/A2ZjDlv2WCkOkiHszPeILdrC+G0a4e4UP10yxvzuLfb23pJ5jy8fUSYZPw==} + '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} @@ -2762,76 +2765,6 @@ packages: cpu: [x64] os: [win32] - '@napi-rs/canvas-android-arm64@0.1.97': - resolution: {integrity: sha512-V1c/WVw+NzH8vk7ZK/O8/nyBSCQimU8sfMsB/9qeSvdkGKNU7+mxy/bIF0gTgeBFmHpj30S4E9WHMSrxXGQuVQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [android] - - '@napi-rs/canvas-darwin-arm64@0.1.97': - resolution: {integrity: sha512-ok+SCEF4YejcxuJ9Rm+WWunHHpf2HmiPxfz6z1a/NFQECGXtsY7A4B8XocK1LmT1D7P174MzwPF9Wy3AUAwEPw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@napi-rs/canvas-darwin-x64@0.1.97': - resolution: {integrity: sha512-PUP6e6/UGlclUvAQNnuXCcnkpdUou6VYZfQOQxExLp86epOylmiwLkqXIvpFmjoTEDmPmXrI+coL/9EFU1gKPA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.97': - resolution: {integrity: sha512-XyXH2L/cic8eTNtbrXCcvqHtMX/nEOxN18+7rMrAM2XtLYC/EB5s0wnO1FsLMWmK+04ZSLN9FBGipo7kpIkcOw==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@napi-rs/canvas-linux-arm64-gnu@0.1.97': - resolution: {integrity: sha512-Kuq/M3djq0K8ktgz6nPlK7Ne5d4uWeDxPpyKWOjWDK2RIOhHVtLtyLiJw2fuldw7Vn4mhw05EZXCEr4Q76rs9w==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/canvas-linux-arm64-musl@0.1.97': - resolution: {integrity: sha512-kKmSkQVnWeqg7qdsiXvYxKhAFuHz3tkBjW/zyQv5YKUPhotpaVhpBGv5LqCngzyuRV85SXoe+OFj+Tv0a0QXkQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/canvas-linux-riscv64-gnu@0.1.97': - resolution: {integrity: sha512-Jc7I3A51jnEOIAXeLsN/M/+Z28LUeakcsXs07FLq9prXc0eYOtVwsDEv913Gr+06IRo34gJJVgT0TXvmz+N2VA==} - engines: {node: '>= 10'} - cpu: [riscv64] - os: [linux] - - '@napi-rs/canvas-linux-x64-gnu@0.1.97': - resolution: {integrity: sha512-iDUBe7AilfuBSRbSa8/IGX38Mf+iCSBqoVKLSQ5XaY2JLOaqz1TVyPFEyIck7wT6mRQhQt5sN6ogfjIDfi74tg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/canvas-linux-x64-musl@0.1.97': - resolution: {integrity: sha512-AKLFd/v0Z5fvgqBDqhvqtAdx+fHMJ5t9JcUNKq4FIZ5WH+iegGm8HPdj00NFlCSnm83Fp3Ln8I2f7uq1aIiWaA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/canvas-win32-arm64-msvc@0.1.97': - resolution: {integrity: sha512-u883Yr6A6fO7Vpsy9YE4FVCIxzzo5sO+7pIUjjoDLjS3vQaNMkVzx5bdIpEL+ob+gU88WDK4VcxYMZ6nmnoX9A==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@napi-rs/canvas-win32-x64-msvc@0.1.97': - resolution: {integrity: sha512-sWtD2EE3fV0IzN+iiQUqr/Q1SwqWhs2O1FKItFlxtdDkikpEj5g7DKQpY3x55H/MAOnL8iomnlk3mcEeGiUMoQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@napi-rs/canvas@0.1.97': - resolution: {integrity: sha512-8cFniXvrIEnVwuNSRCW9wirRZbHvrD3JVujdS2P5n5xiJZNZMOZcfOvJ1pb66c7jXMKHHglJEDVJGbm8XWFcXQ==} - engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -8551,9 +8484,6 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-readable-to-web-readable-stream@0.4.2: - resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==} - node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} @@ -8845,10 +8775,6 @@ packages: pause@0.0.1: resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} - pdfjs-dist@5.5.207: - resolution: {integrity: sha512-WMqqw06w1vUt9ZfT0gOFhMf3wHsWhaCrxGrckGs5Cci6ybDW87IvPaOd2pnBwT6BJuP/CzXDZxjFgmSULLdsdw==} - engines: {node: '>=20.19.0 || >=22.13.0 || >=24'} - peberminta@0.9.0: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} @@ -10328,6 +10254,7 @@ packages: uuid@10.0.0: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true uuid@11.1.0: @@ -12193,6 +12120,8 @@ snapshots: '@csstools/css-tokenizer@3.0.3': {} + '@docmost/pdf-inspector@1.9.4': {} + '@emnapi/core@1.8.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -13193,54 +13122,6 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2': optional: true - '@napi-rs/canvas-android-arm64@0.1.97': - optional: true - - '@napi-rs/canvas-darwin-arm64@0.1.97': - optional: true - - '@napi-rs/canvas-darwin-x64@0.1.97': - optional: true - - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.97': - optional: true - - '@napi-rs/canvas-linux-arm64-gnu@0.1.97': - optional: true - - '@napi-rs/canvas-linux-arm64-musl@0.1.97': - optional: true - - '@napi-rs/canvas-linux-riscv64-gnu@0.1.97': - optional: true - - '@napi-rs/canvas-linux-x64-gnu@0.1.97': - optional: true - - '@napi-rs/canvas-linux-x64-musl@0.1.97': - optional: true - - '@napi-rs/canvas-win32-arm64-msvc@0.1.97': - optional: true - - '@napi-rs/canvas-win32-x64-msvc@0.1.97': - optional: true - - '@napi-rs/canvas@0.1.97': - optionalDependencies: - '@napi-rs/canvas-android-arm64': 0.1.97 - '@napi-rs/canvas-darwin-arm64': 0.1.97 - '@napi-rs/canvas-darwin-x64': 0.1.97 - '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.97 - '@napi-rs/canvas-linux-arm64-gnu': 0.1.97 - '@napi-rs/canvas-linux-arm64-musl': 0.1.97 - '@napi-rs/canvas-linux-riscv64-gnu': 0.1.97 - '@napi-rs/canvas-linux-x64-gnu': 0.1.97 - '@napi-rs/canvas-linux-x64-musl': 0.1.97 - '@napi-rs/canvas-win32-arm64-msvc': 0.1.97 - '@napi-rs/canvas-win32-x64-msvc': 0.1.97 - optional: true - '@napi-rs/wasm-runtime@0.2.12': dependencies: '@emnapi/core': 1.8.1 @@ -19627,9 +19508,6 @@ snapshots: node-int64@0.4.0: {} - node-readable-to-web-readable-stream@0.4.2: - optional: true - node-releases@2.0.27: {} nodemailer@8.0.5: {} @@ -19981,11 +19859,6 @@ snapshots: pause@0.0.1: {} - pdfjs-dist@5.5.207: - optionalDependencies: - '@napi-rs/canvas': 0.1.97 - node-readable-to-web-readable-stream: 0.4.2 - peberminta@0.9.0: {} pend@1.2.0: {} From b74ca00bfd121211c0e15240235f038ab15387f8 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Fri, 1 May 2026 14:57:32 +0100 Subject: [PATCH 17/46] sync --- apps/server/src/ee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/server/src/ee b/apps/server/src/ee index 109829076..211783940 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit 109829076c8d81f6d77836820a5caa63ae8d073f +Subproject commit 211783940cae7f6809eadace1c232f1db5c9fc80 From 17f3158a3b09adf1978aecdefb15679c05645744 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Fri, 1 May 2026 20:00:20 +0100 Subject: [PATCH 18/46] update aws packages --- apps/server/package.json | 6 +- pnpm-lock.yaml | 279 ++++++++++++++++++++------------------- 2 files changed, 143 insertions(+), 142 deletions(-) diff --git a/apps/server/package.json b/apps/server/package.json index c0eeddf33..f9cbdc04a 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -33,9 +33,9 @@ "@ai-sdk/google": "^3.0.52", "@ai-sdk/openai": "^3.0.47", "@ai-sdk/openai-compatible": "^2.0.37", - "@aws-sdk/client-s3": "3.1037.0", - "@aws-sdk/lib-storage": "3.1037.0", - "@aws-sdk/s3-request-presigner": "3.1037.0", + "@aws-sdk/client-s3": "3.1040.0", + "@aws-sdk/lib-storage": "3.1040.0", + "@aws-sdk/s3-request-presigner": "3.1040.0", "@clickhouse/client": "^1.18.2", "@docmost/pdf-inspector": "1.9.4", "@fastify/cookie": "^11.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6e1a7572..a3ca7b679 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -471,14 +471,14 @@ importers: specifier: ^2.0.37 version: 2.0.37(zod@4.3.6) '@aws-sdk/client-s3': - specifier: 3.1037.0 - version: 3.1037.0 + specifier: 3.1040.0 + version: 3.1040.0 '@aws-sdk/lib-storage': - specifier: 3.1037.0 - version: 3.1037.0(@aws-sdk/client-s3@3.1037.0) + specifier: 3.1040.0 + version: 3.1040.0(@aws-sdk/client-s3@3.1040.0) '@aws-sdk/s3-request-presigner': - specifier: 3.1037.0 - version: 3.1037.0 + specifier: 3.1040.0 + version: 3.1040.0 '@clickhouse/client': specifier: ^1.18.2 version: 1.18.2 @@ -941,55 +941,55 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-s3@3.1037.0': - resolution: {integrity: sha512-DBmA1jAW8ST6C4srBxeL1/RLIir/d8WOm4s4mi59mGp6mBktHM59Kwb7GuURaCO60cotuce5zr0sKpMLPcBQyA==} + '@aws-sdk/client-s3@3.1040.0': + resolution: {integrity: sha512-Ldfby1xDrlZwNY2NxP9pwdVrf8sqHbGBKP1UkoG/oWcePGlGhjY8iVwy8hRy9f1EQfHVFWIFunwHaPQxhYTnWQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.974.5': - resolution: {integrity: sha512-lMPlYlYfQdNZhlkJgnkmESwrY+hNh3PljmZ+37oAqLNdJ6rnILAwFSyc6B3bJeDOtMORNnMQIej0aTRuOlDyhQ==} + '@aws-sdk/core@3.974.7': + resolution: {integrity: sha512-YhRC90ofz5oolTJZlA8voU/oUrCB2azi8Usx51k8hhB5LpWbYQMMXKUqSqkoL0Cru+RQJgWTHpAfEDDIwfUhJw==} engines: {node: '>=20.0.0'} '@aws-sdk/crc64-nvme@3.972.7': resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.31': - resolution: {integrity: sha512-X/yGB73LmDW/6MdDJGCDzZBUXnM3ys4vs9l+5ZTJmiEswDdP1OjeoAFlFjVGS9o4KB2wZWQ9KOfdVNSSK6Ep3w==} + '@aws-sdk/credential-provider-env@3.972.33': + resolution: {integrity: sha512-bJV7eViSJV6GSuuN+VIdNVPdwPsNSf75BiC2v5alPrjR/OCcqgKwSZInKbDFz9mNeizldsyf67jt6YSIiv53Cw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.33': - resolution: {integrity: sha512-c0ZF+lwoWVvX5iCaGKL5T/4DnIw88CGqxA0BcBs3U86mIp5EZYPVg+KSPkMXOyokmADvNewiMUfSG2uFwjRp0g==} + '@aws-sdk/credential-provider-http@3.972.35': + resolution: {integrity: sha512-x/BQGEIdq0oI+4WxLjKmnQvT7CnF9r8ezdGt7wXwxb7ckHXQz0Zmgxt8v3Ne0JaT3R5YefmuybHX6E8EnsDXyA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.35': - resolution: {integrity: sha512-jsU4u/cRkKFLKQS0k918FQ27fzXLG5ENiLWQMYE6581zLeI2hWh04ptlrvZMB3wJT/5d+vSzJk74X1CMFr4y8Q==} + '@aws-sdk/credential-provider-ini@3.972.37': + resolution: {integrity: sha512-eUTpmWfd/BKsq9medhCRcu+GRAhFP2Zrn7/2jKDHHOOjCkhrMoTp/t4cEthqFoG7gE0VGp5wUxrXTdvBCmSmJg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.35': - resolution: {integrity: sha512-5oa3j0cA50jPqgNhZ9XdJVopuzUf1klRb28/2MfLYWWiPi9DRVvbrBWT+DidbHTT36520VuXZJahQwR+YgSjrg==} + '@aws-sdk/credential-provider-login@3.972.37': + resolution: {integrity: sha512-Ty68y8ISSC+g5Q3D0K8uAaoINwvfaOslnNpsF/LgVUxyosYXHawcK2yV4HLXDVugiTTYLQfJfcw0ce5meAGkKw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.36': - resolution: {integrity: sha512-4nT2T8Z7vH8KE9EdjEsuIlHpZSlcaK2PrKbQBjuUGU46BCCzF3WvP0u0Uiosni3Ykmmn4rWLVawoOCLotUtCbg==} + '@aws-sdk/credential-provider-node@3.972.38': + resolution: {integrity: sha512-BQ9XYnBDVxR2HuV5huXYQYF/PZMTsY+EnwfGnCU2cA8Zw63XpkOtPY8WqiMIZMQCrKPQQEiFURS/o9CIolRLqg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.31': - resolution: {integrity: sha512-eKeT4MXumpBJsrDLCYcSzIkFPVTFn/es7It2oogp2OhU/ic7P/+xzFpQx9ZhwtXS57Mc5S42BPWi7lHmvs/nYg==} + '@aws-sdk/credential-provider-process@3.972.33': + resolution: {integrity: sha512-yfjGksI9WQbdMObb0VeLXqzTLI+a0qXLJT9gCDiv0+X/xjPpI3mTz6a5FibrhpuEKIe0gSgvs3MaoFZy5cx4WA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.35': - resolution: {integrity: sha512-bCuBdfnj0KGDMdLp6utMTLiJcFN2ek9EgZinxQZZSc3FxjJ/HSqeqab2cjbnoNfy8RM6suDCsRkmVY1izp9I+A==} + '@aws-sdk/credential-provider-sso@3.972.37': + resolution: {integrity: sha512-fpwE+20ntpp3i9Xb9vUuQfXLDKYHH+5I2V+ZG96SX1nBzrruhy10RXDgmN7t1etOz3c55stlA3TeQASUA451NQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.35': - resolution: {integrity: sha512-swW6Bwvl8lanyEMtZOWE/oR6yqcRQH4HTQZUVsnDVgoXvRjRywpYpLv2BWwjUFyjPrqsdX6FeTkf4tMSe/qFTQ==} + '@aws-sdk/credential-provider-web-identity@3.972.37': + resolution: {integrity: sha512-aryawqyebf+3WhAFNHfF62rekFpYtVcVN7dQ89qnAWsa4n5hJst8qBG6gXC24WHtW7Nnhkf9ScYnjwo0Brn3bw==} engines: {node: '>=20.0.0'} - '@aws-sdk/lib-storage@3.1037.0': - resolution: {integrity: sha512-ZFg5Vf4RKS48xTm7DfXTeR0Rvn/Fcu6YFdRygGnvhA+gW3W0WtsRqM1CzkWevYBztdUUAsZqtGbMj9Eu0OaeEg==} + '@aws-sdk/lib-storage@3.1040.0': + resolution: {integrity: sha512-4cPpxs/2Gnzm7dKn2EBTPf0/rPNM5BoOleWSNn03QPGkELPDg9VmVwUhXZsDcb8k8F9wm5ft9n7BSNXKAjoIWw==} engines: {node: '>=20.0.0'} peerDependencies: - '@aws-sdk/client-s3': ^3.1037.0 + '@aws-sdk/client-s3': ^3.1040.0 '@aws-sdk/middleware-bucket-endpoint@3.972.10': resolution: {integrity: sha512-Vbc2frZH7wXlMNd+ZZSXUEs/l1Sv8Jj4zUnIfwrYF5lwaLdXHZ9xx4U3rjUcaye3HRhFVc+E5DbBxpRAbB16BA==} @@ -999,8 +999,8 @@ packages: resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.974.13': - resolution: {integrity: sha512-b6QUe2hQX9XsnCzp6mtzVaERhganDKeb8lmGL6pVhr7rRVH9S9keDFW7uKytuuqmcY5943FixoGqn/QL+sbUBA==} + '@aws-sdk/middleware-flexible-checksums@3.974.15': + resolution: {integrity: sha512-j4Zp7rA1HfhDTteICnx/tPax4N/v5wmytgguXExUGyEwQ8Ug4EBA4kjp9puFAN1UZoBVpxoiXMiuTFvjaHjeEw==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-host-header@3.972.10': @@ -1019,36 +1019,36 @@ packages: resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.34': - resolution: {integrity: sha512-/UL96JKjsjdodcRRMKl99tLQvK6Oi9ptLC9iU1yiTF/ruaDX0mtBBtnLNZDxIZRJOCVOtB49ed1YaTadqygk8Q==} + '@aws-sdk/middleware-sdk-s3@3.972.36': + resolution: {integrity: sha512-YhPix+0x/MdQrb1Ug1GDKeS5fqylIy+naz800asX8II4jqfTk2KY2KhmmYCwZcky8YWtRQQwWCGdoqeAnip8Uw==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-ssec@3.972.10': resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.35': - resolution: {integrity: sha512-hOFWNOjVmOocpRlrU04nYxjMOeoe0Obu5AXEuhB8zblMCPl3cG1hdluQCZERRKFyhMQjwZnDbhSHjoMUjetFGw==} + '@aws-sdk/middleware-user-agent@3.972.37': + resolution: {integrity: sha512-N1oNpdiLoVAWYD3WFBnUi3LlfoDA06ZHo4ozyjbsJNLvILzvt//0CnR8N+CZ0NWeYgVB/5V59ivixHCWCx2ALw==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.997.3': - resolution: {integrity: sha512-SivE6GP228IVgfsrr2c/vqTg95X0Qj39Yw4uIrcddpkUzIltNMoNOR62leHOLhODfjv9K8X2mPTwS69A5kT0nQ==} + '@aws-sdk/nested-clients@3.997.5': + resolution: {integrity: sha512-jGFr6DxtcMTmzOkG/a0jCZYv4BBDmeNYVeO+/memSoDkYCJu4Y58xviYmzwJfYyIVSts+X/BVjJm1uGBnwHEMg==} engines: {node: '>=20.0.0'} '@aws-sdk/region-config-resolver@3.972.13': resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} engines: {node: '>=20.0.0'} - '@aws-sdk/s3-request-presigner@3.1037.0': - resolution: {integrity: sha512-rZQS8DxrqPYXzOvaoysf6L4fHmgFbndZz3GfUMhlHG1iWmcQqH7v0AGhpjyNBY3cYAX8+CAkOkD4VUrntnHNbQ==} + '@aws-sdk/s3-request-presigner@3.1040.0': + resolution: {integrity: sha512-AmesZGG/B5sDIiWahyY11fOkXSsuHc7LciE88YFURehMVSdEORo2Vzz1d2kBgmJG9oar5Vmmwf9X/w7mqb7ytg==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.22': - resolution: {integrity: sha512-/rXhMXteD+BqhFd0nYprAgcZ/KtU+963uftPqd3tiFcFfooHZINXUGtOmo2SQjRVauCTNqIEzkwuSETdZFqTTA==} + '@aws-sdk/signature-v4-multi-region@3.996.24': + resolution: {integrity: sha512-amP7tLikppN940wbBFISYqiuzVmpzMS9U3mcgtmVLjX4fdWI/SNCvrXv6ZxfVzTT4cT0rPKOLhFah2xLwzREWw==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1036.0': - resolution: {integrity: sha512-aNSJ6jjDYayxN9ZA1JpycVScX93Lx03kKZ1EXt3DGOTahcWVLJj3oLAlop0xKP+vP2Ga2t49p1tEaMkTbCCaZA==} + '@aws-sdk/token-providers@3.1039.0': + resolution: {integrity: sha512-NMSFL2HwkAOoCeLCQiqoOq5pT3vVbSjww2QZTuYgYknVwhhv125PSDzZIcL5EYnlxuPWjEOdauZK+FspkZDVdw==} engines: {node: '>=20.0.0'} '@aws-sdk/types@3.973.8': @@ -1074,8 +1074,8 @@ packages: '@aws-sdk/util-user-agent-browser@3.972.10': resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} - '@aws-sdk/util-user-agent-node@3.973.21': - resolution: {integrity: sha512-Av4UHTcAWgdvbN0IP9pbtf4Qa1+6LtJqQdZWj5pLn5J67w0pnJJAZZ+7JPPcj2KN3378zD2JDM9DwJKEyvyMTQ==} + '@aws-sdk/util-user-agent-node@3.973.23': + resolution: {integrity: sha512-gGwq8L2Euw0aNG6Ey4EktiAo3fSCVoDy1CaBIthd+oeaKHPXUrNaApMewQ6La5Hv0lcznOtECZaNvYyc5LXXfA==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1083,8 +1083,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.19': - resolution: {integrity: sha512-Cw8IOMdBUEIl8ZlhRC3Dc/E64D5B5/8JhV6vhPLiPfJwcRC84S6F8aBOIi/N4vR9ZyA4I5Cc0Ateb/9EHaJXeQ==} + '@aws-sdk/xml-builder@3.972.22': + resolution: {integrity: sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.3': @@ -3915,7 +3915,7 @@ packages: resolution: {integrity: sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==} '@react-email/body@0.3.0': - resolution: {integrity: sha512-uGo0BOOzjbMUo3lu+BIDWayvn5o6Xyfmnlla5VGf05n8gHMvO1ll7U4FtzWe3hxMLwt53pmc4iE0M+B5slG+Ug==} + resolution: {integrity: sha512-uGo0BOOzjbMUo3lu+BIDWayvn5o6Xyfmnlla5VGf05n8gHMvO1ll7U4FtzWe3hxMLxMLwt53pmc4iE0M+B5slG+Ug==} engines: {node: '>=20.0.0'} peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc @@ -4281,8 +4281,8 @@ packages: resolution: {integrity: sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.5.5': - resolution: {integrity: sha512-wnYOpB5vATFKWrY2Z9Alb0KhjZI6AbzU6Fbz3Hq2GnURdRYWB4q+qWivQtSTwXcmWUA3MZ6krfwL6Cq5MAbxsA==} + '@smithy/middleware-retry@4.5.7': + resolution: {integrity: sha512-bRt6ZImqVSeTk39Nm81K20ObIiAZ3WefY7G6+iz/0tZjs4dgRRjvRX2sgsH+zi6iDCRR/aQvQofLKxxz4rPBZg==} engines: {node: '>=18.0.0'} '@smithy/middleware-serde@4.2.20': @@ -4317,8 +4317,8 @@ packages: resolution: {integrity: sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.3.0': - resolution: {integrity: sha512-9jKsBYQRPR0xBLgc2415RsA5PIcP2sis4oBdN9s0D13cg1B1284mNTjx9Yc+BEERXzuPm5ObktI96OxsKh8E9A==} + '@smithy/service-error-classification@4.3.1': + resolution: {integrity: sha512-aUQuDGh760ts/8MU+APjIZhlLPKhIIfqyzZaJikLEIMrdxFvxuLYD0WxWzaYWpmLbQlXDe9p7EWM3HsBe0K6Gw==} engines: {node: '>=18.0.0'} '@smithy/shared-ini-file-loader@4.4.9': @@ -4385,8 +4385,8 @@ packages: resolution: {integrity: sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==} engines: {node: '>=18.0.0'} - '@smithy/util-retry@4.3.4': - resolution: {integrity: sha512-FY1UQQ1VFmMwiYp1GVS4MeaGD5O0blLNYK0xCRHU+mJgeoH/hSY8Ld8sJWKQ6uznkh14HveRGQJncgPyNl9J+A==} + '@smithy/util-retry@4.3.6': + resolution: {integrity: sha512-p6/FO1n2KxMeQyna067i0uJ6TSbb165ZhnRtCpWh4Foxqbfc6oW+XITaL8QkFJj3KFnDe2URt4gOhgU06EP9ew==} engines: {node: '>=18.0.0'} '@smithy/util-stream@4.5.25': @@ -4405,8 +4405,8 @@ packages: resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.2.16': - resolution: {integrity: sha512-GtclrKoZ3Lt7jPQ7aTIYKfjY92OgceScftVnkTsG8e1KV8rkvZgN+ny6YSRhd9hxB8rZtwVbmln7NTvE5O3GmQ==} + '@smithy/util-waiter@4.3.0': + resolution: {integrity: sha512-JyjYmLAfS+pdxF92o4yLgEoy0zhayKTw73FU1aofLWwLcJw7iSqIY2exGmMTrl/lmZugP5p/zxdFSippJDfKWA==} engines: {node: '>=18.0.0'} '@smithy/uuid@1.1.2': @@ -6862,8 +6862,8 @@ packages: fast-xml-builder@1.1.5: resolution: {integrity: sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==} - fast-xml-parser@5.7.1: - resolution: {integrity: sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==} + fast-xml-parser@5.7.2: + resolution: {integrity: sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==} hasBin: true fastify-ip@2.0.0: @@ -10814,29 +10814,29 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.1037.0': + '@aws-sdk/client-s3@3.1040.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.5 - '@aws-sdk/credential-provider-node': 3.972.36 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/credential-provider-node': 3.972.38 '@aws-sdk/middleware-bucket-endpoint': 3.972.10 '@aws-sdk/middleware-expect-continue': 3.972.10 - '@aws-sdk/middleware-flexible-checksums': 3.974.13 + '@aws-sdk/middleware-flexible-checksums': 3.974.15 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-location-constraint': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-sdk-s3': 3.972.34 + '@aws-sdk/middleware-sdk-s3': 3.972.36 '@aws-sdk/middleware-ssec': 3.972.10 - '@aws-sdk/middleware-user-agent': 3.972.35 + '@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.22 + '@aws-sdk/signature-v4-multi-region': 3.996.24 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.21 + '@aws-sdk/util-user-agent-node': 3.973.23 '@smithy/config-resolver': 4.4.17 '@smithy/core': 3.23.17 '@smithy/eventstream-serde-browser': 4.2.14 @@ -10850,7 +10850,7 @@ snapshots: '@smithy/md5-js': 4.2.14 '@smithy/middleware-content-length': 4.2.14 '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-retry': 4.5.5 + '@smithy/middleware-retry': 4.5.7 '@smithy/middleware-serde': 4.2.20 '@smithy/middleware-stack': 4.2.14 '@smithy/node-config-provider': 4.3.14 @@ -10866,18 +10866,18 @@ snapshots: '@smithy/util-defaults-mode-node': 4.2.54 '@smithy/util-endpoints': 3.4.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.4 + '@smithy/util-retry': 4.3.6 '@smithy/util-stream': 4.5.25 '@smithy/util-utf8': 4.2.2 - '@smithy/util-waiter': 4.2.16 + '@smithy/util-waiter': 4.3.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.974.5': + '@aws-sdk/core@3.974.7': dependencies: '@aws-sdk/types': 3.973.8 - '@aws-sdk/xml-builder': 3.972.19 + '@aws-sdk/xml-builder': 3.972.22 '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/property-provider': 4.2.14 @@ -10887,7 +10887,7 @@ snapshots: '@smithy/types': 4.14.1 '@smithy/util-base64': 4.3.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.4 + '@smithy/util-retry': 4.3.6 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 @@ -10896,17 +10896,17 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.31': + '@aws-sdk/credential-provider-env@3.972.33': dependencies: - '@aws-sdk/core': 3.974.5 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.33': + '@aws-sdk/credential-provider-http@3.972.35': dependencies: - '@aws-sdk/core': 3.974.5 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@smithy/fetch-http-handler': 5.3.17 '@smithy/node-http-handler': 4.6.1 @@ -10917,16 +10917,16 @@ snapshots: '@smithy/util-stream': 4.5.25 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.35': + '@aws-sdk/credential-provider-ini@3.972.37': dependencies: - '@aws-sdk/core': 3.974.5 - '@aws-sdk/credential-provider-env': 3.972.31 - '@aws-sdk/credential-provider-http': 3.972.33 - '@aws-sdk/credential-provider-login': 3.972.35 - '@aws-sdk/credential-provider-process': 3.972.31 - '@aws-sdk/credential-provider-sso': 3.972.35 - '@aws-sdk/credential-provider-web-identity': 3.972.35 - '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/credential-provider-env': 3.972.33 + '@aws-sdk/credential-provider-http': 3.972.35 + '@aws-sdk/credential-provider-login': 3.972.37 + '@aws-sdk/credential-provider-process': 3.972.33 + '@aws-sdk/credential-provider-sso': 3.972.37 + '@aws-sdk/credential-provider-web-identity': 3.972.37 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -10936,10 +10936,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.35': + '@aws-sdk/credential-provider-login@3.972.37': dependencies: - '@aws-sdk/core': 3.974.5 - '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/protocol-http': 5.3.14 @@ -10949,14 +10949,14 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.36': + '@aws-sdk/credential-provider-node@3.972.38': dependencies: - '@aws-sdk/credential-provider-env': 3.972.31 - '@aws-sdk/credential-provider-http': 3.972.33 - '@aws-sdk/credential-provider-ini': 3.972.35 - '@aws-sdk/credential-provider-process': 3.972.31 - '@aws-sdk/credential-provider-sso': 3.972.35 - '@aws-sdk/credential-provider-web-identity': 3.972.35 + '@aws-sdk/credential-provider-env': 3.972.33 + '@aws-sdk/credential-provider-http': 3.972.35 + '@aws-sdk/credential-provider-ini': 3.972.37 + '@aws-sdk/credential-provider-process': 3.972.33 + '@aws-sdk/credential-provider-sso': 3.972.37 + '@aws-sdk/credential-provider-web-identity': 3.972.37 '@aws-sdk/types': 3.973.8 '@smithy/credential-provider-imds': 4.2.14 '@smithy/property-provider': 4.2.14 @@ -10966,20 +10966,20 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.31': + '@aws-sdk/credential-provider-process@3.972.33': dependencies: - '@aws-sdk/core': 3.974.5 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.35': + '@aws-sdk/credential-provider-sso@3.972.37': dependencies: - '@aws-sdk/core': 3.974.5 - '@aws-sdk/nested-clients': 3.997.3 - '@aws-sdk/token-providers': 3.1036.0 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 + '@aws-sdk/token-providers': 3.1039.0 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -10988,10 +10988,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.35': + '@aws-sdk/credential-provider-web-identity@3.972.37': dependencies: - '@aws-sdk/core': 3.974.5 - '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -11000,9 +11000,9 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/lib-storage@3.1037.0(@aws-sdk/client-s3@3.1037.0)': + '@aws-sdk/lib-storage@3.1040.0(@aws-sdk/client-s3@3.1040.0)': dependencies: - '@aws-sdk/client-s3': 3.1037.0 + '@aws-sdk/client-s3': 3.1040.0 '@smithy/middleware-endpoint': 4.4.32 '@smithy/protocol-http': 5.3.14 '@smithy/smithy-client': 4.12.13 @@ -11029,12 +11029,12 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.974.13': + '@aws-sdk/middleware-flexible-checksums@3.974.15': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.974.5 + '@aws-sdk/core': 3.974.7 '@aws-sdk/crc64-nvme': 3.972.7 '@aws-sdk/types': 3.973.8 '@smithy/is-array-buffer': 4.2.2 @@ -11073,9 +11073,9 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.34': + '@aws-sdk/middleware-sdk-s3@3.972.36': dependencies: - '@aws-sdk/core': 3.974.5 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-arn-parser': 3.972.3 '@smithy/core': 3.23.17 @@ -11096,32 +11096,32 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.35': + '@aws-sdk/middleware-user-agent@3.972.37': dependencies: - '@aws-sdk/core': 3.974.5 + '@aws-sdk/core': 3.974.7 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@smithy/core': 3.23.17 '@smithy/protocol-http': 5.3.14 '@smithy/types': 4.14.1 - '@smithy/util-retry': 4.3.4 + '@smithy/util-retry': 4.3.6 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.997.3': + '@aws-sdk/nested-clients@3.997.5': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.5 + '@aws-sdk/core': 3.974.7 '@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.35 + '@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.22 + '@aws-sdk/signature-v4-multi-region': 3.996.24 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.21 + '@aws-sdk/util-user-agent-node': 3.973.23 '@smithy/config-resolver': 4.4.17 '@smithy/core': 3.23.17 '@smithy/fetch-http-handler': 5.3.17 @@ -11129,7 +11129,7 @@ snapshots: '@smithy/invalid-dependency': 4.2.14 '@smithy/middleware-content-length': 4.2.14 '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-retry': 4.5.5 + '@smithy/middleware-retry': 4.5.7 '@smithy/middleware-serde': 4.2.20 '@smithy/middleware-stack': 4.2.14 '@smithy/node-config-provider': 4.3.14 @@ -11145,7 +11145,7 @@ snapshots: '@smithy/util-defaults-mode-node': 4.2.54 '@smithy/util-endpoints': 3.4.2 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.4 + '@smithy/util-retry': 4.3.6 '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 transitivePeerDependencies: @@ -11159,9 +11159,9 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/s3-request-presigner@3.1037.0': + '@aws-sdk/s3-request-presigner@3.1040.0': dependencies: - '@aws-sdk/signature-v4-multi-region': 3.996.22 + '@aws-sdk/signature-v4-multi-region': 3.996.24 '@aws-sdk/types': 3.973.8 '@aws-sdk/util-format-url': 3.972.10 '@smithy/middleware-endpoint': 4.4.32 @@ -11170,19 +11170,19 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.22': + '@aws-sdk/signature-v4-multi-region@3.996.24': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.34 + '@aws-sdk/middleware-sdk-s3': 3.972.36 '@aws-sdk/types': 3.973.8 '@smithy/protocol-http': 5.3.14 '@smithy/signature-v4': 5.3.14 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1036.0': + '@aws-sdk/token-providers@3.1039.0': dependencies: - '@aws-sdk/core': 3.974.5 - '@aws-sdk/nested-clients': 3.997.3 + '@aws-sdk/core': 3.974.7 + '@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/types': 3.973.8 '@smithy/property-provider': 4.2.14 '@smithy/shared-ini-file-loader': 4.4.9 @@ -11226,19 +11226,20 @@ snapshots: bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.21': + '@aws-sdk/util-user-agent-node@3.973.23': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.35 + '@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/types': 3.973.8 '@smithy/node-config-provider': 4.3.14 '@smithy/types': 4.14.1 '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.19': + '@aws-sdk/xml-builder@3.972.22': dependencies: + '@nodable/entities': 2.1.0 '@smithy/types': 4.14.1 - fast-xml-parser: 5.7.1 + fast-xml-parser: 5.7.2 tslib: 2.8.1 '@aws/lambda-invoke-store@0.2.3': {} @@ -14684,16 +14685,16 @@ snapshots: '@smithy/util-middleware': 4.2.14 tslib: 2.8.1 - '@smithy/middleware-retry@4.5.5': + '@smithy/middleware-retry@4.5.7': dependencies: '@smithy/core': 3.23.17 '@smithy/node-config-provider': 4.3.14 '@smithy/protocol-http': 5.3.14 - '@smithy/service-error-classification': 4.3.0 + '@smithy/service-error-classification': 4.3.1 '@smithy/smithy-client': 4.12.13 '@smithy/types': 4.14.1 '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.4 + '@smithy/util-retry': 4.3.6 '@smithy/uuid': 1.1.2 tslib: 2.8.1 @@ -14744,7 +14745,7 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/service-error-classification@4.3.0': + '@smithy/service-error-classification@4.3.1': dependencies: '@smithy/types': 4.14.1 @@ -14844,9 +14845,9 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/util-retry@4.3.4': + '@smithy/util-retry@4.3.6': dependencies: - '@smithy/service-error-classification': 4.3.0 + '@smithy/service-error-classification': 4.3.1 '@smithy/types': 4.14.1 tslib: 2.8.1 @@ -14875,7 +14876,7 @@ snapshots: '@smithy/util-buffer-from': 4.2.2 tslib: 2.8.1 - '@smithy/util-waiter@4.2.16': + '@smithy/util-waiter@4.3.0': dependencies: '@smithy/types': 4.14.1 tslib: 2.8.1 @@ -17735,7 +17736,7 @@ snapshots: dependencies: path-expression-matcher: 1.5.0 - fast-xml-parser@5.7.1: + fast-xml-parser@5.7.2: dependencies: '@nodable/entities': 2.1.0 fast-xml-builder: 1.1.5 From fcef0c6b96dc2273e34e6211ab95bd94ef8df618 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Mon, 4 May 2026 20:57:35 +0100 Subject: [PATCH 19/46] fix: S3 --- .../src/integrations/environment/environment.service.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/server/src/integrations/environment/environment.service.ts b/apps/server/src/integrations/environment/environment.service.ts index f0b548ab7..d9ef01abb 100644 --- a/apps/server/src/integrations/environment/environment.service.ts +++ b/apps/server/src/integrations/environment/environment.service.ts @@ -112,7 +112,10 @@ export class EnvironmentService { } getAwsS3ForcePathStyle(): boolean { - return this.configService.get('AWS_S3_FORCE_PATH_STYLE'); + const forcePathStyle = this.configService + .get('AWS_S3_FORCE_PATH_STYLE', 'false') + .toLowerCase(); + return forcePathStyle === 'true'; } getAwsS3Url(): string { From fe18f22dc685c4406d0715eb271052ec2581e0d1 Mon Sep 17 00:00:00 2001 From: Sarthak Chaturvedi <84394327+mayhemking007@users.noreply.github.com> Date: Tue, 5 May 2026 01:44:21 +0530 Subject: [PATCH 20/46] fix: prevent code block deletion when adding inline comments in read mode (#2146) --- apps/server/src/collaboration/yjs.util.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/server/src/collaboration/yjs.util.ts b/apps/server/src/collaboration/yjs.util.ts index 863b149a6..c79e5331d 100644 --- a/apps/server/src/collaboration/yjs.util.ts +++ b/apps/server/src/collaboration/yjs.util.ts @@ -62,14 +62,14 @@ function applyMarkToYFragment( ) { let pos = 0; - const processItem = (item: any): boolean => { + const processItem = (item: any, parentNodeName?: string): boolean => { if (pos >= to) return false; if (item instanceof Y.XmlText) { const textLength = item.length; const itemEnd = pos + textLength; - if (itemEnd > from && pos < to) { + if (itemEnd > from && pos < to && parentNodeName !== 'codeBlock') { const formatFrom = Math.max(0, from - pos); const formatTo = Math.min(textLength, to - pos); const formatLength = formatTo - formatFrom; @@ -82,7 +82,7 @@ function applyMarkToYFragment( } else if (item instanceof Y.XmlElement) { pos++; // Opening tag for (let i = 0; i < item.length; i++) { - if (!processItem(item.get(i))) return false; + if (!processItem(item.get(i), item.nodeName)) return false; } pos++; // Closing tag } From dbe6c2d6baf60d7d3abfcb191da31b29157f568c Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Mon, 4 May 2026 21:21:37 +0100 Subject: [PATCH 21/46] feat: A11y fixes (#2148) --- .../public/locales/en-US/translation.json | 28 ++++++- .../src/components/common/avatar-uploader.tsx | 10 +++ apps/client/src/components/common/copy.tsx | 1 + .../src/components/common/recent-changes.tsx | 6 +- .../src/components/common/search-input.tsx | 3 + .../components/icons/icon-people-circle.tsx | 6 +- .../layouts/global/app-shell.module.css | 18 ++++ .../layouts/global/global-app-shell.tsx | 37 ++++++++- .../layouts/global/global-sidebar.module.css | 2 +- .../layouts/global/global-sidebar.tsx | 12 +-- .../src/components/settings/app-version.tsx | 2 +- .../components/settings/settings-sidebar.tsx | 61 +++++++------- .../src/components/ui/custom-avatar.tsx | 34 +++++++- .../ui/destination-picker/page-children.tsx | 13 ++- .../client/src/components/ui/emoji-picker.tsx | 9 +- .../components/ai-chat-sidebar-item.tsx | 1 + .../ee/api-key/components/api-key-table.tsx | 8 +- .../components/page-verification-modal.tsx | 22 ++++- .../ee/scim/components/scim-token-table.tsx | 2 +- .../security/components/sso-provider-list.tsx | 9 +- .../ee/template/components/template-card.tsx | 1 + .../components/template-preview-modal.tsx | 2 +- .../comment/components/comment-dialog.tsx | 1 + .../comment/components/comment-list-item.tsx | 9 ++ .../comment/components/comment-menu.tsx | 6 +- .../editor/components/audio/audio-view.tsx | 4 +- .../components/bubble-menu/color-selector.tsx | 83 +++++++++++++------ .../components/bubble-menu/node-selector.tsx | 3 + .../bubble-menu/text-alignment-selector.tsx | 3 + .../editor/components/drawio/drawio-view.tsx | 8 +- .../components/emoji-menu/emoji-list.tsx | 16 +++- .../components/link/link-editor-panel.tsx | 17 ++++ .../components/mention/mention-list.tsx | 27 +++++- .../editor/components/pdf/pdf-view.tsx | 15 +++- .../search-and-replace-dialog.tsx | 28 ++++++- .../components/slash-menu/command-list.tsx | 40 ++++++--- .../editor/components/status/status-view.tsx | 19 +++++ .../editor/components/video/video-view.tsx | 4 +- .../favorite/components/star-button.tsx | 12 +-- .../group/components/group-action-menu.tsx | 2 +- .../group/components/group-members.tsx | 2 +- .../home/components/created-by-me.tsx | 6 +- .../home/components/favorites-pages.tsx | 6 +- .../components/notification-popover.tsx | 3 + .../page-history/components/history-modal.tsx | 2 + .../components/breadcrumbs/breadcrumb.tsx | 33 ++++++-- .../components/header/page-header-menu.tsx | 20 ++++- .../page/components/page-import-modal.tsx | 37 ++++++++- .../components/trash-page-content-modal.tsx | 2 +- .../features/page/trash/components/trash.tsx | 2 +- .../page/tree/components/space-tree.tsx | 8 ++ .../search/components/search-control.tsx | 1 + .../session/components/session-list.tsx | 4 +- .../share/components/share-action-menu.tsx | 2 +- .../features/share/components/share-shell.tsx | 2 + .../space/components/space-members.tsx | 2 +- .../spaces-page/all-spaces-list.tsx | 18 ++-- .../components/members-action-menu.tsx | 6 +- .../components/workspace-invites-table.tsx | 1 + .../components/workspace-members-table.tsx | 1 + .../src/pages/favorites/favorites-page.tsx | 6 +- apps/client/src/theme.ts | 2 +- 62 files changed, 587 insertions(+), 163 deletions(-) diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index 56709bbe6..38fd5f2df 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -416,6 +416,7 @@ "{{latestVersion}} is available": "{{latestVersion}} is available", "Default page edit mode": "Default page edit mode", "Choose your preferred page edit mode. Avoid accidental edits.": "Choose your preferred page edit mode. Avoid accidental edits.", + "Choose {{format}} file": "Choose {{format}} file", "Reading": "Reading", "Delete member": "Delete member", "Member deleted successfully": "Member deleted successfully", @@ -900,5 +901,30 @@ "SCIM tokens": "SCIM tokens", "This action cannot be undone. Your identity provider will stop syncing immediately.": "This action cannot be undone. Your identity provider will stop syncing immediately.", "Toggle SCIM provisioning": "Toggle SCIM provisioning", - "Token": "Token" + "Token": "Token", + "Page menu": "Page menu", + "Expand": "Expand", + "Collapse": "Collapse", + "Comment menu": "Comment menu", + "Group menu": "Group menu", + "Show hidden breadcrumbs": "Show hidden breadcrumbs", + "Breadcrumbs": "Breadcrumbs", + "Page actions": "Page actions", + "Pick emoji": "Pick emoji", + "Template menu": "Template menu", + "Chat menu": "Chat menu", + "API key menu": "API key menu", + "Jump to comment selection": "Jump to comment selection", + "Slash commands": "Slash commands", + "Mention suggestions": "Mention suggestions", + "Link suggestions": "Link suggestions", + "Diagram editor": "Diagram editor", + "Add comment": "Add comment", + "Find and replace": "Find and replace", + "Main navigation": "Main navigation", + "Space navigation": "Space navigation", + "Settings navigation": "Settings navigation", + "AI navigation": "AI navigation", + "Breadcrumb": "Breadcrumb", + "Skip to main content": "Skip to main content" } diff --git a/apps/client/src/components/common/avatar-uploader.tsx b/apps/client/src/components/common/avatar-uploader.tsx index 8d9552f64..750e4ba68 100644 --- a/apps/client/src/components/common/avatar-uploader.tsx +++ b/apps/client/src/components/common/avatar-uploader.tsx @@ -80,6 +80,12 @@ export default function AvatarUploader({ } }; + const ariaLabel = { + [AvatarIconType.AVATAR]: t("Change avatar"), + [AvatarIconType.SPACE_ICON]: t("Change space icon"), + [AvatarIconType.WORKSPACE_ICON]: t("Change workspace icon"), + }[type]; + const handleRemove = async () => { if (disabled) return; @@ -104,6 +110,8 @@ export default function AvatarUploader({ ref={fileInputRef} onChange={handleFileInputChange} accept="image/png,image/jpeg,image/jpg" + aria-label={ariaLabel} + tabIndex={-1} style={{ display: "none" }} /> @@ -115,6 +123,8 @@ export default function AvatarUploader({ size={size} avatarUrl={currentImageUrl} name={fallbackName} + aria-label={ariaLabel} + aria-haspopup="menu" style={{ cursor: disabled || isLoading ? "default" : "pointer", opacity: isLoading ? 0.6 : 1, diff --git a/apps/client/src/components/common/copy.tsx b/apps/client/src/components/common/copy.tsx index 745fc4ba6..2144417b9 100644 --- a/apps/client/src/components/common/copy.tsx +++ b/apps/client/src/components/common/copy.tsx @@ -25,6 +25,7 @@ export default function CopyTextButton({ text, size }: CopyProps) { variant="subtle" onClick={copy} size={size} + aria-label={copied ? t("Copied") : t("Copy")} > {copied ? : } diff --git a/apps/client/src/components/common/recent-changes.tsx b/apps/client/src/components/common/recent-changes.tsx index 277ceb811..8e0e56f29 100644 --- a/apps/client/src/components/common/recent-changes.tsx +++ b/apps/client/src/components/common/recent-changes.tsx @@ -4,7 +4,7 @@ import { UnstyledButton, Badge, Table, - ActionIcon, + ThemeIcon, Button, } from "@mantine/core"; import { Link } from "react-router-dom"; @@ -49,9 +49,9 @@ export default function RecentChanges({ spaceId }: Props) { > {page.icon || ( - + - + )} diff --git a/apps/client/src/components/common/search-input.tsx b/apps/client/src/components/common/search-input.tsx index 08cbbee06..27e50fd4e 100644 --- a/apps/client/src/components/common/search-input.tsx +++ b/apps/client/src/components/common/search-input.tsx @@ -6,12 +6,14 @@ import { useTranslation } from "react-i18next"; export interface SearchInputProps { placeholder?: string; + ariaLabel?: string; debounceDelay?: number; onSearch: (value: string) => void; } export function SearchInput({ placeholder, + ariaLabel, debounceDelay = 500, onSearch, }: SearchInputProps) { @@ -28,6 +30,7 @@ export function SearchInput({ } value={value} onChange={(e) => setValue(e.currentTarget.value)} diff --git a/apps/client/src/components/icons/icon-people-circle.tsx b/apps/client/src/components/icons/icon-people-circle.tsx index 996958965..1a2daf73d 100644 --- a/apps/client/src/components/icons/icon-people-circle.tsx +++ b/apps/client/src/components/icons/icon-people-circle.tsx @@ -1,11 +1,11 @@ -import { ActionIcon, rem } from "@mantine/core"; +import { ThemeIcon } from "@mantine/core"; import React from "react"; import { IconUsersGroup } from "@tabler/icons-react"; export function IconGroupCircle() { return ( - + - + ); } diff --git a/apps/client/src/components/layouts/global/app-shell.module.css b/apps/client/src/components/layouts/global/app-shell.module.css index ed369612c..7ed937727 100644 --- a/apps/client/src/components/layouts/global/app-shell.module.css +++ b/apps/client/src/components/layouts/global/app-shell.module.css @@ -28,4 +28,22 @@ } } +.skipLink { + position: fixed; + left: 8px; + top: 8px; + padding: 8px 12px; + background: var(--mantine-color-blue-6); + color: #fff; + border-radius: 4px; + text-decoration: none; + z-index: 1000; + transform: translateY(-150%); + + &:focus { + transform: translateY(0); + outline: 2px solid var(--mantine-color-blue-3); + } +} + diff --git a/apps/client/src/components/layouts/global/global-app-shell.tsx b/apps/client/src/components/layouts/global/global-app-shell.tsx index 6e842a056..99373814a 100644 --- a/apps/client/src/components/layouts/global/global-app-shell.tsx +++ b/apps/client/src/components/layouts/global/global-app-shell.tsx @@ -1,6 +1,7 @@ import { AppShell, Container } from "@mantine/core"; import React, { useEffect, useRef, useState } from "react"; import { useLocation } from "react-router-dom"; +import { useTranslation } from "react-i18next"; import SettingsSidebar from "@/components/settings/settings-sidebar.tsx"; import { useAtom } from "jotai"; import { @@ -23,11 +24,12 @@ export default function GlobalAppShell({ }: { children: React.ReactNode; }) { + const { t } = useTranslation(); useTrialEndAction(); const [mobileOpened] = useAtom(mobileSidebarAtom); const toggleMobile = useToggleSidebar(mobileSidebarAtom); const [desktopOpened] = useAtom(desktopSidebarAtom); - const [{ isAsideOpen }] = useAtom(asideStateAtom); + const [{ isAsideOpen, tab: asideTab }] = useAtom(asideStateAtom); const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom); const [isResizing, setIsResizing] = useState(false); const sidebarRef = useRef(null); @@ -79,7 +81,11 @@ export default function GlobalAppShell({ const showGlobalSidebar = !isSpaceRoute && !isSettingsRoute && !isAiRoute; return ( - + + {t("Skip to main content")} + + {isSpaceRoute && (
@@ -114,7 +129,7 @@ export default function GlobalAppShell({ {isAiRoute && } {showGlobalSidebar && } - + {isSettingsRoute ? ( {children} @@ -125,10 +140,24 @@ export default function GlobalAppShell({ {isPageRoute && ( - +
may have been replaced by a PM transaction; drop + // the cached reference before checking eligibility. + this.cachedHeaderRow = null; + if (!this.isEligible()) { + this.apply('off'); + return; + } + if (this.mode === 'off') { + // Eligibility just flipped back on; re-trigger the observer so it + // emits the current intersection state. + this.fitsObserver?.unobserve(this.table); + this.fitsObserver?.observe(this.table); + } + } + + destroy() { + this.fitsObserver?.disconnect(); + this.fitsObserver = undefined; + this.apply('off'); + pinOffsetWatcher.release(); + } +} + +const controllers = new WeakMap(); + +export function attach(wrapper: HTMLElement) { + if (controllers.has(wrapper)) return; + const table = wrapper.querySelector(':scope > table') as HTMLTableElement | null; + if (!table) return; + controllers.set(wrapper, new TablePinController(wrapper, table)); +} + +export function detach(wrapper: HTMLElement) { + const ctrl = controllers.get(wrapper); + if (!ctrl) return; + ctrl.destroy(); + controllers.delete(wrapper); +} + +export function getController(wrapper: HTMLElement): TablePinController | undefined { + return controllers.get(wrapper); +} diff --git a/packages/editor-ext/src/lib/table/header-pin/extension.ts b/packages/editor-ext/src/lib/table/header-pin/extension.ts new file mode 100644 index 000000000..8e5157ede --- /dev/null +++ b/packages/editor-ext/src/lib/table/header-pin/extension.ts @@ -0,0 +1,78 @@ +import { Extension } from '@tiptap/core'; +import { Plugin, PluginKey } from '@tiptap/pm/state'; + +import { attach, detach, getController } from './controller'; + +const tableHeaderPinKey = new PluginKey('tableHeaderPin'); + +export const TableHeaderPin = Extension.create({ + name: 'tableHeaderPin', + + addProseMirrorPlugins() { + let editorRoot: HTMLElement | null = null; + let domObserver: MutationObserver | null = null; + const tracked = new Set(); + let rafHandle: number | null = null; + + const reconcile = () => { + rafHandle = null; + if (!editorRoot) return; + const current = new Set( + editorRoot.querySelectorAll('.tableWrapper'), + ); + for (const w of tracked) { + if (!current.has(w)) { + detach(w); + tracked.delete(w); + } + } + for (const w of current) { + if (!tracked.has(w)) { + attach(w); + tracked.add(w); + } + } + }; + + const schedule = () => { + if (rafHandle !== null) return; + rafHandle = requestAnimationFrame(reconcile); + }; + + return [ + new Plugin({ + key: tableHeaderPinKey, + + view(editorView) { + editorRoot = editorView.dom as HTMLElement; + + schedule(); + + domObserver = new MutationObserver(schedule); + domObserver.observe(editorRoot, { subtree: true, childList: true }); + + return { + update(view, prevState) { + if (!editorRoot) return; + if (view.state.doc === prevState.doc) return; + editorRoot + .querySelectorAll('.tableWrapper') + .forEach((w) => getController(w)?.refresh()); + }, + destroy() { + if (rafHandle !== null) { + cancelAnimationFrame(rafHandle); + rafHandle = null; + } + domObserver?.disconnect(); + domObserver = null; + for (const w of tracked) detach(w); + tracked.clear(); + editorRoot = null; + }, + }; + }, + }), + ]; + }, +}); diff --git a/packages/editor-ext/src/lib/table/header-pin/index.ts b/packages/editor-ext/src/lib/table/header-pin/index.ts new file mode 100644 index 000000000..b45e01aee --- /dev/null +++ b/packages/editor-ext/src/lib/table/header-pin/index.ts @@ -0,0 +1 @@ +export { TableHeaderPin } from './extension'; diff --git a/packages/editor-ext/src/lib/table/header-pin/offset.ts b/packages/editor-ext/src/lib/table/header-pin/offset.ts new file mode 100644 index 000000000..89cc6bf9e --- /dev/null +++ b/packages/editor-ext/src/lib/table/header-pin/offset.ts @@ -0,0 +1,65 @@ +// Pin-offset measurement and watcher used by the table header-pin controller. + +// Fallback app-bar height (px) when no fixed surface is mounted; matches global-app-shell.tsx. +const APP_BAR_FALLBACK_HEIGHT = 45; + +export const EDITOR_PIN_OFFSET_VAR = '--editor-pin-offset'; + +// Selectors for fixed surfaces between viewport top and editor content. Use data attributes — +// CSS module classes are build-time hashed and won't match. +const PIN_ANCHOR_SELECTORS = [ + '[data-page-header]', + '[data-fixed-toolbar]', +] as const; + +export function computePinTop(): number { + let bottom = APP_BAR_FALLBACK_HEIGHT; + for (const sel of PIN_ANCHOR_SELECTORS) { + const el = document.querySelector(sel) as HTMLElement | null; + if (!el) continue; + const rect = el.getBoundingClientRect(); + if (rect.height > 0 && rect.bottom > bottom) bottom = rect.bottom; + } + return bottom; +} + +// Reference-counted watcher that publishes the editor's top offset to a CSS custom property. +export const pinOffsetWatcher = { + refs: 0, + resizeObserver: null as ResizeObserver | null, + rafPending: false, + lastValue: -1, + + acquire() { + if (this.refs++ > 0) return; + this.publish(); + const schedule = () => { + if (this.rafPending) return; + this.rafPending = true; + requestAnimationFrame(() => { + this.rafPending = false; + this.publish(); + }); + }; + this.resizeObserver = new ResizeObserver(schedule); + this.resizeObserver.observe(document.body); + }, + + release() { + if (--this.refs > 0) return; + this.resizeObserver?.disconnect(); + this.resizeObserver = null; + document.documentElement.style.removeProperty(EDITOR_PIN_OFFSET_VAR); + this.lastValue = -1; + }, + + publish() { + const top = computePinTop(); + if (top === this.lastValue) return; + this.lastValue = top; + document.documentElement.style.setProperty( + EDITOR_PIN_OFFSET_VAR, + `${top}px`, + ); + }, +}; diff --git a/packages/editor-ext/src/lib/table/index.ts b/packages/editor-ext/src/lib/table/index.ts index 9e5a92651..ed06582e3 100644 --- a/packages/editor-ext/src/lib/table/index.ts +++ b/packages/editor-ext/src/lib/table/index.ts @@ -2,4 +2,14 @@ export * from "./row"; export * from "./cell"; export * from "./header"; export * from "./table"; -export * from "./dnd"; \ No newline at end of file +export * from "./dnd"; +export * from "./table-view"; +export * from "./header-pin"; +export * from "./table-readonly-sort"; +export { moveColumn } from "./utils/move-column"; +export type { MoveColumnParams } from "./utils/move-column"; +export { moveRow } from "./utils/move-row"; +export type { MoveRowParams } from "./utils/move-row"; +export { convertTableNodeToArrayOfRows } from "./utils/convert-table-node-to-array-of-rows"; +export { convertArrayOfRowsToTableNode } from "./utils/convert-array-of-rows-to-table-node"; +export { transpose } from "./utils/transpose"; diff --git a/packages/editor-ext/src/lib/table/table-readonly-sort.ts b/packages/editor-ext/src/lib/table/table-readonly-sort.ts new file mode 100644 index 000000000..3e246a411 --- /dev/null +++ b/packages/editor-ext/src/lib/table/table-readonly-sort.ts @@ -0,0 +1,233 @@ +import { Extension } from '@tiptap/core'; +import { Plugin, PluginKey } from '@tiptap/pm/state'; + +type SortDirection = 'asc' | 'desc'; + +type SortState = { + col: number; + direction: SortDirection; +}; + +const CHEVRON_CLASS = 'tableReadonlySortChevron'; + +const tableReadonlySortKey = new PluginKey('tableReadonlySort'); + +const sortStates = new WeakMap(); +const originalOrders = new WeakMap(); + +const collator = new Intl.Collator(undefined, { sensitivity: 'base', numeric: true }); + +function getColumnIndex(th: HTMLTableCellElement): number { + const row = th.parentElement as HTMLTableRowElement; + if (!row) return -1; + let col = 0; + for (let i = 0; i < row.cells.length; i++) { + if (row.cells[i] === th) return col; + col += row.cells[i].colSpan ?? 1; + } + return -1; +} + +function getHeaderTh(target: EventTarget | null): HTMLTableCellElement | null { + if (!(target instanceof Element)) return null; + const th = target.closest('th') as HTMLTableCellElement | null; + if (!th) return null; + const row = th.parentElement; + if (!row) return null; + const tbody = row.parentElement; + if (!tbody) return null; + const table = tbody.closest('table'); + if (!table) return null; + + // th must be in the first row of the table (could be in thead or tbody) + const firstRow = table.querySelector('tr'); + if (firstRow !== row) return null; + + return th; +} + +function getCellText(row: HTMLTableRowElement, colIndex: number): string { + let col = 0; + for (let i = 0; i < row.cells.length; i++) { + if (col === colIndex) return row.cells[i].textContent?.trim() ?? ''; + col += row.cells[i].colSpan ?? 1; + } + return ''; +} + +function getOrSaveOriginalOrder( + table: HTMLTableElement, + dataRows: HTMLTableRowElement[], +): HTMLTableRowElement[] { + if (!originalOrders.has(table)) { + originalOrders.set(table, [...dataRows]); + } + return originalOrders.get(table)!; +} + +function sortDataRows( + dataRows: HTMLTableRowElement[], + colIndex: number, + direction: SortDirection, +): HTMLTableRowElement[] { + return [...dataRows].sort((a, b) => { + const textA = getCellText(a, colIndex); + const textB = getCellText(b, colIndex); + const emptyA = textA === ''; + const emptyB = textB === ''; + if (emptyA && emptyB) return 0; + if (emptyA) return 1; + if (emptyB) return -1; + const cmp = collator.compare(textA, textB); + return direction === 'asc' ? cmp : -cmp; + }); +} + +function applySort(table: HTMLTableElement, colIndex: number): void { + const tbody = table.querySelector('tbody'); + if (!tbody) return; + + const allRows = Array.from(tbody.querySelectorAll(':scope > tr')); + if (allRows.length === 0) return; + + const headerRow = allRows[0]; + const dataRows = allRows.slice(1); + if (dataRows.length === 0) return; + + const current = sortStates.get(table) ?? null; + const saved = getOrSaveOriginalOrder(table, dataRows); + + let next: SortState | null; + if (!current || current.col !== colIndex) { + next = { col: colIndex, direction: 'asc' }; + } else if (current.direction === 'asc') { + next = { col: colIndex, direction: 'desc' }; + } else { + next = null; + } + + if (next === null) { + sortStates.delete(table); + tbody.append(headerRow, ...saved); + } else { + sortStates.set(table, next); + const sorted = sortDataRows(saved, next.col, next.direction); + tbody.append(headerRow, ...sorted); + } + + updateChevrons(table); +} + +const CHEVRON_SVG = + ''; + +function ensureChevron(th: HTMLTableCellElement): HTMLSpanElement { + let chevron = th.querySelector(`.${CHEVRON_CLASS}`); + if (!chevron) { + chevron = document.createElement('span'); + chevron.className = CHEVRON_CLASS; + chevron.setAttribute('aria-hidden', 'true'); + chevron.innerHTML = CHEVRON_SVG; + th.appendChild(chevron); + } + return chevron; +} + +function updateChevrons(table: HTMLTableElement): void { + const firstRow = table.querySelector('tr'); + if (!firstRow) return; + + const state = sortStates.get(table) ?? null; + let col = 0; + for (let i = 0; i < firstRow.cells.length; i++) { + const cell = firstRow.cells[i]; + if (cell.tagName !== 'TH') { + col += cell.colSpan ?? 1; + continue; + } + const chevron = ensureChevron(cell as HTMLTableCellElement); + let label: string; + if (state && state.col === col) { + chevron.setAttribute('data-sort', state.direction); + label = state.direction === 'asc' ? 'Sort descending' : 'Clear sort'; + } else { + chevron.removeAttribute('data-sort'); + label = 'Sort ascending'; + } + chevron.setAttribute('data-tooltip', label); + chevron.setAttribute('aria-label', label); + chevron.title = label; + col += cell.colSpan ?? 1; + } +} + +function addChevronsToAllTables(editorRoot: HTMLElement): void { + const tables = editorRoot.querySelectorAll('table'); + tables.forEach((table) => updateChevrons(table)); +} + +function removeAllChevrons(editorRoot: HTMLElement): void { + editorRoot + .querySelectorAll(`.${CHEVRON_CLASS}`) + .forEach((el) => el.remove()); +} + +export const TableReadonlySort = Extension.create({ + name: 'tableReadonlySort', + + addProseMirrorPlugins() { + const editor = this.editor; + let editorRoot: HTMLElement | null = null; + + const onClick = (event: MouseEvent) => { + if (editor.isEditable) return; + // Only react to clicks on the chevron, not anywhere else in the header + // cell. This lets the user click into a header to select text without + // accidentally triggering a sort. + if (!(event.target instanceof Element)) return; + const chevron = event.target.closest(`.${CHEVRON_CLASS}`); + if (!chevron) return; + const th = getHeaderTh(chevron); + if (!th) return; + const table = th.closest('table') as HTMLTableElement | null; + if (!table) return; + const colIndex = getColumnIndex(th); + if (colIndex < 0) return; + applySort(table, colIndex); + }; + + return [ + new Plugin({ + key: tableReadonlySortKey, + + view(editorView) { + editorRoot = editorView.dom as HTMLElement; + editorRoot.addEventListener('click', onClick); + + if (!editor.isEditable) { + addChevronsToAllTables(editorRoot); + } + + return { + update(view) { + const root = view.dom as HTMLElement; + if (!editor.isEditable) { + addChevronsToAllTables(root); + } else { + removeAllChevrons(root); + } + }, + destroy() { + if (editorRoot) { + editorRoot.removeEventListener('click', onClick); + removeAllChevrons(editorRoot); + } + }, + }; + }, + }), + ]; + }, +}); diff --git a/packages/editor-ext/src/lib/table/table-view.ts b/packages/editor-ext/src/lib/table/table-view.ts new file mode 100644 index 000000000..7e410918e --- /dev/null +++ b/packages/editor-ext/src/lib/table/table-view.ts @@ -0,0 +1,158 @@ +import type { Node as ProseMirrorNode } from '@tiptap/pm/model'; +import type { NodeView, ViewMutationRecord } from '@tiptap/pm/view'; +import { getColStyleDeclaration } from './utils/col-style'; + +export function updateColumns( + node: ProseMirrorNode, + colgroup: HTMLElement, + table: HTMLTableElement, + cellMinWidth: number, + overrideCol?: number, + overrideValue?: number, +) { + let totalWidth = 0; + let fixedWidth = true; + let nextDOM = colgroup.firstChild; + const row = node.firstChild; + + if (row !== null) { + for (let i = 0, col = 0; i < row.childCount; i += 1) { + const { colspan, colwidth } = row.child(i).attrs; + + for (let j = 0; j < colspan; j += 1, col += 1) { + const hasWidth = + overrideCol === col + ? overrideValue + : ((colwidth && colwidth[j]) as number | undefined); + const cssWidth = hasWidth ? `${hasWidth}px` : ''; + + totalWidth += hasWidth || cellMinWidth; + + if (!hasWidth) { + fixedWidth = false; + } + + if (!nextDOM) { + const colElement = document.createElement('col'); + + const [propertyKey, propertyValue] = getColStyleDeclaration( + cellMinWidth, + hasWidth, + ); + + colElement.style.setProperty(propertyKey, propertyValue); + + colgroup.appendChild(colElement); + } else { + if ((nextDOM as HTMLTableColElement).style.width !== cssWidth) { + const [propertyKey, propertyValue] = getColStyleDeclaration( + cellMinWidth, + hasWidth, + ); + + (nextDOM as HTMLTableColElement).style.setProperty( + propertyKey, + propertyValue, + ); + } + + nextDOM = nextDOM.nextSibling; + } + } + } + } + + while (nextDOM) { + const after = nextDOM.nextSibling; + + nextDOM.parentNode?.removeChild(nextDOM); + nextDOM = after; + } + + const hasUserWidth = + node.attrs.style && + typeof node.attrs.style === 'string' && + /\bwidth\s*:/i.test(node.attrs.style); + + if (fixedWidth && !hasUserWidth) { + table.style.width = `${totalWidth}px`; + table.style.minWidth = ''; + } else { + table.style.width = ''; + table.style.minWidth = `${totalWidth}px`; + } +} + +export class TableView implements NodeView { + node: ProseMirrorNode; + + cellMinWidth: number; + + dom: HTMLDivElement; + + table: HTMLTableElement; + + colgroup: HTMLTableColElement; + + contentDOM: HTMLTableSectionElement; + + constructor(node: ProseMirrorNode, cellMinWidth: number) { + this.node = node; + this.cellMinWidth = cellMinWidth; + this.dom = document.createElement('div'); + this.dom.className = 'tableWrapper'; + this.table = this.dom.appendChild(document.createElement('table')); + + if (node.attrs.style) { + this.table.style.cssText = node.attrs.style; + } + + this.colgroup = this.table.appendChild(document.createElement('colgroup')); + updateColumns(node, this.colgroup, this.table, cellMinWidth); + this.contentDOM = this.table.appendChild(document.createElement('tbody')); + } + + update(node: ProseMirrorNode) { + if (node.type !== this.node.type) return false; + + this.node = node; + updateColumns(node, this.colgroup, this.table, this.cellMinWidth); + + return true; + } + + ignoreMutation(mutation: ViewMutationRecord) { + const target = mutation.target as Node; + const isInsideWrapper = this.dom.contains(target); + const isInsideContent = this.contentDOM.contains(target); + + if (isInsideWrapper && !isInsideContent) { + if ( + mutation.type === 'attributes' || + mutation.type === 'childList' || + mutation.type === 'characterData' + ) { + return true; + } + } + + // Chevron span (.tableReadonlySortChevron) added/removed by sort plugin. + if (mutation.type === 'childList') { + const nodes = [ + ...Array.from(mutation.addedNodes), + ...Array.from(mutation.removedNodes), + ]; + if ( + nodes.some( + (n) => + n instanceof Element && + n.classList.contains('tableReadonlySortChevron'), + ) + ) { + return true; + } + } + + return false; + } +} diff --git a/packages/editor-ext/src/lib/table/table.ts b/packages/editor-ext/src/lib/table/table.ts index f1436c28d..e87048a46 100644 --- a/packages/editor-ext/src/lib/table/table.ts +++ b/packages/editor-ext/src/lib/table/table.ts @@ -1,6 +1,8 @@ import { Table } from "@tiptap/extension-table"; import { Editor } from "@tiptap/core"; import { DOMOutputSpec } from "@tiptap/pm/model"; +import { TextSelection } from "@tiptap/pm/state"; +import { cellAround } from "@tiptap/pm/tables"; const LIST_TYPES = ["bulletList", "orderedList", "taskList"]; @@ -32,9 +34,36 @@ function handleListOutdent(editor: Editor): boolean { } export const CustomTable = Table.extend({ + addKeyboardShortcuts() { return { ...this.parent?.(), + "Mod-a": () => { + const { state, view } = this.editor; + const { selection, doc } = state; + + const $cellPos = cellAround(selection.$anchor); + if (!$cellPos) return false; + + const cellNode = doc.nodeAt($cellPos.pos); + // Empty cells have nothing useful to scope to — let the default + // Mod-a fall through and select the whole doc. + if (!cellNode || !cellNode.textContent) return false; + + const from = $cellPos.pos + 1; + const to = $cellPos.pos + cellNode.nodeSize - 1; + if (from >= to) return true; + + const nextSel = TextSelection.between( + doc.resolve(from), + doc.resolve(to), + 1, + ); + if (!nextSel || selection.eq(nextSel)) return true; + + view.dispatch(state.tr.setSelection(nextSel)); + return true; + }, Tab: () => { // If we're in a list within a table, handle list indentation if (isInList(this.editor) && this.editor.isActive("table")) { diff --git a/packages/editor-ext/src/lib/table/utils/col-style.ts b/packages/editor-ext/src/lib/table/utils/col-style.ts new file mode 100644 index 000000000..8060962fd --- /dev/null +++ b/packages/editor-ext/src/lib/table/utils/col-style.ts @@ -0,0 +1,7 @@ +export function getColStyleDeclaration(minWidth: number, width: number | undefined): [string, string] { + if (width) { + return ['width', `${Math.max(width, minWidth)}px`] + } + + return ['min-width', `${minWidth}px`] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a6dd37f6..f4a628064 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -248,22 +248,22 @@ importers: apps/client: dependencies: '@atlaskit/pragmatic-drag-and-drop': - specifier: ^1.8.1 + specifier: 1.8.1 version: 1.8.1 '@atlaskit/pragmatic-drag-and-drop-auto-scroll': - specifier: ^2.1.0 + specifier: 2.1.5 version: 2.1.5 '@atlaskit/pragmatic-drag-and-drop-flourish': - specifier: ^2.0.15 + specifier: 2.0.15 version: 2.0.15(react@18.3.1) '@atlaskit/pragmatic-drag-and-drop-hitbox': - specifier: ^1.1.0 + specifier: 1.1.0 version: 1.1.0 '@atlaskit/pragmatic-drag-and-drop-live-region': - specifier: ^1.3.4 + specifier: 1.3.4 version: 1.3.4 '@casl/react': - specifier: ^5.0.1 + specifier: 5.0.1 version: 5.0.1(@casl/ability@6.8.0)(react@18.3.1) '@docmost/editor-ext': specifier: workspace:* @@ -272,37 +272,37 @@ importers: specifier: 0.18.0-3a5ef40 version: 0.18.0-3a5ef40(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/core': - specifier: ^8.3.18 + specifier: 8.3.18 version: 8.3.18(@mantine/hooks@8.3.18(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/dates': - specifier: ^8.3.18 + specifier: 8.3.18 version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@8.3.18(react@18.3.1))(dayjs@1.11.19)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/form': - specifier: ^8.3.18 + specifier: 8.3.18 version: 8.3.18(react@18.3.1) '@mantine/hooks': - specifier: ^8.3.18 + specifier: 8.3.18 version: 8.3.18(react@18.3.1) '@mantine/modals': - specifier: ^8.3.18 + specifier: 8.3.18 version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@8.3.18(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/notifications': - specifier: ^8.3.18 + specifier: 8.3.18 version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@8.3.18(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mantine/spotlight': - specifier: ^8.3.18 + specifier: 8.3.18 version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@8.3.18(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@slidoapp/emoji-mart': - specifier: ^5.8.7 + specifier: 5.8.7 version: 5.8.7 '@slidoapp/emoji-mart-data': - specifier: ^1.2.4 + specifier: 1.2.4 version: 1.2.4 '@slidoapp/emoji-mart-react': - specifier: ^1.1.5 + specifier: 1.1.5 version: 1.1.5(@slidoapp/emoji-mart@5.8.7)(react@18.3.1) '@tabler/icons-react': - specifier: ^3.40.0 + specifier: 3.40.0 version: 3.40.0(react@18.3.1) '@tanstack/react-query': specifier: 5.90.17 @@ -311,22 +311,22 @@ importers: specifier: 3.13.24 version: 3.13.24(react-dom@18.3.1(react@18.3.1))(react@18.3.1) alfaaz: - specifier: ^1.1.0 + specifier: 1.1.0 version: 1.1.0 axios: specifier: 1.16.0 version: 1.16.0 blueimp-load-image: - specifier: ^5.16.0 + specifier: 5.16.0 version: 5.16.0 clsx: - specifier: ^2.1.1 + specifier: 2.1.1 version: 2.1.1 file-saver: - specifier: ^2.0.5 + specifier: 2.0.5 version: 2.0.5 highlightjs-sap-abap: - specifier: ^0.3.0 + specifier: 0.3.0 version: 0.3.0 i18next: specifier: 25.10.1 @@ -335,37 +335,37 @@ importers: specifier: 3.0.6 version: 3.0.6 jotai: - specifier: ^2.18.1 + specifier: 2.18.1 version: 2.18.1(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@18.3.12)(react@18.3.1) jotai-optics: - specifier: ^0.4.0 + specifier: 0.4.0 version: 0.4.0(jotai@2.18.1(@babel/core@7.28.5)(@babel/template@7.27.2)(@types/react@18.3.12)(react@18.3.1))(optics-ts@2.4.1) js-cookie: - specifier: ^3.0.5 + specifier: 3.0.5 version: 3.0.5 jwt-decode: - specifier: ^4.0.0 + specifier: 4.0.0 version: 4.0.0 katex: specifier: 0.16.40 version: 0.16.40 lowlight: - specifier: ^3.3.0 + specifier: 3.3.0 version: 3.3.0 mantine-form-zod-resolver: - specifier: ^1.3.0 + specifier: 1.3.0 version: 1.3.0(@mantine/form@8.3.18(react@18.3.1))(zod@4.3.6) mermaid: specifier: 11.13.0 version: 11.13.0 mitt: - specifier: ^3.0.1 + specifier: 3.0.1 version: 3.0.1 posthog-js: specifier: 1.372.2 version: 1.372.2 react: - specifier: ^18.3.1 + specifier: 18.3.1 version: 18.3.1 react-clear-modal: specifier: ^2.0.18 @@ -374,111 +374,111 @@ importers: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) react-drawio: - specifier: ^1.0.7 + specifier: 1.0.7 version: 1.0.7(react@18.3.1) react-error-boundary: - specifier: ^6.1.1 + specifier: 6.1.1 version: 6.1.1(react@18.3.1) react-helmet-async: - specifier: ^3.0.0 + specifier: 3.0.0 version: 3.0.0(react@18.3.1) react-i18next: specifier: 16.5.8 version: 16.5.8(i18next@25.10.1(typescript@5.9.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.3) react-router-dom: - specifier: ^7.13.1 + specifier: 7.13.1 version: 7.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) semver: - specifier: ^7.7.4 + specifier: 7.7.4 version: 7.7.4 socket.io-client: - specifier: ^4.8.3 + specifier: 4.8.3 version: 4.8.3 zod: - specifier: ^4.3.6 + specifier: 4.3.6 version: 4.3.6 devDependencies: '@eslint/js': - specifier: ^9.28.0 - version: 9.39.4 + specifier: 9.28.0 + version: 9.28.0 '@tanstack/eslint-plugin-query': - specifier: ^5.94.4 - version: 5.94.4(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + specifier: 5.94.4 + version: 5.94.4(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) '@testing-library/jest-dom': - specifier: ^6.6.0 - version: 6.9.1 + specifier: 6.6.0 + version: 6.6.0 '@testing-library/react': - specifier: ^16.1.0 - version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 16.1.0 + version: 16.1.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/blueimp-load-image': - specifier: ^5.16.6 + specifier: 5.16.6 version: 5.16.6 '@types/file-saver': - specifier: ^2.0.7 + specifier: 2.0.7 version: 2.0.7 '@types/js-cookie': - specifier: ^3.0.6 + specifier: 3.0.6 version: 3.0.6 '@types/katex': - specifier: ^0.16.8 + specifier: 0.16.8 version: 0.16.8 '@types/node': specifier: 22.19.1 version: 22.19.1 '@types/react': - specifier: ^18.3.12 + specifier: 18.3.12 version: 18.3.12 '@types/react-dom': - specifier: ^18.3.1 + specifier: 18.3.1 version: 18.3.1 '@vitejs/plugin-react': - specifier: ^6.0.1 - version: 6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) + specifier: 6.0.1 + version: 6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) eslint: - specifier: ^9.28.0 - version: 9.39.4(jiti@2.4.2) + specifier: 9.28.0 + version: 9.28.0(jiti@2.4.2) eslint-plugin-react: - specifier: ^7.37.5 - version: 7.37.5(eslint@9.39.4(jiti@2.4.2)) + specifier: 7.37.5 + version: 7.37.5(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-react-hooks: - specifier: ^7.0.1 - version: 7.0.1(eslint@9.39.4(jiti@2.4.2)) + specifier: 7.0.1 + version: 7.0.1(eslint@9.28.0(jiti@2.4.2)) eslint-plugin-react-refresh: - specifier: ^0.5.2 - version: 0.5.2(eslint@9.39.4(jiti@2.4.2)) + specifier: 0.5.2 + version: 0.5.2(eslint@9.28.0(jiti@2.4.2)) globals: - specifier: ^15.13.0 + specifier: 15.13.0 version: 15.13.0 jsdom: - specifier: ^25.0.0 - version: 25.0.1 + specifier: 25.0.0 + version: 25.0.0 optics-ts: - specifier: ^2.4.1 + specifier: 2.4.1 version: 2.4.1 postcss: - specifier: ^8.5.12 - version: 8.5.12 + specifier: 8.5.14 + version: 8.5.14 postcss-preset-mantine: - specifier: ^1.18.0 - version: 1.18.0(postcss@8.5.12) + specifier: 1.18.0 + version: 1.18.0(postcss@8.5.14) postcss-simple-vars: - specifier: ^7.0.1 - version: 7.0.1(postcss@8.5.12) + specifier: 7.0.1 + version: 7.0.1(postcss@8.5.14) prettier: - specifier: ^3.8.1 + specifier: 3.8.1 version: 3.8.1 typescript: - specifier: ^5.9.3 + specifier: 5.9.3 version: 5.9.3 typescript-eslint: - specifier: ^8.57.1 - version: 8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) + specifier: 8.57.1 + version: 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) vite: specifier: 8.0.5 - version: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) + version: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) vitest: - specifier: ^4.1.6 - version: 4.1.6(@opentelemetry/api@1.9.0)(@types/node@22.19.1)(happy-dom@20.8.9)(jsdom@25.0.1)(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) + specifier: 4.1.6 + version: 4.1.6(@opentelemetry/api@1.9.0)(@types/node@22.19.1)(happy-dom@20.8.9)(jsdom@25.0.0)(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) apps/server: dependencies: @@ -2237,14 +2237,30 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint/config-array@0.20.1': + resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-array@0.21.2': resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.2.3': + resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.4.2': resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.14.0': + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.15.2': + resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.17.0': resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2253,6 +2269,10 @@ packages: resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.28.0': + resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.39.4': resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2261,6 +2281,10 @@ packages: resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.3.5': + resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.4.1': resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4463,12 +4487,12 @@ packages: resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.9.1': - resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + '@testing-library/jest-dom@6.6.0': + resolution: {integrity: sha512-Y76dmd7C85xekWqylJqRmO6lr83cdVprTs0muSvkXr6M73auYK5OvZMc3tKe1F7wMFdzfeBCwVbkoGrRKWb+fg==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - '@testing-library/react@16.3.2': - resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + '@testing-library/react@16.1.0': + resolution: {integrity: sha512-Q2ToPvg0KsVL0ohND9A3zLJWcOXXcO8IDu3fj11KhNt0UlCWyFyvnCIBkd12tidB2lkiVRG8VFqdhcqhqnAQtg==} engines: {node: '>=18'} peerDependencies: '@testing-library/dom': ^10.0.0 @@ -5540,10 +5564,6 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} - array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} - engines: {node: '>= 0.4'} - array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} @@ -5571,10 +5591,6 @@ packages: resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} - engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.4: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} @@ -5787,10 +5803,6 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} - call-bind@1.0.8: resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} engines: {node: '>= 0.4'} @@ -5825,6 +5837,10 @@ packages: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -6135,9 +6151,6 @@ packages: resolution: {integrity: sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==} engines: {node: '>=18'} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -6301,26 +6314,14 @@ packages: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} - data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} - engines: {node: '>= 0.4'} - data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} - data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} - engines: {node: '>= 0.4'} - data-view-byte-length@1.0.2: resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} engines: {node: '>= 0.4'} - data-view-byte-offset@1.0.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} - engines: {node: '>= 0.4'} - data-view-byte-offset@1.0.1: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} @@ -6606,10 +6607,6 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-abstract@1.23.5: - resolution: {integrity: sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==} - engines: {node: '>= 0.4'} - es-abstract@1.24.1: resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} engines: {node: '>= 0.4'} @@ -6626,9 +6623,6 @@ packages: resolution: {integrity: sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ==} engines: {node: '>= 0.4'} - es-module-lexer@2.0.0: - resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - es-module-lexer@2.1.0: resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} @@ -6727,6 +6721,16 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + eslint@9.28.0: + resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + eslint@9.39.4: resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -6954,9 +6958,6 @@ packages: debug: optional: true - for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -7016,10 +7017,6 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} - engines: {node: '>= 0.4'} - function.prototype.name@1.1.8: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} @@ -7059,10 +7056,6 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} - engines: {node: '>= 0.4'} - get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -7137,10 +7130,6 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} - has-proto@1.2.0: resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} engines: {node: '>= 0.4'} @@ -7292,10 +7281,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} - engines: {node: '>= 0.4'} - internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -7326,10 +7311,6 @@ packages: resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} engines: {node: '>= 10'} - is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} - engines: {node: '>= 0.4'} - is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -7349,10 +7330,6 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-boolean-object@1.2.0: - resolution: {integrity: sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==} - engines: {node: '>= 0.4'} - is-boolean-object@1.2.2: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} @@ -7364,18 +7341,10 @@ packages: is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - is-data-view@1.0.1: - resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} - engines: {node: '>= 0.4'} - is-data-view@1.0.2: resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} - is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - is-date-object@1.1.0: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} @@ -7421,10 +7390,6 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-number-object@1.1.0: - resolution: {integrity: sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==} - engines: {node: '>= 0.4'} - is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -7439,10 +7404,6 @@ packages: is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - is-regex@1.2.0: - resolution: {integrity: sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==} - engines: {node: '>= 0.4'} - is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -7451,10 +7412,6 @@ packages: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} - is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} - engines: {node: '>= 0.4'} - is-shared-array-buffer@1.0.4: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} @@ -7463,26 +7420,14 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-string@1.1.0: - resolution: {integrity: sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==} - engines: {node: '>= 0.4'} - is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} - is-symbol@1.1.0: - resolution: {integrity: sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==} - engines: {node: '>= 0.4'} - is-symbol@1.1.1: resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} - is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} - is-typed-array@1.1.15: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} @@ -7499,9 +7444,6 @@ packages: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} - is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - is-weakref@1.1.1: resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} engines: {node: '>= 0.4'} @@ -7785,8 +7727,8 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsdom@25.0.1: - resolution: {integrity: sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==} + jsdom@25.0.0: + resolution: {integrity: sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==} engines: {node: '>=18'} peerDependencies: canvas: ^2.11.2 @@ -8555,10 +8497,6 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} - engines: {node: '>= 0.4'} - object.assign@4.1.7: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} @@ -8948,8 +8886,8 @@ packages: peerDependencies: postcss: ^8.2.1 - postcss@8.5.12: - resolution: {integrity: sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==} + postcss@8.5.14: + resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -9095,6 +9033,9 @@ packages: prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} @@ -9124,6 +9065,9 @@ packages: query-selector-shadow-dom@1.0.1: resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -9324,10 +9268,6 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - reflect.getprototypeof@1.0.7: - resolution: {integrity: sha512-bMvFGIUKlc/eSfXNX+aZ+EL95/EgZzuwA0OBPTbZZDEJw/0AkentjMuM1oiRfwHrshqk4RzdgiTg5CcDalXN5g==} - engines: {node: '>= 0.4'} - regenerate-unicode-properties@10.1.1: resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} engines: {node: '>=4'} @@ -9338,10 +9278,6 @@ packages: regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - regexp.prototype.flags@1.5.3: - resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} - engines: {node: '>= 0.4'} - regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} @@ -9365,6 +9301,9 @@ packages: require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -9446,10 +9385,6 @@ packages: rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - safe-array-concat@1.1.2: - resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} - engines: {node: '>=0.4'} - safe-array-concat@1.1.3: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} @@ -9464,10 +9399,6 @@ packages: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} - safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} - engines: {node: '>= 0.4'} - safe-regex-test@1.1.0: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} @@ -9710,13 +9641,6 @@ packages: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} - string.prototype.trim@1.2.9: - resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} - string.prototype.trimend@1.0.9: resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} engines: {node: '>= 0.4'} @@ -9920,6 +9844,10 @@ packages: resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} engines: {node: '>=14.16'} + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + tough-cookie@5.1.2: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} @@ -10046,26 +9974,14 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} - typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} - engines: {node: '>= 0.4'} - typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} - engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.3: resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.3: - resolution: {integrity: sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==} - engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.4: resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} @@ -10118,9 +10034,6 @@ packages: resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} engines: {node: '>=18'} - unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -10154,6 +10067,10 @@ packages: resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} engines: {node: '>=4'} + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -10174,6 +10091,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -10445,18 +10365,10 @@ packages: when-exit@2.1.5: resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} - which-boxed-primitive@1.1.0: - resolution: {integrity: sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==} - engines: {node: '>= 0.4'} - which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} - which-builtin-type@1.2.0: - resolution: {integrity: sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==} - engines: {node: '>= 0.4'} - which-builtin-type@1.2.1: resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} engines: {node: '>= 0.4'} @@ -10468,10 +10380,6 @@ packages: which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - which-typed-array@1.1.16: - resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==} - engines: {node: '>= 0.4'} - which-typed-array@1.1.20: resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} @@ -12430,6 +12338,11 @@ snapshots: '@esbuild/win32-x64@0.28.0': optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@9.28.0(jiti@2.4.2))': + dependencies: + eslint: 9.28.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.4.2))': dependencies: eslint: 9.39.4(jiti@2.4.2) @@ -12437,6 +12350,14 @@ snapshots: '@eslint-community/regexpp@4.12.2': {} + '@eslint/config-array@0.20.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + '@eslint/config-array@0.21.2': dependencies: '@eslint/object-schema': 2.1.7 @@ -12445,10 +12366,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/config-helpers@0.2.3': {} + '@eslint/config-helpers@0.4.2': dependencies: '@eslint/core': 0.17.0 + '@eslint/core@0.14.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/core@0.15.2': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 @@ -12467,10 +12398,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/js@9.28.0': {} + '@eslint/js@9.39.4': {} '@eslint/object-schema@2.1.7': {} + '@eslint/plugin-kit@0.3.5': + dependencies: + '@eslint/core': 0.15.2 + levn: 0.4.1 + '@eslint/plugin-kit@0.4.1': dependencies: '@eslint/core': 0.17.0 @@ -13065,7 +13003,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': @@ -14985,10 +14923,10 @@ snapshots: '@tabler/icons@3.40.0': {} - '@tanstack/eslint-plugin-query@5.94.4(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': + '@tanstack/eslint-plugin-query@5.94.4(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3) - eslint: 9.39.4(jiti@2.4.2) + '@typescript-eslint/utils': 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + eslint: 9.28.0(jiti@2.4.2) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -15020,16 +14958,17 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.9.1': + '@testing-library/jest-dom@6.6.0': dependencies: '@adobe/css-tools': 4.4.3 aria-query: 5.3.2 + chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 - picocolors: 1.1.1 + lodash: 4.18.1 redent: 3.0.0 - '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@testing-library/react@16.1.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.29.2 '@testing-library/dom': 10.4.1 @@ -15517,11 +15456,11 @@ snapshots: '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 8.56.10 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/eslint@8.56.10': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@types/estree@1.0.8': {} @@ -15686,7 +15625,7 @@ snapshots: '@types/react@18.3.12': dependencies: '@types/prop-types': 15.7.11 - csstype: 3.1.3 + csstype: 3.2.3 '@types/send@0.17.4': dependencies: @@ -15747,6 +15686,22 @@ snapshots: dependencies: '@types/node': 25.5.0 + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/type-utils': 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 + eslint: 9.28.0(jiti@2.4.2) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3))(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -15763,6 +15718,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 + debug: 4.4.3 + eslint: 9.28.0(jiti@2.4.2) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.57.1 @@ -15793,6 +15760,18 @@ snapshots: dependencies: typescript: 5.9.3 + '@typescript-eslint/type-utils@8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.28.0(jiti@2.4.2) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/type-utils@8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.57.1 @@ -15822,6 +15801,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.28.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + eslint: 9.28.0(jiti@2.4.2) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.4.2)) @@ -15922,10 +15912,10 @@ snapshots: '@vercel/oidc@3.1.0': {} - '@vitejs/plugin-react@6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitejs/plugin-react@6.0.1(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) '@vitest/expect@4.1.6': dependencies: @@ -15936,13 +15926,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.6(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3))': + '@vitest/mocker@4.1.6(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.1.6 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) '@vitest/pretty-format@4.1.6': dependencies: @@ -16187,11 +16177,6 @@ snapshots: aria-query@5.3.2: {} - array-buffer-byte-length@1.0.1: - dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 - array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 @@ -16199,57 +16184,46 @@ snapshots: array-includes@3.1.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.1 es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 - is-string: 1.1.0 + is-string: 1.1.1 array-timsort@1.0.3: {} array.prototype.findlast@1.2.5: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.1 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.0.2 array.prototype.flat@1.3.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.1 es-shim-unscopables: 1.0.2 array.prototype.flatmap@1.3.3: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.1 es-shim-unscopables: 1.0.2 array.prototype.tosorted@1.1.4: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.1 es-errors: 1.3.0 es-shim-unscopables: 1.0.2 - arraybuffer.prototype.slice@1.0.3: - dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.5 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.4 - is-shared-array-buffer: 1.0.3 - arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 @@ -16531,14 +16505,6 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.7: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - call-bind@1.0.8: dependencies: call-bind-apply-helpers: 1.0.2 @@ -16565,6 +16531,11 @@ snapshots: chai@6.2.2: {} + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -16890,8 +16861,6 @@ snapshots: '@asamuzakjp/css-color': 2.8.3 rrweb-cssom: 0.8.0 - csstype@3.1.3: {} - csstype@3.2.3: {} cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): @@ -17083,36 +17052,18 @@ snapshots: whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - data-view-buffer@1.0.1: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 - data-view-buffer@1.0.2: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 - data-view-byte-length@1.0.1: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 - data-view-byte-length@1.0.2: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 - data-view-byte-offset@1.0.0: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 - data-view-byte-offset@1.0.1: dependencies: call-bound: 1.0.4 @@ -17230,7 +17181,7 @@ snapshots: dom-helpers@5.2.1: dependencies: '@babel/runtime': 7.29.2 - csstype: 3.1.3 + csstype: 3.2.3 dom-serializer@2.0.0: dependencies: @@ -17368,55 +17319,6 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.23.5: - dependencies: - array-buffer-byte-length: 1.0.1 - arraybuffer.prototype.slice: 1.0.3 - available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - data-view-buffer: 1.0.1 - data-view-byte-length: 1.0.1 - data-view-byte-offset: 1.0.0 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.6 - get-intrinsic: 1.3.0 - get-symbol-description: 1.0.2 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.0.7 - is-array-buffer: 3.0.4 - is-callable: 1.2.7 - is-data-view: 1.0.1 - is-negative-zero: 2.0.3 - is-regex: 1.2.0 - is-shared-array-buffer: 1.0.3 - is-string: 1.1.0 - is-typed-array: 1.1.13 - is-weakref: 1.0.2 - object-inspect: 1.13.3 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.3 - safe-array-concat: 1.1.2 - safe-regex-test: 1.0.3 - string.prototype.trim: 1.2.9 - string.prototype.trimend: 1.0.8 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.2 - typed-array-byte-length: 1.0.1 - typed-array-byte-offset: 1.0.3 - typed-array-length: 1.0.7 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.16 - es-abstract@1.24.1: dependencies: array-buffer-byte-length: 1.0.2 @@ -17498,8 +17400,6 @@ snapshots: math-intrinsics: 1.1.0 safe-array-concat: 1.1.3 - es-module-lexer@2.0.0: {} - es-module-lexer@2.1.0: {} es-object-atoms@1.1.1: @@ -17520,8 +17420,8 @@ snapshots: es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.1.0 + is-date-object: 1.1.0 + is-symbol: 1.1.1 es6-promise-pool@2.5.0: {} @@ -17599,22 +17499,22 @@ snapshots: dependencies: eslint: 9.39.4(jiti@2.4.2) - eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.4.2)): + eslint-plugin-react-hooks@7.0.1(eslint@9.28.0(jiti@2.4.2)): dependencies: '@babel/core': 7.28.5 '@babel/parser': 7.28.5 - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.28.0(jiti@2.4.2) hermes-parser: 0.25.1 zod: 4.3.6 zod-validation-error: 4.0.2(zod@4.3.6) transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.5.2(eslint@9.39.4(jiti@2.4.2)): + eslint-plugin-react-refresh@0.5.2(eslint@9.28.0(jiti@2.4.2)): dependencies: - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.28.0(jiti@2.4.2) - eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.4.2)): + eslint-plugin-react@7.37.5(eslint@9.28.0(jiti@2.4.2)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -17622,7 +17522,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.3.1 - eslint: 9.39.4(jiti@2.4.2) + eslint: 9.28.0(jiti@2.4.2) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -17652,6 +17552,48 @@ snapshots: eslint-visitor-keys@5.0.1: {} + eslint@9.28.0(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.28.0(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.20.1 + '@eslint/config-helpers': 0.2.3 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.28.0 + '@eslint/plugin-kit': 0.3.5 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.3 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + eslint@9.39.4(jiti@2.4.2): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.4.2)) @@ -17955,10 +17897,6 @@ snapshots: follow-redirects@1.16.0: {} - for-each@0.3.3: - dependencies: - is-callable: 1.2.7 - for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -18027,13 +17965,6 @@ snapshots: function-bind@1.1.2: {} - function.prototype.name@1.1.6: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.5 - functions-have-names: 1.2.3 - function.prototype.name@1.1.8: dependencies: call-bind: 1.0.8 @@ -18075,12 +18006,6 @@ snapshots: get-stream@6.0.1: {} - get-symbol-description@1.0.2: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 @@ -18157,8 +18082,6 @@ snapshots: dependencies: es-define-property: 1.0.1 - has-proto@1.0.3: {} - has-proto@1.2.0: dependencies: dunder-proto: 1.0.1 @@ -18306,12 +18229,6 @@ snapshots: inherits@2.0.4: {} - internal-slot@1.0.7: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -18346,11 +18263,6 @@ snapshots: ipaddr.js@2.2.0: {} - is-array-buffer@3.0.4: - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.3.0 - is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -18371,11 +18283,6 @@ snapshots: dependencies: binary-extensions: 2.3.0 - is-boolean-object@1.2.0: - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 @@ -18387,20 +18294,12 @@ snapshots: dependencies: hasown: 2.0.2 - is-data-view@1.0.1: - dependencies: - is-typed-array: 1.1.13 - is-data-view@1.0.2: dependencies: call-bound: 1.0.4 get-intrinsic: 1.3.0 is-typed-array: 1.1.15 - is-date-object@1.0.5: - dependencies: - has-tostringtag: 1.0.2 - is-date-object@1.1.0: dependencies: call-bound: 1.0.4 @@ -18432,11 +18331,6 @@ snapshots: is-negative-zero@2.0.3: {} - is-number-object@1.1.0: - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -18448,13 +18342,6 @@ snapshots: is-promise@4.0.0: {} - is-regex@1.2.0: - dependencies: - call-bind: 1.0.7 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -18464,42 +18351,23 @@ snapshots: is-set@2.0.3: {} - is-shared-array-buffer@1.0.3: - dependencies: - call-bind: 1.0.7 - is-shared-array-buffer@1.0.4: dependencies: call-bound: 1.0.4 is-stream@2.0.1: {} - is-string@1.1.0: - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - is-string@1.1.1: dependencies: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-symbol@1.1.0: - dependencies: - call-bind: 1.0.7 - has-symbols: 1.1.0 - safe-regex-test: 1.0.3 - is-symbol@1.1.1: dependencies: call-bound: 1.0.4 has-symbols: 1.1.0 safe-regex-test: 1.1.0 - is-typed-array@1.1.13: - dependencies: - which-typed-array: 1.1.16 - is-typed-array@1.1.15: dependencies: which-typed-array: 1.1.20 @@ -18510,10 +18378,6 @@ snapshots: is-weakmap@2.0.2: {} - is-weakref@1.0.2: - dependencies: - call-bind: 1.0.7 - is-weakref@1.1.1: dependencies: call-bound: 1.0.4 @@ -18990,7 +18854,7 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@25.0.1: + jsdom@25.0.0: dependencies: cssstyle: 4.2.1 data-urls: 5.0.0 @@ -19005,7 +18869,7 @@ snapshots: rrweb-cssom: 0.7.1 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 5.1.2 + tough-cookie: 4.1.4 w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 @@ -19098,7 +18962,7 @@ snapshots: dependencies: array-includes: 3.1.8 array.prototype.flat: 1.3.2 - object.assign: 4.1.5 + object.assign: 4.1.7 object.values: 1.2.1 jszip@3.10.1: @@ -19729,13 +19593,6 @@ snapshots: object-keys@1.1.1: {} - object.assign@4.1.5: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - object.assign@4.1.7: dependencies: call-bind: 1.0.8 @@ -19754,9 +19611,9 @@ snapshots: object.fromentries@2.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.1 es-object-atoms: 1.1.1 object.values@1.2.1: @@ -20134,40 +19991,40 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-js@4.0.1(postcss@8.5.12): + postcss-js@4.0.1(postcss@8.5.14): dependencies: camelcase-css: 2.0.1 - postcss: 8.5.12 + postcss: 8.5.14 - postcss-mixins@12.1.2(postcss@8.5.12): + postcss-mixins@12.1.2(postcss@8.5.14): dependencies: - postcss: 8.5.12 - postcss-js: 4.0.1(postcss@8.5.12) - postcss-simple-vars: 7.0.1(postcss@8.5.12) - sugarss: 5.0.1(postcss@8.5.12) + postcss: 8.5.14 + postcss-js: 4.0.1(postcss@8.5.14) + postcss-simple-vars: 7.0.1(postcss@8.5.14) + sugarss: 5.0.1(postcss@8.5.14) tinyglobby: 0.2.15 - postcss-nested@7.0.2(postcss@8.5.12): + postcss-nested@7.0.2(postcss@8.5.14): dependencies: - postcss: 8.5.12 + postcss: 8.5.14 postcss-selector-parser: 7.1.1 - postcss-preset-mantine@1.18.0(postcss@8.5.12): + postcss-preset-mantine@1.18.0(postcss@8.5.14): dependencies: - postcss: 8.5.12 - postcss-mixins: 12.1.2(postcss@8.5.12) - postcss-nested: 7.0.2(postcss@8.5.12) + postcss: 8.5.14 + postcss-mixins: 12.1.2(postcss@8.5.14) + postcss-nested: 7.0.2(postcss@8.5.14) postcss-selector-parser@7.1.1: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-simple-vars@7.0.1(postcss@8.5.12): + postcss-simple-vars@7.0.1(postcss@8.5.14): dependencies: - postcss: 8.5.12 + postcss: 8.5.14 - postcss@8.5.12: + postcss@8.5.14: dependencies: nanoid: 3.3.8 picocolors: 1.1.1 @@ -20382,6 +20239,10 @@ snapshots: prr@1.0.1: optional: true + psl@1.15.0: + dependencies: + punycode: 2.3.1 + pump@3.0.3: dependencies: end-of-stream: 1.4.4 @@ -20407,6 +20268,8 @@ snapshots: query-selector-shadow-dom@1.0.1: {} + querystringify@2.2.0: {} + quick-format-unescaped@4.0.4: {} radix-ui@1.4.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -20677,16 +20540,6 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 - reflect.getprototypeof@1.0.7: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.5 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - which-builtin-type: 1.2.0 - regenerate-unicode-properties@10.1.1: dependencies: regenerate: 1.4.2 @@ -20697,13 +20550,6 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 - regexp.prototype.flags@1.5.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - set-function-name: 2.0.2 - regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -20732,6 +20578,8 @@ snapshots: require-main-filename@2.0.0: {} + requires-port@1.0.0: {} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -20832,13 +20680,6 @@ snapshots: dependencies: tslib: 2.8.1 - safe-array-concat@1.1.2: - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 @@ -20856,12 +20697,6 @@ snapshots: es-errors: 1.3.0 isarray: 2.0.5 - safe-regex-test@1.0.3: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-regex: 1.2.0 - safe-regex-test@1.1.0: dependencies: call-bound: 1.0.4 @@ -21149,14 +20984,14 @@ snapshots: gopd: 1.2.0 has-symbols: 1.1.0 internal-slot: 1.1.0 - regexp.prototype.flags: 1.5.3 + regexp.prototype.flags: 1.5.4 set-function-name: 2.0.2 side-channel: 1.1.0 string.prototype.repeat@1.0.0: dependencies: define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.1 string.prototype.trim@1.2.10: dependencies: @@ -21168,19 +21003,6 @@ snapshots: es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 - string.prototype.trim@1.2.9: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.5 - es-object-atoms: 1.1.1 - - string.prototype.trimend@1.0.8: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - string.prototype.trimend@1.0.9: dependencies: call-bind: 1.0.8 @@ -21190,7 +21012,7 @@ snapshots: string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -21239,9 +21061,9 @@ snapshots: stylis@4.3.6: {} - sugarss@5.0.1(postcss@8.5.12): + sugarss@5.0.1(postcss@8.5.14): dependencies: - postcss: 8.5.12 + postcss: 8.5.14 superagent@10.3.0: dependencies: @@ -21371,6 +21193,13 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 + tough-cookie@4.1.4: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + tough-cookie@5.1.2: dependencies: tldts: 6.1.72 @@ -21497,49 +21326,25 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.2 - typed-array-buffer@1.0.2: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-typed-array: 1.1.13 - typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-typed-array: 1.1.15 - typed-array-byte-length@1.0.1: - dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 - typed-array-byte-length@1.0.3: dependencies: call-bind: 1.0.8 - for-each: 0.3.3 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.3: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 - reflect.getprototypeof: 1.0.7 - typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 - for-each: 0.3.3 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 @@ -21547,12 +21352,23 @@ snapshots: typed-array-length@1.0.7: dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 + call-bind: 1.0.8 + for-each: 0.3.5 gopd: 1.2.0 - is-typed-array: 1.1.13 + is-typed-array: 1.1.15 possible-typed-array-names: 1.0.0 - reflect.getprototypeof: 1.0.7 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.9.3) + eslint: 9.28.0(jiti@2.4.2) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color typescript-eslint@8.57.1(eslint@9.39.4(jiti@2.4.2))(typescript@5.9.3): dependencies: @@ -21593,13 +21409,6 @@ snapshots: uint8array-extras@1.5.0: {} - unbox-primitive@1.0.2: - dependencies: - call-bind: 1.0.7 - has-bigints: 1.0.2 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.0 - unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -21626,6 +21435,8 @@ snapshots: unicode-property-aliases-ecmascript@2.1.0: {} + universalify@0.2.0: {} + universalify@2.0.1: {} unpipe@1.0.0: {} @@ -21664,6 +21475,11 @@ snapshots: dependencies: punycode: 2.3.1 + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + use-callback-ref@1.3.3(@types/react@18.3.12)(react@18.3.1): dependencies: react: 18.3.1 @@ -21724,11 +21540,11 @@ snapshots: vary@1.1.2: {} - vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3): + vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 - postcss: 8.5.12 + postcss: 8.5.14 rolldown: 1.0.0-rc.12 tinyglobby: 0.2.15 optionalDependencies: @@ -21737,15 +21553,15 @@ snapshots: fsevents: 2.3.3 jiti: 2.4.2 less: 4.2.0 - sugarss: 5.0.1(postcss@8.5.12) + sugarss: 5.0.1(postcss@8.5.14) terser: 5.39.0 tsx: 4.21.0 yaml: 2.8.3 - vitest@4.1.6(@opentelemetry/api@1.9.0)(@types/node@22.19.1)(happy-dom@20.8.9)(jsdom@25.0.1)(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)): + vitest@4.1.6(@opentelemetry/api@1.9.0)(@types/node@22.19.1)(happy-dom@20.8.9)(jsdom@25.0.0)(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)): dependencies: '@vitest/expect': 4.1.6 - '@vitest/mocker': 4.1.6(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) + '@vitest/mocker': 4.1.6(vite@8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/pretty-format': 4.1.6 '@vitest/runner': 4.1.6 '@vitest/snapshot': 4.1.6 @@ -21762,13 +21578,13 @@ snapshots: tinyexec: 1.1.2 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.12))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) + vite: 8.0.5(@types/node@22.19.1)(esbuild@0.28.0)(jiti@2.4.2)(less@4.2.0)(sugarss@5.0.1(postcss@8.5.14))(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 '@types/node': 22.19.1 happy-dom: 20.8.9 - jsdom: 25.0.1 + jsdom: 25.0.0 transitivePeerDependencies: - msw @@ -21825,7 +21641,7 @@ snapshots: webpack@5.106.0(@swc/core@1.5.25(@swc/helpers@0.5.5)): dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 @@ -21835,7 +21651,7 @@ snapshots: browserslist: 4.28.1 chrome-trace-event: 1.0.3 enhanced-resolve: 5.20.1 - es-module-lexer: 2.0.0 + es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -21878,14 +21694,6 @@ snapshots: when-exit@2.1.5: {} - which-boxed-primitive@1.1.0: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.0 - is-number-object: 1.1.0 - is-string: 1.1.0 - is-symbol: 1.1.0 - which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -21894,22 +21702,6 @@ snapshots: is-string: 1.1.1 is-symbol: 1.1.1 - which-builtin-type@1.2.0: - dependencies: - call-bind: 1.0.7 - function.prototype.name: 1.1.6 - has-tostringtag: 1.0.2 - is-async-function: 2.0.0 - is-date-object: 1.0.5 - is-finalizationregistry: 1.1.0 - is-generator-function: 1.0.10 - is-regex: 1.2.0 - is-weakref: 1.0.2 - isarray: 2.0.5 - which-boxed-primitive: 1.1.0 - which-collection: 1.0.2 - which-typed-array: 1.1.16 - which-builtin-type@1.2.1: dependencies: call-bound: 1.0.4 @@ -21922,7 +21714,7 @@ snapshots: is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 - which-boxed-primitive: 1.1.0 + which-boxed-primitive: 1.1.1 which-collection: 1.0.2 which-typed-array: 1.1.20 @@ -21935,14 +21727,6 @@ snapshots: which-module@2.0.1: {} - which-typed-array@1.1.16: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 From 299a9ca3c886f74ddddbed38578747e3ba463f81 Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Thu, 14 May 2026 02:54:00 +0100 Subject: [PATCH 38/46] fix: bug fixes (#2201) * fix(editor): hide transclusion borders and reset spacing in read-only mode * feat(share): add full width toggle for shared pages * feat(share): support resizing sidebar on shared pages * fix: auto redirect if there is only one SSO provider. - fix tighten sso redirect - fix share tree margin * sync * package overrides --- apps/client/src/ee/components/sso-login.tsx | 69 +- apps/client/src/ee/security/sso.utils.ts | 13 +- .../src/features/auth/hooks/use-auth.ts | 2 +- .../transclusion-reference-view.tsx | 1 + .../transclusion/transclusion-view.tsx | 1 + .../transclusion/transclusion.module.css | 31 +- .../features/share/atoms/shared-page-atom.ts | 7 +- .../features/share/components/share-shell.tsx | 73 +- .../share/components/share.module.css | 24 + apps/client/src/lib/app-route.ts | 42 +- apps/client/src/pages/share/shared-page.tsx | 8 +- apps/server/package.json | 4 +- apps/server/src/ee | 2 +- package.json | 9 +- pnpm-lock.yaml | 1232 ++++++----------- 15 files changed, 696 insertions(+), 822 deletions(-) diff --git a/apps/client/src/ee/components/sso-login.tsx b/apps/client/src/ee/components/sso-login.tsx index ff739dd35..3e84f8efc 100644 --- a/apps/client/src/ee/components/sso-login.tsx +++ b/apps/client/src/ee/components/sso-login.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { useWorkspacePublicDataQuery } from "@/features/workspace/queries/workspace-query.ts"; import { Button, Divider, Stack } from "@mantine/core"; import { IconLock, IconServer } from "@tabler/icons-react"; @@ -7,15 +7,37 @@ import { buildSsoLoginUrl } from "@/ee/security/sso.utils.ts"; import { SSO_PROVIDER } from "@/ee/security/contants.ts"; import { GoogleIcon } from "@/components/icons/google-icon.tsx"; import { LdapLoginModal } from "@/ee/components/ldap-login-modal.tsx"; +import { getRedirectParam } from "@/lib/app-route.ts"; +import useCurrentUser from "@/features/user/hooks/use-current-user.ts"; + +const SSO_AUTO_ATTEMPT_KEY = "docmost:ssoAutoAttempt"; +const SSO_AUTO_ATTEMPT_TTL_MS = 5 * 60_000; + +function recentAutoAttempt(): boolean { + try { + const raw = window.sessionStorage.getItem(SSO_AUTO_ATTEMPT_KEY); + if (!raw) return false; + const ts = Number(raw); + return Number.isFinite(ts) && Date.now() - ts < SSO_AUTO_ATTEMPT_TTL_MS; + } catch { + return false; + } +} + +function markAutoAttempt(): void { + try { + window.sessionStorage.setItem(SSO_AUTO_ATTEMPT_KEY, String(Date.now())); + } catch { + /* sessionStorage unavailable (private mode, etc.) — best effort */ + } +} export default function SsoLogin() { const { data, isLoading } = useWorkspacePublicDataQuery(); + const { data: currentUser } = useCurrentUser(); const [ldapModalOpened, setLdapModalOpened] = useState(false); const [selectedLdapProvider, setSelectedLdapProvider] = useState(null); - - if (!data?.authProviders || data?.authProviders?.length === 0) { - return null; - } + const autoRedirectedRef = useRef(false); const handleSsoLogin = (provider: IAuthProvider) => { if (provider.type === SSO_PROVIDER.LDAP) { @@ -28,10 +50,47 @@ export default function SsoLogin() { providerId: provider.id, type: provider.type, workspaceId: data.id, + redirect: getRedirectParam() ?? undefined, }); } }; + // Auto-redirect when SSO is enforced and there is exactly one non-LDAP + // provider. The user has no other option, so skip the extra click. + useEffect(() => { + if (autoRedirectedRef.current) return; + if (!data?.enforceSso) return; + if (!data.authProviders || data.authProviders.length !== 1) return; + const onlyProvider = data.authProviders[0]; + if (onlyProvider.type === SSO_PROVIDER.LDAP) return; + + // Already signed in: let useRedirectIfAuthenticated handle navigation + // instead of racing it through the IdP. + if (currentUser?.user) return; + + // Explicit logout: don't immediately bounce them back to the IdP. + const params = new URLSearchParams(window.location.search); + if (params.has("logout")) return; + + // Circuit-breaker: if we already auto-redirected within the TTL, the + // user came back (likely from an IdP failure). Show the page so they + // can read errors or pick a different account. + if (recentAutoAttempt()) return; + + autoRedirectedRef.current = true; + markAutoAttempt(); + window.location.href = buildSsoLoginUrl({ + providerId: onlyProvider.id, + type: onlyProvider.type, + workspaceId: data.id, + redirect: getRedirectParam() ?? undefined, + }); + }, [data, currentUser]); + + if (!data?.authProviders || data?.authProviders?.length === 0) { + return null; + } + const getProviderIcon = (provider: IAuthProvider) => { if (provider.type === SSO_PROVIDER.GOOGLE) { return ; diff --git a/apps/client/src/ee/security/sso.utils.ts b/apps/client/src/ee/security/sso.utils.ts index 4a4665c16..bfeb7c062 100644 --- a/apps/client/src/ee/security/sso.utils.ts +++ b/apps/client/src/ee/security/sso.utils.ts @@ -18,14 +18,21 @@ export function buildSsoLoginUrl(opts: { providerId: string; type: SSO_PROVIDER; workspaceId?: string; + redirect?: string; }): string { - const { providerId, type, workspaceId } = opts; + const { providerId, type, workspaceId, redirect } = opts; const domain = getAppUrl(); + const params = new URLSearchParams(); + if (redirect) params.set("redirect", redirect); + if (type === SSO_PROVIDER.GOOGLE) { - return `${getServerAppUrl()}/api/sso/${type}/login?workspaceId=${workspaceId}`; + if (workspaceId) params.set("workspaceId", workspaceId); + return `${getServerAppUrl()}/api/sso/${type}/login?${params.toString()}`; } - return `${domain}/api/sso/${type}/${providerId}/login`; + const query = params.toString(); + const base = `${domain}/api/sso/${type}/${providerId}/login`; + return query ? `${base}?${query}` : base; } export function getGoogleSignupUrl(): string { diff --git a/apps/client/src/features/auth/hooks/use-auth.ts b/apps/client/src/features/auth/hooks/use-auth.ts index 411e04b41..970a85897 100644 --- a/apps/client/src/features/auth/hooks/use-auth.ts +++ b/apps/client/src/features/auth/hooks/use-auth.ts @@ -166,7 +166,7 @@ export default function useAuth() { const handleLogout = async () => { setCurrentUser(RESET); await logout(); - window.location.replace(APP_ROUTE.AUTH.LOGIN); + window.location.replace(`${APP_ROUTE.AUTH.LOGIN}?logout=1`); }; const handleForgotPassword = async (data: IForgotPassword) => { diff --git a/apps/client/src/features/editor/components/transclusion/transclusion-reference-view.tsx b/apps/client/src/features/editor/components/transclusion/transclusion-reference-view.tsx index 490e179b2..e50793149 100644 --- a/apps/client/src/features/editor/components/transclusion/transclusion-reference-view.tsx +++ b/apps/client/src/features/editor/components/transclusion/transclusion-reference-view.tsx @@ -35,6 +35,7 @@ export default function TransclusionReferenceView(props: NodeViewProps) { return ( 0 ? "true" : "false"} contentEditable={false} diff --git a/apps/client/src/features/editor/components/transclusion/transclusion-view.tsx b/apps/client/src/features/editor/components/transclusion/transclusion-view.tsx index c27024472..82997f5d5 100644 --- a/apps/client/src/features/editor/components/transclusion/transclusion-view.tsx +++ b/apps/client/src/features/editor/components/transclusion/transclusion-view.tsx @@ -62,6 +62,7 @@ export default function TransclusionView(props: NodeViewProps) { return ( 0 ? "true" : "false"} data-id={transclusionId ?? undefined} > diff --git a/apps/client/src/features/editor/components/transclusion/transclusion.module.css b/apps/client/src/features/editor/components/transclusion/transclusion.module.css index 2fb5f7547..4d8d321a1 100644 --- a/apps/client/src/features/editor/components/transclusion/transclusion.module.css +++ b/apps/client/src/features/editor/components/transclusion/transclusion.module.css @@ -44,8 +44,29 @@ transition: border 0.3s; } -.transclusionWrap:hover, -.transclusionWrap:focus-within { +.transclusionWrap[data-editable="false"], +.includeWrap[data-editable="false"] { + margin-left: 0; + margin-right: 0; + width: 100%; + padding: 0; +} + +/* Cancel the wrapping .react-renderer's vertical spacing in read-only mode + so the synced block sits flush with surrounding paragraphs (whose own + margins already provide the right rhythm). */ +:global(.react-renderer.node-transclusionSource):has( + .transclusionWrap[data-editable="false"] + ), +:global(.react-renderer.node-transclusionReference):has( + .includeWrap[data-editable="false"] + ) { + margin-top: 0; + margin-bottom: 0; +} + +.transclusionWrap[data-editable="true"]:hover, +.transclusionWrap[data-editable="true"]:focus-within { border: 2px solid light-dark( var(--mantine-color-orange-2), @@ -114,9 +135,9 @@ transition: border 0.3s; } -.includeWrap:hover, -.includeWrap[data-focused="true"], -.includeWrap[data-menu-open="true"] { +.includeWrap[data-editable="true"]:hover, +.includeWrap[data-editable="true"][data-focused="true"], +.includeWrap[data-editable="true"][data-menu-open="true"] { border: 2px solid light-dark( var(--mantine-color-orange-2), diff --git a/apps/client/src/features/share/atoms/shared-page-atom.ts b/apps/client/src/features/share/atoms/shared-page-atom.ts index 813f5e61b..bf8929942 100644 --- a/apps/client/src/features/share/atoms/shared-page-atom.ts +++ b/apps/client/src/features/share/atoms/shared-page-atom.ts @@ -1,6 +1,11 @@ import { atom } from "jotai"; +import { atomWithStorage } from "jotai/utils"; import { ISharedPageTree } from "@/features/share/types/share.types"; import { SharedPageTreeNode } from "@/features/share/utils"; export const sharedPageTreeAtom = atom(null); -export const sharedTreeDataAtom = atom(null); \ No newline at end of file +export const sharedTreeDataAtom = atom(null); +export const sharedPageFullWidthAtom = atomWithStorage( + "sharedPageFullWidth", + false, +); \ No newline at end of file diff --git a/apps/client/src/features/share/components/share-shell.tsx b/apps/client/src/features/share/components/share-shell.tsx index bba226fe7..1bd559258 100644 --- a/apps/client/src/features/share/components/share-shell.tsx +++ b/apps/client/src/features/share/components/share-shell.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo } from "react"; +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { ActionIcon, AppShell, @@ -14,11 +14,16 @@ import { readOnlyEditorAtom } from "@/features/editor/atoms/editor-atoms.ts"; import { ThemeToggle } from "@/components/theme-toggle.tsx"; import { useAtomValue, useSetAtom } from "jotai"; import { useAtom } from "jotai"; -import { sharedPageTreeAtom, sharedTreeDataAtom } from "@/features/share/atoms/shared-page-atom"; +import { + sharedPageFullWidthAtom, + sharedPageTreeAtom, + sharedTreeDataAtom, +} from "@/features/share/atoms/shared-page-atom"; import { buildSharedPageTree } from "@/features/share/utils"; import { desktopSidebarAtom, mobileSidebarAtom, + sidebarWidthAtom, } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts"; import SidebarToggle from "@/components/ui/sidebar-toggle-button.tsx"; import { useTranslation } from "react-i18next"; @@ -27,7 +32,7 @@ import { mobileTableOfContentAsideAtom, tableOfContentAsideAtom, } from "@/features/share/atoms/sidebar-atom.ts"; -import { IconList } from "@tabler/icons-react"; +import { IconArrowsHorizontal, IconList } from "@tabler/icons-react"; import { useToggleToc } from "@/features/share/hooks/use-toggle-toc.ts"; import classes from "./share.module.css"; import { @@ -55,6 +60,46 @@ export default function ShareShell({ const [mobileTocOpened] = useAtom(mobileTableOfContentAsideAtom); const toggleTocMobile = useToggleToc(mobileTableOfContentAsideAtom); const toggleToc = useToggleToc(tableOfContentAsideAtom); + const [fullWidth, setFullWidth] = useAtom(sharedPageFullWidthAtom); + const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom); + const [isResizing, setIsResizing] = useState(false); + const sidebarRef = useRef(null); + + const startResizing = useCallback((e: React.MouseEvent) => { + e.preventDefault(); + setIsResizing(true); + }, []); + + const stopResizing = useCallback(() => { + setIsResizing(false); + }, []); + + const resize = useCallback( + (e: MouseEvent) => { + if (!isResizing || !sidebarRef.current) return; + const newWidth = + e.clientX - sidebarRef.current.getBoundingClientRect().left; + if (newWidth < 220) { + setSidebarWidth(220); + return; + } + if (newWidth > 600) { + setSidebarWidth(600); + return; + } + setSidebarWidth(newWidth); + }, + [isResizing, setSidebarWidth], + ); + + useEffect(() => { + window.addEventListener("mousemove", resize); + window.addEventListener("mouseup", stopResizing); + return () => { + window.removeEventListener("mousemove", resize); + window.removeEventListener("mouseup", stopResizing); + }; + }, [resize, stopResizing]); const { shareId } = useParams(); const { data } = useGetSharedPageTreeQuery(shareId); @@ -81,7 +126,7 @@ export default function ShareShell({ header={{ height: 50 }} {...(data?.pageTree?.length > 1 && { navbar: { - width: 300, + width: sidebarWidth, breakpoint: "sm", collapsed: { mobile: !mobileOpened, @@ -166,6 +211,20 @@ export default function ShareShell({ + + + setFullWidth((v) => !v)} + visibleFrom="sm" + size="sm" + > + + + @@ -174,7 +233,11 @@ export default function ShareShell({ {data?.pageTree?.length > 1 && ( - + +
)} diff --git a/apps/client/src/features/share/components/share.module.css b/apps/client/src/features/share/components/share.module.css index 617768ff1..ebf1e74cb 100644 --- a/apps/client/src/features/share/components/share.module.css +++ b/apps/client/src/features/share/components/share.module.css @@ -10,6 +10,7 @@ .treeNode { text-decoration: none; user-select: none; + padding-bottom: 0; } .navbar, @@ -18,3 +19,26 @@ width: 350px; } } + +.resizeHandle { + width: 3px; + cursor: col-resize; + position: absolute; + right: 0; + top: 0; + bottom: 0; + z-index: 1; + + &:hover, + &:active { + width: 5px; + background: light-dark( + var(--mantine-color-gray-4), + var(--mantine-color-dark-5) + ); + } + + @media (max-width: $mantine-breakpoint-sm) { + display: none; + } +} diff --git a/apps/client/src/lib/app-route.ts b/apps/client/src/lib/app-route.ts index e817c0722..48c1b87d1 100644 --- a/apps/client/src/lib/app-route.ts +++ b/apps/client/src/lib/app-route.ts @@ -31,20 +31,38 @@ const APP_ROUTE = { }, }; +export function safeRedirectPath(input: unknown): string | null { + if (typeof input !== "string") return null; + if (input.length === 0 || input.length > 2048) return null; + // Reject whitespace, backslash, and any Unicode "Other" category char + // (ASCII controls, zero-width space, BOM, bidi marks, etc). + if (/[\s\\]|\p{C}/u.test(input)) return null; + if (!input.startsWith("/") || input.startsWith("//")) return null; + if (input.toLowerCase().includes("://")) return null; + if (/^\/[a-z][a-z0-9+\-.]*:/i.test(input)) return null; + try { + const resolved = new URL(input, window.location.origin); + if (resolved.origin !== window.location.origin) return null; + return resolved.pathname + resolved.search + resolved.hash; + } catch { + return null; + } +} + export function getPostLoginRedirect(): string { const params = new URLSearchParams(window.location.search); - const redirect = params.get("redirect"); - if (redirect) { - try { - const resolved = new URL(redirect, window.location.origin); - if (resolved.origin === window.location.origin) { - return resolved.pathname + resolved.search + resolved.hash; - } - } catch { - // malformed URL, fall through to default - } - } - return APP_ROUTE.HOME; + return safeRedirectPath(params.get("redirect")) ?? APP_ROUTE.HOME; +} + +/** + * Returns the `?redirect=` value from the current URL only when it is a safe + * same-origin path. Unlike {@link getPostLoginRedirect} this returns `null` + * (not `/home`) when no redirect is present, so callers can distinguish + * "user came here directly" from "user was bounced from a deep link". + */ +export function getRedirectParam(): string | null { + const params = new URLSearchParams(window.location.search); + return safeRedirectPath(params.get("redirect")); } export default APP_ROUTE; diff --git a/apps/client/src/pages/share/shared-page.tsx b/apps/client/src/pages/share/shared-page.tsx index 0db817f60..f156208e5 100644 --- a/apps/client/src/pages/share/shared-page.tsx +++ b/apps/client/src/pages/share/shared-page.tsx @@ -9,7 +9,10 @@ import { extractPageSlugId } from "@/lib"; import { Error404 } from "@/components/ui/error-404.tsx"; import ShareBranding from "@/features/share/components/share-branding.tsx"; import { useAtomValue } from "jotai"; -import { sharedTreeDataAtom } from "@/features/share/atoms/shared-page-atom.ts"; +import { + sharedPageFullWidthAtom, + sharedTreeDataAtom, +} from "@/features/share/atoms/shared-page-atom.ts"; import { isPageInTree } from "@/features/share/utils.ts"; export default function SharedPage() { @@ -23,6 +26,7 @@ export default function SharedPage() { }); const sharedTreeData = useAtomValue(sharedTreeDataAtom); + const fullWidth = useAtomValue(sharedPageFullWidthAtom); useEffect(() => { if (shareId && data) { @@ -59,7 +63,7 @@ export default function SharedPage() { )} - + =20.0.0'} - '@aws-sdk/core@3.974.7': - resolution: {integrity: sha512-YhRC90ofz5oolTJZlA8voU/oUrCB2azi8Usx51k8hhB5LpWbYQMMXKUqSqkoL0Cru+RQJgWTHpAfEDDIwfUhJw==} + '@aws-sdk/core@3.974.9': + resolution: {integrity: sha512-bXxosFunr+v/kqNb99r1NRkrVBha7CG036fRSpWGbC1A/e363XFQN6wcZMx7MYTdRr1tYwNnkrWX2xc1rT3BCQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/crc64-nvme@3.972.7': - resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==} + '@aws-sdk/crc64-nvme@3.972.8': + resolution: {integrity: sha512-fVfUCL/Xh2zINYMPZvj+iBn6XWouQf0DAnjaWCI9MkmqXzL2Iy5FoQB8O7syFe6gN6AH1ecDDU58T51Ou0kFkA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.33': - resolution: {integrity: sha512-bJV7eViSJV6GSuuN+VIdNVPdwPsNSf75BiC2v5alPrjR/OCcqgKwSZInKbDFz9mNeizldsyf67jt6YSIiv53Cw==} + '@aws-sdk/credential-provider-env@3.972.35': + resolution: {integrity: sha512-WkFQ8BedszVomhh/Zzs8WwnE/XBmTqZjoQVB8u/4zH6kZCjouXZpPpb93gD8m0EZmzAl7dxHE/y+yDpuKzNCMw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.35': - resolution: {integrity: sha512-x/BQGEIdq0oI+4WxLjKmnQvT7CnF9r8ezdGt7wXwxb7ckHXQz0Zmgxt8v3Ne0JaT3R5YefmuybHX6E8EnsDXyA==} + '@aws-sdk/credential-provider-http@3.972.37': + resolution: {integrity: sha512-ylx0ZJTU+2eNcvXQ69VNR3TVSYa/ibpvdK717/NxqR9aXRMn2QRWZaiI8aa5yY/fOWZ5mknSmxGaVxxtdwv3EA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.37': - resolution: {integrity: sha512-eUTpmWfd/BKsq9medhCRcu+GRAhFP2Zrn7/2jKDHHOOjCkhrMoTp/t4cEthqFoG7gE0VGp5wUxrXTdvBCmSmJg==} + '@aws-sdk/credential-provider-ini@3.972.39': + resolution: {integrity: sha512-QhRSrdkk+Gq0AFIylpiI0N6lcJqFYV9Jtr4Luz5FpYOYbjJSfyTG6iLhnK/UPIgN1Jnon8WAmSC//16XYGvwkA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.37': - resolution: {integrity: sha512-Ty68y8ISSC+g5Q3D0K8uAaoINwvfaOslnNpsF/LgVUxyosYXHawcK2yV4HLXDVugiTTYLQfJfcw0ce5meAGkKw==} + '@aws-sdk/credential-provider-login@3.972.39': + resolution: {integrity: sha512-1hU0NtC04QbFIuoBuF4aQ2A97GsSE5/A0ZJpDijwexsBREIQ4KPRYl3v/FfKCPBYsaTeGjkOFx5nLhWHY24LOw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.38': - resolution: {integrity: sha512-BQ9XYnBDVxR2HuV5huXYQYF/PZMTsY+EnwfGnCU2cA8Zw63XpkOtPY8WqiMIZMQCrKPQQEiFURS/o9CIolRLqg==} + '@aws-sdk/credential-provider-node@3.972.40': + resolution: {integrity: sha512-ZgrQaGkpyTlVSCCsffzijVg+KgftTAWYvI5Otc36J/4jNiHb+7MmBiJIR0a5AHLvifC92PiYHt5pijP0dswd1w==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.33': - resolution: {integrity: sha512-yfjGksI9WQbdMObb0VeLXqzTLI+a0qXLJT9gCDiv0+X/xjPpI3mTz6a5FibrhpuEKIe0gSgvs3MaoFZy5cx4WA==} + '@aws-sdk/credential-provider-process@3.972.35': + resolution: {integrity: sha512-hNj1rAwZWT1vfz54BwH8FUWxZuqStrM25Q5LEIwn2erHPMRVAjLlpZqEbCEEqS99eEEOhdeetnS0WeNa3iYeEQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.37': - resolution: {integrity: sha512-fpwE+20ntpp3i9Xb9vUuQfXLDKYHH+5I2V+ZG96SX1nBzrruhy10RXDgmN7t1etOz3c55stlA3TeQASUA451NQ==} + '@aws-sdk/credential-provider-sso@3.972.39': + resolution: {integrity: sha512-mwIPNPldyCZkvHozb6E0X/vuQLN1UCjcA6MwUf1gaO7EwghCmuNZXatq0L3zptKFvPC4Nds7+WFUkifI1XmbSw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.37': - resolution: {integrity: sha512-aryawqyebf+3WhAFNHfF62rekFpYtVcVN7dQ89qnAWsa4n5hJst8qBG6gXC24WHtW7Nnhkf9ScYnjwo0Brn3bw==} + '@aws-sdk/credential-provider-web-identity@3.972.39': + resolution: {integrity: sha512-b9HT8CnpyPVn1hU14Q7ihjwSPlRzToYmRYJxRd5jNHEZ43lrIhoLaTT8JmfQQt5j5M8rTX1iN1X8mvu0SM1dXA==} engines: {node: '>=20.0.0'} '@aws-sdk/lib-storage@3.1040.0': @@ -1057,20 +1058,20 @@ packages: peerDependencies: '@aws-sdk/client-s3': ^3.1040.0 - '@aws-sdk/middleware-bucket-endpoint@3.972.10': - resolution: {integrity: sha512-Vbc2frZH7wXlMNd+ZZSXUEs/l1Sv8Jj4zUnIfwrYF5lwaLdXHZ9xx4U3rjUcaye3HRhFVc+E5DbBxpRAbB16BA==} + '@aws-sdk/middleware-bucket-endpoint@3.972.11': + resolution: {integrity: sha512-AhVDn+qObNacklqmBABnFa3YfVk08CzksuuecL/x+lo95dZxXuAkqJZLUsAEKQ3EiDd5E9wTUBjh0cSogmKMYA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-expect-continue@3.972.10': - resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==} + '@aws-sdk/middleware-expect-continue@3.972.11': + resolution: {integrity: sha512-xpobcctR1AHSrvkiArgTyLffn78Lt9unPMpa/yic9RKn+bOf/5M55UIM6RaPL5xKzI06/GSsTDywTWvzEAbyyw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.974.15': - resolution: {integrity: sha512-j4Zp7rA1HfhDTteICnx/tPax4N/v5wmytgguXExUGyEwQ8Ug4EBA4kjp9puFAN1UZoBVpxoiXMiuTFvjaHjeEw==} + '@aws-sdk/middleware-flexible-checksums@3.974.17': + resolution: {integrity: sha512-Js24a6sdH9SU5DI5++nlQJayCuOweiiTjnCcAsY75/JtaXF+xysDQ6nRBYx6pUPNY22viRYmdDTFZDaA9AF46g==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-host-header@3.972.10': - resolution: {integrity: sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==} + '@aws-sdk/middleware-host-header@3.972.11': + resolution: {integrity: sha512-CBC6+tVYaOJo7QXgN1zJ4Ba2f3/Cpy4eRViYFimXW/O5Mn8hBmgXXzHu4vy4ubT80YWnp8aCFygr7dTOa14yQg==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-location-constraint@3.972.10': @@ -1081,67 +1082,63 @@ packages: resolution: {integrity: sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-recursion-detection@3.972.11': - resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} + '@aws-sdk/middleware-recursion-detection@3.972.12': + resolution: {integrity: sha512-5eltYxKB4MfdQv7/VhWxRbAVQKow5dz9votRFigTYrWJHMQXwLMltlbk7KFWSZh5NDBySfmjT7Jv/DWfYCmDng==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.36': - resolution: {integrity: sha512-YhPix+0x/MdQrb1Ug1GDKeS5fqylIy+naz800asX8II4jqfTk2KY2KhmmYCwZcky8YWtRQQwWCGdoqeAnip8Uw==} + '@aws-sdk/middleware-sdk-s3@3.972.38': + resolution: {integrity: sha512-Yuv3urkJtd1/b3kIURzHwihc1SV6n1t+uiXffOD2OpylZ7+4/QnO2W73yhLZzK1Z762BaqwQ3IVRqAHWzNbQ4A==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-ssec@3.972.10': resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.37': - resolution: {integrity: sha512-N1oNpdiLoVAWYD3WFBnUi3LlfoDA06ZHo4ozyjbsJNLvILzvt//0CnR8N+CZ0NWeYgVB/5V59ivixHCWCx2ALw==} + '@aws-sdk/middleware-user-agent@3.972.39': + resolution: {integrity: sha512-MlNSvNsSVlMKKWaCzA0GP1nS4Cuq3WCXUN1vmMvd+Ctztib5kmRcpmTtKx9kikN8szAc+gcdp7uqJJervV2nQg==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.997.5': - resolution: {integrity: sha512-jGFr6DxtcMTmzOkG/a0jCZYv4BBDmeNYVeO+/memSoDkYCJu4Y58xviYmzwJfYyIVSts+X/BVjJm1uGBnwHEMg==} + '@aws-sdk/nested-clients@3.997.7': + resolution: {integrity: sha512-jT2AXOODobQfTYGC2SChMSnZ/voIcRV/LHlY1suyhY1bdgP/voKkhEg8Ci1jiGQ4lBiaso5BEAV3ZWWpPTfmYA==} engines: {node: '>=20.0.0'} - '@aws-sdk/region-config-resolver@3.972.13': - resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} + '@aws-sdk/region-config-resolver@3.972.14': + resolution: {integrity: sha512-VuLXVmm7+lKVxqFcOItPkXhjbJ02iUfxkxheRu41SfWf6/xrZup2A2SwHZos/LeQGu3SBHeqTQht80Uo3ienPA==} engines: {node: '>=20.0.0'} '@aws-sdk/s3-request-presigner@3.1040.0': resolution: {integrity: sha512-AmesZGG/B5sDIiWahyY11fOkXSsuHc7LciE88YFURehMVSdEORo2Vzz1d2kBgmJG9oar5Vmmwf9X/w7mqb7ytg==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.24': - resolution: {integrity: sha512-amP7tLikppN940wbBFISYqiuzVmpzMS9U3mcgtmVLjX4fdWI/SNCvrXv6ZxfVzTT4cT0rPKOLhFah2xLwzREWw==} + '@aws-sdk/signature-v4-multi-region@3.996.26': + resolution: {integrity: sha512-2N62veqdMZBCwQUHsbhtnaovOFjOa5Dn3dAD1nRqFTUXR4QmirT3HZnfus/L1DS08Vm5CkoKmL0iMVt6YbqEag==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1039.0': - resolution: {integrity: sha512-NMSFL2HwkAOoCeLCQiqoOq5pT3vVbSjww2QZTuYgYknVwhhv125PSDzZIcL5EYnlxuPWjEOdauZK+FspkZDVdw==} + '@aws-sdk/token-providers@3.1046.0': + resolution: {integrity: sha512-9je8nZt+ntB8IjhpGNayU/AkBgvq/f4aFO2bH1LSNC5JX6K8zY4LUnr/ymqunePrwq+B5OVBpL7ILjYzMFSZAw==} engines: {node: '>=20.0.0'} '@aws-sdk/types@3.973.8': resolution: {integrity: sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-arn-parser@3.972.3': - resolution: {integrity: sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==} + '@aws-sdk/util-endpoints@3.996.9': + resolution: {integrity: sha512-ibx8Vd73rCTHekNGeXX8cpGWoBKbNAlwKHL3yjSxxttu5QnNDaSAM7/0MFYDjU31/F4lyrPoQcGirT0ew61xcg==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.996.8': - resolution: {integrity: sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-format-url@3.972.10': - resolution: {integrity: sha512-DEKiHNJVtNxdyTeQspzY+15Po/kHm6sF0Cs4HV9Q2+lplB63+DrvdeiSoOSdWEWAoO2RcY1veoXVDz2tWxWCgQ==} + '@aws-sdk/util-format-url@3.972.11': + resolution: {integrity: sha512-LSzASo5djqKTUWWHhmuj9oZ6KHLaH8eUKhZLPi75imT3CcNqzkPflU9+mwl7jHP9ROsC0dSarcnpDYwyp9J/uw==} engines: {node: '>=20.0.0'} '@aws-sdk/util-locate-window@3.535.0': resolution: {integrity: sha512-PHJ3SL6d2jpcgbqdgiPxkXpu7Drc2PYViwxSIqvvMKhDwzSB1W3mMvtpzwKM4IE7zLFodZo0GKjJ9AsoXndXhA==} engines: {node: '>=14.0.0'} - '@aws-sdk/util-user-agent-browser@3.972.10': - resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} + '@aws-sdk/util-user-agent-browser@3.972.11': + resolution: {integrity: sha512-kq3RS6XQtHMrLFShbkem6h+8fxazB3jEIsbMC6aaSInOciRGE+eGAqTgJ+obO7Euo/pjM8thVqLiLISEH9X9DA==} - '@aws-sdk/util-user-agent-node@3.973.23': - resolution: {integrity: sha512-gGwq8L2Euw0aNG6Ey4EktiAo3fSCVoDy1CaBIthd+oeaKHPXUrNaApMewQ6La5Hv0lcznOtECZaNvYyc5LXXfA==} + '@aws-sdk/util-user-agent-node@3.973.25': + resolution: {integrity: sha512-066hKH/0nvV7x4ofV/iK9kz8r/qNfcR6rzuEOFqI2vQL/fcTTsDAbTw0jmXkyMzANK8ltQdALj19ns3zuOJiUw==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1149,8 +1146,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.22': - resolution: {integrity: sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==} + '@aws-sdk/xml-builder@3.972.23': + resolution: {integrity: sha512-A0YmgYFv+hTI9c17Ntvd2hSehm9bmJfkb+ggADBwVKA8H/3+Jx94SzR2qOB9bAA9WFeDqnfz9PKKQ+D+YAKomA==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.3': @@ -1817,21 +1814,12 @@ packages: '@chevrotain/cst-dts-gen@11.0.3': resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} - '@chevrotain/cst-dts-gen@11.1.2': - resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==} - '@chevrotain/gast@11.0.3': resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==} - '@chevrotain/gast@11.1.2': - resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==} - '@chevrotain/regexp-to-ast@11.0.3': resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==} - '@chevrotain/regexp-to-ast@11.1.2': - resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==} - '@chevrotain/types@11.0.3': resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==} @@ -1841,9 +1829,6 @@ packages: '@chevrotain/utils@11.0.3': resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} - '@chevrotain/utils@11.1.2': - resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} - '@clickhouse/client-common@1.18.2': resolution: {integrity: sha512-J0SG6q9V31ydxonglpj9xhNRsUxCsF71iEZ784yldqMYwsHixj/9xHFDgBDX3DuMiDx/kPDfXnf+pimp08wIBA==} @@ -2413,7 +2398,7 @@ packages: resolution: {integrity: sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==} engines: {node: '>=18.14.1'} peerDependencies: - hono: 4.12.14 + hono: 4.12.18 '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -2729,8 +2714,8 @@ packages: '@keyv/serialize@1.1.1': resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} - '@langchain/core@1.1.39': - resolution: {integrity: sha512-DP9c7TREy6iA7HnywstmUAsNyJNYTFpRg2yBfQ+6H0l1HnvQzei9GsQ36GeOLxgRaD3vm9K8urCcawSC7yQpCw==} + '@langchain/core@1.1.46': + resolution: {integrity: sha512-i8rDC83BpItxChCw4Lf+6tAr+k+OUcbirc5ZkrhI9ywYWmvxegUljLGOGYvtJNTbEAIFkhYIODPE5QRqyjF6sA==} engines: {node: '>=20'} '@langchain/textsplitters@1.0.1': @@ -2811,8 +2796,8 @@ packages: '@mermaid-js/parser@0.6.3': resolution: {integrity: sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==} - '@mermaid-js/parser@1.0.1': - resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==} + '@mermaid-js/parser@1.1.1': + resolution: {integrity: sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw==} '@modelcontextprotocol/sdk@1.29.0': resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} @@ -3280,8 +3265,8 @@ packages: '@protobufjs/base64@1.1.2': resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} '@protobufjs/eventemitter@1.1.0': resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} @@ -3292,8 +3277,8 @@ packages: '@protobufjs/float@1.0.2': resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + '@protobufjs/inquire@1.1.1': + resolution: {integrity: sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew==} '@protobufjs/path@1.1.2': resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} @@ -3301,8 +3286,8 @@ packages: '@protobufjs/pool@1.1.0': resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@protobufjs/utf8@1.1.1': + resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} @@ -4140,217 +4125,156 @@ packages: '@slidoapp/emoji-mart@5.8.7': resolution: {integrity: sha512-zn8CBoZRFY0M0Tps0rFgcbu1nhQDmnSoD8CqkTVobI9k3MK2WHIYRp50DXhMxRoQnoct4nomrVaY9kU01ARDTQ==} - '@smithy/chunked-blob-reader-native@4.2.3': - resolution: {integrity: sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==} + '@smithy/config-resolver@4.5.1': + resolution: {integrity: sha512-abXk3LhODsvRHsk0ZS9ztrg/fZatTa9Z/z4pgx65YSLR+rY6kvUG/1IgcDKEUciR8MfdnkT5oPeHJTy/HhzDIQ==} engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader@5.2.2': - resolution: {integrity: sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==} + '@smithy/core@3.24.1': + resolution: {integrity: sha512-3mT7o4qQyUWttYnVK3A0Z/u3Xha3E81tXn32Tz6vjZiUXhBrkEivpw1hBYfh84iFF9CSzkBU9Y1DJ3Q6RQ231g==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.4.17': - resolution: {integrity: sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==} + '@smithy/credential-provider-imds@4.3.1': + resolution: {integrity: sha512-0S/acwHnqX4WrjXzhdiDRxsG2s9SC0cpPIK9nZ1R6UOHd+j7uL28+4bHu22urbLk2TVw3fkp6na/+fkUt/pLNQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.23.17': - resolution: {integrity: sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==} + '@smithy/eventstream-serde-browser@4.3.1': + resolution: {integrity: sha512-X7MyI1fu8M84IPKk49kO4kb27Mqp6un9/0o/MsA1ngZ5OxxWKGUxPS3S/AJ9q1cPVTSGmRcbaGNfGUSsflTJkg==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.2.14': - resolution: {integrity: sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==} + '@smithy/eventstream-serde-config-resolver@4.4.1': + resolution: {integrity: sha512-JZGbSXaBk7JY8VPzsh66ksJ0nTWXbApduFDkA/pEl3aTm2EoAiUZE1Iltp6c+X1bB8kxPQW0mHDfVdYCpWTOzg==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.2.14': - resolution: {integrity: sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==} + '@smithy/eventstream-serde-node@4.3.1': + resolution: {integrity: sha512-6Cn4xTNVxn9PWTHSbvf8zmcDhQW8lrLE1Xq5CJgmX6wEvdjS2S0KuE79Aiznv/jx51jpFJ98OuWyE+Bt+oG1MQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.2.14': - resolution: {integrity: sha512-8IelTCtTctWRbb+0Dcy+C0aICh1qa0qWXqgjcXDmMuCvPJRnv26hiDZoAau2ILOniki65mCPKqOQs/BaWvO4CQ==} + '@smithy/fetch-http-handler@5.4.1': + resolution: {integrity: sha512-r7bN6spQ+caZC8AnyvSxkRUb57zt2jhhRw3Z+2Ez8hjq6coIikDBFUUI/+CQ1xx9K6eX1Gx6wUKo4ylU66TIqw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.3.14': - resolution: {integrity: sha512-sqHiHpYRYo3FJlaIxD1J8PhbcmJAm7IuM16mVnwSkCToD7g00IBZzKuiLNMGmftULmEUX6/UAz8/NN5uMP8bVA==} + '@smithy/hash-blob-browser@4.3.1': + resolution: {integrity: sha512-2fbltQVQYmGd0OzPv2oDMRF0pxkzeIx8cbpx2x6W3UJWGaEyUzVPxF4d0sDXZ/r2obg+RbTyhTidXWlPDsKRKw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.2.14': - resolution: {integrity: sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw==} + '@smithy/hash-node@4.3.1': + resolution: {integrity: sha512-u0/zo11mg7yNneoYgTkH4sXwSmcBpbl49o4UNCtQ7hYsXxynsN25KYHmXzqi7TPk5HQL5klGnpU5koOY0O+9hw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.2.14': - resolution: {integrity: sha512-lWyt4T2XQZUZgK3tQ3Wn0w3XBvZsK/vjTuJl6bXbnGZBHH0ZUSONTYiK9TgjTTzU54xQr3DRFwpjmhp0oLm3gg==} + '@smithy/hash-stream-node@4.3.1': + resolution: {integrity: sha512-4NOnngIoXngbJw9By3u8KXRgqt4vYATpAobNBnNWxOREP7JY3kB0bUmbBNhZ7dtZV/b4auO1eFMD4cLj9OauVg==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.17': - resolution: {integrity: sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-blob-browser@4.2.15': - resolution: {integrity: sha512-0PJ4Al3fg2nM4qKrAIxyNcApgqHAXcBkN8FeizOz69z0rb26uZ6lMESYtxegaTlXB5Hj84JfwMPavMrwDMjucA==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-node@4.2.14': - resolution: {integrity: sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-stream-node@4.2.14': - resolution: {integrity: sha512-tw4GANWkZPb6+BdD4Fgucqzey2+r73Z/GRo9zklsCdwrnxxumUV83ZIaBDdudV4Ylazw3EPTiJZhpX42105ruQ==} - engines: {node: '>=18.0.0'} - - '@smithy/invalid-dependency@4.2.14': - resolution: {integrity: sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==} + '@smithy/invalid-dependency@4.3.1': + resolution: {integrity: sha512-cLmwtDoulyZvRepAfyV+3rx5oMvuh51dbE+6En3vGC09j3uVSRt1U4oguNu32ub3soGX0oYtBs8E7S2Q4SxTqg==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/is-array-buffer@4.2.2': - resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} + '@smithy/md5-js@4.3.1': + resolution: {integrity: sha512-98NalujRdzv6ggVQNYPWpL2K57UKeUB8roIr61u6+JiHd7KUlMQ+sn/vk6IG4XxEjw2vlC7eu/xjYXshUE4XXg==} engines: {node: '>=18.0.0'} - '@smithy/md5-js@4.2.14': - resolution: {integrity: sha512-V2v0vx+h0iUSNG1Alt+GNBMSLGCrl9iVsdd+Ap67HPM9PN479x12V8LkuMoKImNZxn3MXeuyUjls+/7ZACZghA==} + '@smithy/middleware-content-length@4.3.1': + resolution: {integrity: sha512-l4BUIP+wljW/Ar+0/QcGdmElI9lalrywfzNijXMBG34Z510FRzPyrDLx/blNTZOAm0C4Mvx5t/bf760CZo1ajg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.14': - resolution: {integrity: sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==} + '@smithy/middleware-endpoint@4.5.1': + resolution: {integrity: sha512-qtqu5TS+8Y18ZDkJoiXN5AMW1G4JAg1+xytzpsUvIR5a4EUsgd5HQg12lekEHWpm2TDUmOgg+hBaHK7dvyWdkA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.32': - resolution: {integrity: sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==} + '@smithy/middleware-retry@4.6.1': + resolution: {integrity: sha512-eTaQhxs0rfUuAkL2MSKrH8DTO7YCeAgrdN0B2/RAeuHmXQ+x52dk5qUBsi/jtcqe5LxItgq5AG5tI6Cp8c0sow==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.5.7': - resolution: {integrity: sha512-bRt6ZImqVSeTk39Nm81K20ObIiAZ3WefY7G6+iz/0tZjs4dgRRjvRX2sgsH+zi6iDCRR/aQvQofLKxxz4rPBZg==} + '@smithy/middleware-serde@4.3.1': + resolution: {integrity: sha512-t7YtUe076zWVypVmy1rX91oKi2TFJCkpfFpfMhJFpEIRPP0iL9JxjeSyFQ+1bF45JUfDzOzslUJa150WcSrBug==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.20': - resolution: {integrity: sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==} + '@smithy/middleware-stack@4.3.1': + resolution: {integrity: sha512-1jKwiKZxCMQNqmp4uVPYA6r+MLGjEtH07gnOUdPgbnjuOIrl/0JY/ICdpQtFgeBsQ/Up01gnSv8GYEL0fb8yvg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.14': - resolution: {integrity: sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==} + '@smithy/node-config-provider@4.4.1': + resolution: {integrity: sha512-q7tDJEJXcaSG/8TVpu2f2l9bzxTzDM9geWmltbzsY6Hfh3yiuXXTpLIO8+zwYASPPVFaTJpdKwjSSjdoDoccgw==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.14': - resolution: {integrity: sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==} + '@smithy/node-http-handler@4.7.1': + resolution: {integrity: sha512-BdEYko85f/ldp68uH8XEyIvo810xFk6eyPH81SRggTOApYHWA+Xu7B2EzLuHbe37WVLaUA7F1fWR3/zBeme2WA==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.6.1': - resolution: {integrity: sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==} + '@smithy/protocol-http@5.4.1': + resolution: {integrity: sha512-8irPNCQgYxcSFp1aGcnDNFkTwSA+xPUaFq9V/v1+JXWu8sKr5b3cFmg2kBTkjkvypDmGeNffuNu0x5iqw1NoAw==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.2.14': - resolution: {integrity: sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==} + '@smithy/signature-v4@5.4.1': + resolution: {integrity: sha512-728lZZEWYWubBESrfntNslZQYDKRlJDY4dcDnYbL50+gu35pGPLblu4S0/RH/RDLF6me1M87ECHsHELGL7dA/Q==} engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.3.14': - resolution: {integrity: sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==} - engines: {node: '>=18.0.0'} - - '@smithy/querystring-builder@4.2.14': - resolution: {integrity: sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==} - engines: {node: '>=18.0.0'} - - '@smithy/querystring-parser@4.2.14': - resolution: {integrity: sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==} - engines: {node: '>=18.0.0'} - - '@smithy/service-error-classification@4.3.1': - resolution: {integrity: sha512-aUQuDGh760ts/8MU+APjIZhlLPKhIIfqyzZaJikLEIMrdxFvxuLYD0WxWzaYWpmLbQlXDe9p7EWM3HsBe0K6Gw==} - engines: {node: '>=18.0.0'} - - '@smithy/shared-ini-file-loader@4.4.9': - resolution: {integrity: sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==} - engines: {node: '>=18.0.0'} - - '@smithy/signature-v4@5.3.14': - resolution: {integrity: sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==} - engines: {node: '>=18.0.0'} - - '@smithy/smithy-client@4.12.13': - resolution: {integrity: sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==} + '@smithy/smithy-client@4.13.1': + resolution: {integrity: sha512-IcznNM8Qd9u1X3oflp12tkzyOB4HbT+sfYWlWiyEysgNzSHoWcHUUsTT4y1jjDjtVuuVVQbYks+g1kVd7u1eGQ==} engines: {node: '>=18.0.0'} '@smithy/types@4.14.1': resolution: {integrity: sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==} engines: {node: '>=18.0.0'} - '@smithy/url-parser@4.2.14': - resolution: {integrity: sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==} + '@smithy/url-parser@4.3.1': + resolution: {integrity: sha512-tuelFlF2PZR/wogFC58NIrPOv+Zna4N1+3kA161/33D1Gbwvl6Nh4WsAsW05ZyPp0O6CMGsdbb0S2b/qVjRMCw==} engines: {node: '>=18.0.0'} - '@smithy/util-base64@4.3.2': - resolution: {integrity: sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==} + '@smithy/util-base64@4.4.1': + resolution: {integrity: sha512-fTHiwW2xbiRiWzfSk4IGAr3gNZCH4fuRYqt8+IuarsP/YON35576iVdePraZ6yJlFxlCL0eMec3/F7xYqoKzlg==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-browser@4.2.2': - resolution: {integrity: sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==} + '@smithy/util-body-length-browser@4.3.1': + resolution: {integrity: sha512-1scg5t4nV3hV7CZs996/XHb80aDZ5YotH4NcvkW/w/rHj+cSz0aCIzwz8aUNKB4nCDPSHRCbrKoj+TvycYefmw==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-node@4.2.3': - resolution: {integrity: sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==} + '@smithy/util-body-length-node@4.3.1': + resolution: {integrity: sha512-VRC8MKVPKrgUYThTA7ughcKMfjW6/X92H0wXGJoda0Apw4O5xbXL0GMLz40DTWlsb5hh2iItk6+XL72uJdxYcw==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} - '@smithy/util-buffer-from@4.2.2': - resolution: {integrity: sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==} + '@smithy/util-defaults-mode-browser@4.4.1': + resolution: {integrity: sha512-1rA7w+LjK1WJClsffC81Z/ZtjFt22QsKhBjUYEnZsGVS2nOTfOENKBzdg4SxhdwFvBCjcbpjscUfXOPwE3UHWQ==} engines: {node: '>=18.0.0'} - '@smithy/util-config-provider@4.2.2': - resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} + '@smithy/util-defaults-mode-node@4.3.1': + resolution: {integrity: sha512-1fk1wfQHBenQD5NitVKOFgW0wsISYAFPIXGyStJWAeCtMyRhgHYvtJxBk2rwGWA0L5QX6oM6yeHSLKPFMk59ww==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.49': - resolution: {integrity: sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==} + '@smithy/util-endpoints@3.5.1': + resolution: {integrity: sha512-yORYzJD5zoGbSDkAACr0dIjDiSEA3X8h8lggDENl1dkKpCG0TQIoItPBqtvuJHzFFjRXumcoH+/09xIuixGyCw==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.54': - resolution: {integrity: sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==} + '@smithy/util-middleware@4.3.1': + resolution: {integrity: sha512-SRRMDcIgVXVhVbxviBaSZbuWuVW3jD08wv4ESV0V2oiw0Mki8TPVQ5IxwD3MvSTPg52QYsRP+JoMw5WdUdeWAg==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.4.2': - resolution: {integrity: sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg==} + '@smithy/util-retry@4.4.1': + resolution: {integrity: sha512-qkgWgwn1xw0GoY9Ea/B6FrYSPfHA0zyOtJkokwxZuvucRf2+2lfTut6adi4e4Y7LEAaxsFG7r6i05mtDCxbHKA==} engines: {node: '>=18.0.0'} - '@smithy/util-hex-encoding@4.2.2': - resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} - engines: {node: '>=18.0.0'} - - '@smithy/util-middleware@4.2.14': - resolution: {integrity: sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-retry@4.3.6': - resolution: {integrity: sha512-p6/FO1n2KxMeQyna067i0uJ6TSbb165ZhnRtCpWh4Foxqbfc6oW+XITaL8QkFJj3KFnDe2URt4gOhgU06EP9ew==} - engines: {node: '>=18.0.0'} - deprecated: '@smithy/util-retry v4.3.6 contains a bug in Adaptive Retry, see https://github.com/smithy-lang/smithy-typescript/issues/1993. Upgrade to 4.3.7+' - - '@smithy/util-stream@4.5.25': - resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==} - engines: {node: '>=18.0.0'} - - '@smithy/util-uri-escape@4.2.2': - resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} + '@smithy/util-stream@4.6.1': + resolution: {integrity: sha512-GjZfEft0M0V3n2YM/LGkr5LeLd8gxHUIzW0rUz6VtTtlAq245GxHlJghvoPEjJHKTj255iHFAiA4IsIdK40Ueg==} engines: {node: '>=18.0.0'} '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@smithy/util-utf8@4.2.2': - resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} + '@smithy/util-utf8@4.3.1': + resolution: {integrity: sha512-FtRrSnriXtOs4+J8/y9SbQ1xmN71hrOsN/YJr5PQQj5nR1l7YNkGS/TEk4gr0WN7gyrUqw8/RFaYVjI18732ZA==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.3.0': - resolution: {integrity: sha512-JyjYmLAfS+pdxF92o4yLgEoy0zhayKTw73FU1aofLWwLcJw7iSqIY2exGmMTrl/lmZugP5p/zxdFSippJDfKWA==} - engines: {node: '>=18.0.0'} - - '@smithy/uuid@1.1.2': - resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} + '@smithy/util-waiter@4.4.1': + resolution: {integrity: sha512-G/gWDykZNL0NVcd1qXkoKm45jxJECp6q53DSomM5QKMsyAMEsGksVq+HwgonqYxfFJEzzHi6ljtWKXVS1pl0/Q==} engines: {node: '>=18.0.0'} '@socket.io/component-emitter@3.1.0': @@ -5871,9 +5795,6 @@ packages: chevrotain@11.0.3: resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==} - chevrotain@11.1.2: - resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -6641,6 +6562,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es-toolkit@1.46.1: + resolution: {integrity: sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==} + es6-promise-pool@2.5.0: resolution: {integrity: sha512-VHErXfzR/6r/+yyzPKeBvO0lgjfC5cbDCQWjWwMZWSb6YU39TGIl51OUmCfWCq4ylMdJSB8zkz2vIuIeIxXApA==} engines: {node: '>=0.10.0'} @@ -7166,8 +7090,8 @@ packages: highlightjs-sap-abap@0.3.0: resolution: {integrity: sha512-nSiUvEOCycjtFA3pHaTowrbAAk5+lciBHyoVkDsd6FTRBtW9sT2dt42o2jAKbXjZVUidtacdk+j0Y2xnd233Mw==} - hono@4.12.14: - resolution: {integrity: sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==} + hono@4.12.18: + resolution: {integrity: sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==} engines: {node: '>=16.9.0'} hookified@1.15.1: @@ -7299,8 +7223,8 @@ packages: resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} - ip-address@10.1.0: - resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + ip-address@10.1.1: + resolution: {integrity: sha512-1FMu8/N15Ck1BL551Jf42NYIoin2unWjLQ2Fze/DXryJRl5twqtwNHlO39qERGbIOcKYWHdgRryhOC+NG4eaLw==} engines: {node: '>= 12'} ipaddr.js@1.9.1: @@ -7891,20 +7815,16 @@ packages: postgres: optional: true - kysely@0.28.14: - resolution: {integrity: sha512-SU3lgh0rPvq7upc6vvdVrCsSMUG1h3ChvHVOY7wJ2fw4C9QEB7X3d5eyYEyULUX7UQtxZJtZXGuT6U2US72UYA==} - engines: {node: '>=20.0.0'} + kysely@0.29.0: + resolution: {integrity: sha512-LrQfPUeTW7MXbMvT62moEMnpMTuj9TO3lqjCeLKjM975PJ4Alrl/43f2tlDX7xOsNptKgH4LSNGwIbXwEkLg4g==} + engines: {node: '>=22.0.0'} langium@3.3.1: resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} engines: {node: '>=16.0.0'} - langium@4.2.1: - resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} - engines: {node: '>=20.10.0', npm: '>=10.2.3'} - - langsmith@0.5.19: - resolution: {integrity: sha512-5tFoETuFMvGkbPGsINNlIE4Ab86CsPhdPOQZCGwNt/NX0h5NDKQLKOWS/G2XcRUBOQl4mCNbrayUvUTWaIRsCg==} + langsmith@0.7.0: + resolution: {integrity: sha512-iiPAGHJZ3uIHGnnLSkgcYZ4+thzhsGp5U48pWuW3ETgCRtbYzoDxYJigiQ3iWkK8ovF7Vr37tYvbI1ZE0tB+6A==} peerDependencies: '@opentelemetry/api': '*' '@opentelemetry/exporter-trace-otlp-proto': '*' @@ -8226,8 +8146,8 @@ packages: merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - mermaid@11.13.0: - resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==} + mermaid@11.15.0: + resolution: {integrity: sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw==} methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} @@ -9018,8 +8938,8 @@ packages: prosemirror-view@1.40.0: resolution: {integrity: sha512-2G3svX0Cr1sJjkD/DYWSe3cfV5VPVTBOxI9XQEGWJDFEpsZb/gh4MV29ctv+OJx2RFX4BLt09i+6zaGM/ldkCw==} - protobufjs@7.5.5: - resolution: {integrity: sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==} + protobufjs@7.5.6: + resolution: {integrity: sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg==} engines: {node: '>=12.0.0'} proxy-addr@2.0.7: @@ -10288,9 +10208,6 @@ packages: vscode-uri@3.0.8: resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -10851,182 +10768,164 @@ snapshots: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.7 - '@aws-sdk/credential-provider-node': 3.972.38 - '@aws-sdk/middleware-bucket-endpoint': 3.972.10 - '@aws-sdk/middleware-expect-continue': 3.972.10 - '@aws-sdk/middleware-flexible-checksums': 3.974.15 - '@aws-sdk/middleware-host-header': 3.972.10 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/credential-provider-node': 3.972.40 + '@aws-sdk/middleware-bucket-endpoint': 3.972.11 + '@aws-sdk/middleware-expect-continue': 3.972.11 + '@aws-sdk/middleware-flexible-checksums': 3.974.17 + '@aws-sdk/middleware-host-header': 3.972.11 '@aws-sdk/middleware-location-constraint': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10 - '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-sdk-s3': 3.972.36 + '@aws-sdk/middleware-recursion-detection': 3.972.12 + '@aws-sdk/middleware-sdk-s3': 3.972.38 '@aws-sdk/middleware-ssec': 3.972.10 - '@aws-sdk/middleware-user-agent': 3.972.37 - '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.24 + '@aws-sdk/middleware-user-agent': 3.972.39 + '@aws-sdk/region-config-resolver': 3.972.14 + '@aws-sdk/signature-v4-multi-region': 3.996.26 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.8 - '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.23 - '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.17 - '@smithy/eventstream-serde-browser': 4.2.14 - '@smithy/eventstream-serde-config-resolver': 4.3.14 - '@smithy/eventstream-serde-node': 4.2.14 - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/hash-blob-browser': 4.2.15 - '@smithy/hash-node': 4.2.14 - '@smithy/hash-stream-node': 4.2.14 - '@smithy/invalid-dependency': 4.2.14 - '@smithy/md5-js': 4.2.14 - '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-retry': 4.5.7 - '@smithy/middleware-serde': 4.2.20 - '@smithy/middleware-stack': 4.2.14 - '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.1 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 + '@aws-sdk/util-endpoints': 3.996.9 + '@aws-sdk/util-user-agent-browser': 3.972.11 + '@aws-sdk/util-user-agent-node': 3.973.25 + '@smithy/config-resolver': 4.5.1 + '@smithy/core': 3.24.1 + '@smithy/eventstream-serde-browser': 4.3.1 + '@smithy/eventstream-serde-config-resolver': 4.4.1 + '@smithy/eventstream-serde-node': 4.3.1 + '@smithy/fetch-http-handler': 5.4.1 + '@smithy/hash-blob-browser': 4.3.1 + '@smithy/hash-node': 4.3.1 + '@smithy/hash-stream-node': 4.3.1 + '@smithy/invalid-dependency': 4.3.1 + '@smithy/md5-js': 4.3.1 + '@smithy/middleware-content-length': 4.3.1 + '@smithy/middleware-endpoint': 4.5.1 + '@smithy/middleware-retry': 4.6.1 + '@smithy/middleware-serde': 4.3.1 + '@smithy/middleware-stack': 4.3.1 + '@smithy/node-config-provider': 4.4.1 + '@smithy/node-http-handler': 4.7.1 + '@smithy/protocol-http': 5.4.1 + '@smithy/smithy-client': 4.13.1 '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-base64': 4.3.2 - '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.49 - '@smithy/util-defaults-mode-node': 4.2.54 - '@smithy/util-endpoints': 3.4.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 - '@smithy/util-waiter': 4.3.0 + '@smithy/url-parser': 4.3.1 + '@smithy/util-base64': 4.4.1 + '@smithy/util-body-length-browser': 4.3.1 + '@smithy/util-body-length-node': 4.3.1 + '@smithy/util-defaults-mode-browser': 4.4.1 + '@smithy/util-defaults-mode-node': 4.3.1 + '@smithy/util-endpoints': 3.5.1 + '@smithy/util-middleware': 4.3.1 + '@smithy/util-retry': 4.4.1 + '@smithy/util-stream': 4.6.1 + '@smithy/util-utf8': 4.3.1 + '@smithy/util-waiter': 4.4.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.974.7': + '@aws-sdk/core@3.974.9': dependencies: '@aws-sdk/types': 3.973.8 - '@aws-sdk/xml-builder': 3.972.22 - '@smithy/core': 3.23.17 - '@smithy/node-config-provider': 4.3.14 - '@smithy/property-provider': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.13 + '@aws-sdk/xml-builder': 3.972.23 + '@smithy/core': 3.24.1 + '@smithy/signature-v4': 5.4.1 '@smithy/types': 4.14.1 - '@smithy/util-base64': 4.3.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/crc64-nvme@3.972.7': + '@aws-sdk/crc64-nvme@3.972.8': dependencies: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.33': + '@aws-sdk/credential-provider-env@3.972.35': dependencies: - '@aws-sdk/core': 3.974.7 + '@aws-sdk/core': 3.974.9 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.35': + '@aws-sdk/credential-provider-http@3.972.37': dependencies: - '@aws-sdk/core': 3.974.7 + '@aws-sdk/core': 3.974.9 '@aws-sdk/types': 3.973.8 - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.1 - '@smithy/property-provider': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 + '@smithy/core': 3.24.1 + '@smithy/fetch-http-handler': 5.4.1 + '@smithy/node-http-handler': 4.7.1 '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.25 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.37': + '@aws-sdk/credential-provider-ini@3.972.39': dependencies: - '@aws-sdk/core': 3.974.7 - '@aws-sdk/credential-provider-env': 3.972.33 - '@aws-sdk/credential-provider-http': 3.972.35 - '@aws-sdk/credential-provider-login': 3.972.37 - '@aws-sdk/credential-provider-process': 3.972.33 - '@aws-sdk/credential-provider-sso': 3.972.37 - '@aws-sdk/credential-provider-web-identity': 3.972.37 - '@aws-sdk/nested-clients': 3.997.5 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/credential-provider-env': 3.972.35 + '@aws-sdk/credential-provider-http': 3.972.37 + '@aws-sdk/credential-provider-login': 3.972.39 + '@aws-sdk/credential-provider-process': 3.972.35 + '@aws-sdk/credential-provider-sso': 3.972.39 + '@aws-sdk/credential-provider-web-identity': 3.972.39 + '@aws-sdk/nested-clients': 3.997.7 '@aws-sdk/types': 3.973.8 - '@smithy/credential-provider-imds': 4.2.14 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/core': 3.24.1 + '@smithy/credential-provider-imds': 4.3.1 '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.37': + '@aws-sdk/credential-provider-login@3.972.39': dependencies: - '@aws-sdk/core': 3.974.7 - '@aws-sdk/nested-clients': 3.997.5 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/nested-clients': 3.997.7 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.38': + '@aws-sdk/credential-provider-node@3.972.40': dependencies: - '@aws-sdk/credential-provider-env': 3.972.33 - '@aws-sdk/credential-provider-http': 3.972.35 - '@aws-sdk/credential-provider-ini': 3.972.37 - '@aws-sdk/credential-provider-process': 3.972.33 - '@aws-sdk/credential-provider-sso': 3.972.37 - '@aws-sdk/credential-provider-web-identity': 3.972.37 + '@aws-sdk/credential-provider-env': 3.972.35 + '@aws-sdk/credential-provider-http': 3.972.37 + '@aws-sdk/credential-provider-ini': 3.972.39 + '@aws-sdk/credential-provider-process': 3.972.35 + '@aws-sdk/credential-provider-sso': 3.972.39 + '@aws-sdk/credential-provider-web-identity': 3.972.39 '@aws-sdk/types': 3.973.8 - '@smithy/credential-provider-imds': 4.2.14 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/core': 3.24.1 + '@smithy/credential-provider-imds': 4.3.1 '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.33': + '@aws-sdk/credential-provider-process@3.972.35': dependencies: - '@aws-sdk/core': 3.974.7 + '@aws-sdk/core': 3.974.9 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.37': + '@aws-sdk/credential-provider-sso@3.972.39': dependencies: - '@aws-sdk/core': 3.974.7 - '@aws-sdk/nested-clients': 3.997.5 - '@aws-sdk/token-providers': 3.1039.0 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/nested-clients': 3.997.7 + '@aws-sdk/token-providers': 3.1046.0 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.37': + '@aws-sdk/credential-provider-web-identity@3.972.39': dependencies: - '@aws-sdk/core': 3.974.7 - '@aws-sdk/nested-clients': 3.997.5 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/nested-clients': 3.997.7 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: @@ -11035,53 +10934,46 @@ snapshots: '@aws-sdk/lib-storage@3.1040.0(@aws-sdk/client-s3@3.1040.0)': dependencies: '@aws-sdk/client-s3': 3.1040.0 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 + '@smithy/middleware-endpoint': 4.5.1 + '@smithy/protocol-http': 5.4.1 + '@smithy/smithy-client': 4.13.1 '@smithy/types': 4.14.1 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: 2.8.1 - '@aws-sdk/middleware-bucket-endpoint@3.972.10': + '@aws-sdk/middleware-bucket-endpoint@3.972.11': dependencies: + '@aws-sdk/core': 3.974.9 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 - tslib: 2.8.1 - - '@aws-sdk/middleware-expect-continue@3.972.10': - dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/protocol-http': 5.3.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.974.15': + '@aws-sdk/middleware-expect-continue@3.972.11': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.1 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-flexible-checksums@3.974.17': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.974.7 - '@aws-sdk/crc64-nvme': 3.972.7 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/crc64-nvme': 3.972.8 '@aws-sdk/types': 3.973.8 - '@smithy/is-array-buffer': 4.2.2 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.972.10': + '@aws-sdk/middleware-host-header@3.972.11': dependencies: '@aws-sdk/types': 3.973.8 - '@smithy/protocol-http': 5.3.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 @@ -11097,29 +10989,22 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.972.11': + '@aws-sdk/middleware-recursion-detection@3.972.12': dependencies: '@aws-sdk/types': 3.973.8 '@aws/lambda-invoke-store': 0.2.3 - '@smithy/protocol-http': 5.3.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.36': + '@aws-sdk/middleware-sdk-s3@3.972.38': dependencies: - '@aws-sdk/core': 3.974.7 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/signature-v4-multi-region': 3.996.26 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/core': 3.23.17 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.13 + '@smithy/core': 3.24.1 + '@smithy/signature-v4': 5.4.1 '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 '@aws-sdk/middleware-ssec@3.972.10': @@ -11128,96 +11013,70 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.37': + '@aws-sdk/middleware-user-agent@3.972.39': dependencies: - '@aws-sdk/core': 3.974.7 + '@aws-sdk/core': 3.974.9 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.8 - '@smithy/core': 3.23.17 - '@smithy/protocol-http': 5.3.14 + '@aws-sdk/util-endpoints': 3.996.9 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 - '@smithy/util-retry': 4.3.6 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.997.5': + '@aws-sdk/nested-clients@3.997.7': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.7 - '@aws-sdk/middleware-host-header': 3.972.10 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/middleware-host-header': 3.972.11 '@aws-sdk/middleware-logger': 3.972.10 - '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.37 - '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.24 + '@aws-sdk/middleware-recursion-detection': 3.972.12 + '@aws-sdk/middleware-user-agent': 3.972.39 + '@aws-sdk/region-config-resolver': 3.972.14 + '@aws-sdk/signature-v4-multi-region': 3.996.26 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.8 - '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.23 - '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.17 - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/hash-node': 4.2.14 - '@smithy/invalid-dependency': 4.2.14 - '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-retry': 4.5.7 - '@smithy/middleware-serde': 4.2.20 - '@smithy/middleware-stack': 4.2.14 - '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.1 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 + '@aws-sdk/util-endpoints': 3.996.9 + '@aws-sdk/util-user-agent-browser': 3.972.11 + '@aws-sdk/util-user-agent-node': 3.973.25 + '@smithy/core': 3.24.1 + '@smithy/fetch-http-handler': 5.4.1 + '@smithy/node-http-handler': 4.7.1 '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-base64': 4.3.2 - '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.49 - '@smithy/util-defaults-mode-node': 4.2.54 - '@smithy/util-endpoints': 3.4.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.972.13': + '@aws-sdk/region-config-resolver@3.972.14': dependencies: '@aws-sdk/types': 3.973.8 - '@smithy/config-resolver': 4.4.17 - '@smithy/node-config-provider': 4.3.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 '@aws-sdk/s3-request-presigner@3.1040.0': dependencies: - '@aws-sdk/signature-v4-multi-region': 3.996.24 + '@aws-sdk/signature-v4-multi-region': 3.996.26 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-format-url': 3.972.10 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 + '@aws-sdk/util-format-url': 3.972.11 + '@smithy/middleware-endpoint': 4.5.1 + '@smithy/protocol-http': 5.4.1 + '@smithy/smithy-client': 4.13.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.24': + '@aws-sdk/signature-v4-multi-region@3.996.26': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.36 '@aws-sdk/types': 3.973.8 - '@smithy/protocol-http': 5.3.14 - '@smithy/signature-v4': 5.3.14 + '@smithy/core': 3.24.1 + '@smithy/signature-v4': 5.4.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1039.0': + '@aws-sdk/token-providers@3.1046.0': dependencies: - '@aws-sdk/core': 3.974.7 - '@aws-sdk/nested-clients': 3.997.5 + '@aws-sdk/core': 3.974.9 + '@aws-sdk/nested-clients': 3.997.7 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 transitivePeerDependencies: @@ -11228,46 +11087,38 @@ snapshots: '@smithy/types': 4.14.1 tslib: 2.8.1 - '@aws-sdk/util-arn-parser@3.972.3': - dependencies: - tslib: 2.8.1 - - '@aws-sdk/util-endpoints@3.996.8': + '@aws-sdk/util-endpoints@3.996.9': dependencies: '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-endpoints': 3.4.2 tslib: 2.8.1 - '@aws-sdk/util-format-url@3.972.10': + '@aws-sdk/util-format-url@3.972.11': dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/querystring-builder': 4.2.14 - '@smithy/types': 4.14.1 + '@aws-sdk/core': 3.974.9 tslib: 2.8.1 '@aws-sdk/util-locate-window@3.535.0': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.972.10': + '@aws-sdk/util-user-agent-browser@3.972.11': dependencies: '@aws-sdk/types': 3.973.8 '@smithy/types': 4.14.1 bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.23': + '@aws-sdk/util-user-agent-node@3.973.25': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.37 + '@aws-sdk/middleware-user-agent': 3.972.39 '@aws-sdk/types': 3.973.8 - '@smithy/node-config-provider': 4.3.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.22': + '@aws-sdk/xml-builder@3.972.23': dependencies: '@nodable/entities': 2.1.0 '@smithy/types': 4.14.1 @@ -12090,34 +11941,19 @@ snapshots: '@chevrotain/types': 11.0.3 lodash-es: 4.18.1 - '@chevrotain/cst-dts-gen@11.1.2': - dependencies: - '@chevrotain/gast': 11.1.2 - '@chevrotain/types': 11.1.2 - lodash-es: 4.18.1 - '@chevrotain/gast@11.0.3': dependencies: '@chevrotain/types': 11.0.3 lodash-es: 4.18.1 - '@chevrotain/gast@11.1.2': - dependencies: - '@chevrotain/types': 11.1.2 - lodash-es: 4.18.1 - '@chevrotain/regexp-to-ast@11.0.3': {} - '@chevrotain/regexp-to-ast@11.1.2': {} - '@chevrotain/types@11.0.3': {} '@chevrotain/types@11.1.2': {} '@chevrotain/utils@11.0.3': {} - '@chevrotain/utils@11.1.2': {} - '@clickhouse/client-common@1.18.2': {} '@clickhouse/client@1.18.2': @@ -12476,7 +12312,7 @@ snapshots: dependencies: '@excalidraw/markdown-to-text': 0.1.2 '@mermaid-js/parser': 0.6.3 - mermaid: 11.13.0 + mermaid: 11.15.0 nanoid: 4.0.2 '@excalidraw/random-username@1.1.0': {} @@ -12618,9 +12454,9 @@ snapshots: y-prosemirror: 1.3.7(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.40.0)(y-protocols@1.0.6(yjs@13.6.30))(yjs@13.6.30) yjs: 13.6.30 - '@hono/node-server@1.19.13(hono@4.12.14)': + '@hono/node-server@1.19.13(hono@4.12.18)': dependencies: - hono: 4.12.14 + hono: 4.12.18 '@humanfs/core@0.19.1': {} @@ -13043,18 +12879,14 @@ snapshots: '@keyv/serialize@1.1.1': {} - '@langchain/core@1.1.39(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0)': + '@langchain/core@1.1.46(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0)': dependencies: '@cfworker/json-schema': 4.1.1 '@standard-schema/spec': 1.1.0 - ansi-styles: 5.2.0 - camelcase: 6.3.0 - decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.5.19(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) + langsmith: 0.7.0(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) mustache: 4.2.0 p-queue: 6.6.2 - uuid: 11.1.0 zod: 4.3.6 transitivePeerDependencies: - '@opentelemetry/api' @@ -13063,9 +12895,9 @@ snapshots: - openai - ws - '@langchain/textsplitters@1.0.1(@langchain/core@1.1.39(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))': + '@langchain/textsplitters@1.0.1(@langchain/core@1.1.46(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))': dependencies: - '@langchain/core': 1.1.39(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) + '@langchain/core': 1.1.46(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) js-tiktoken: 1.0.21 '@lifeomic/attempt@3.0.3': {} @@ -13141,13 +12973,13 @@ snapshots: dependencies: langium: 3.3.1 - '@mermaid-js/parser@1.0.1': + '@mermaid-js/parser@1.1.1': dependencies: - langium: 4.2.1 + '@chevrotain/types': 11.1.2 '@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@4.3.6)': dependencies: - '@hono/node-server': 1.19.13(hono@4.12.14) + '@hono/node-server': 1.19.13(hono@4.12.18) ajv: 8.18.0 ajv-formats: 3.0.1(ajv@8.18.0) content-type: 1.0.5 @@ -13157,7 +12989,7 @@ snapshots: eventsource-parser: 3.0.6 express: 5.2.1 express-rate-limit: 8.2.2(express@5.2.1) - hono: 4.12.14 + hono: 4.12.18 jose: 6.1.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -13585,7 +13417,7 @@ snapshots: '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - protobufjs: 7.5.5 + protobufjs: 7.5.6 '@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0)': dependencies: @@ -13641,24 +13473,24 @@ snapshots: '@protobufjs/base64@1.1.2': {} - '@protobufjs/codegen@2.0.4': {} + '@protobufjs/codegen@2.0.5': {} '@protobufjs/eventemitter@1.1.0': {} '@protobufjs/fetch@1.1.0': dependencies: '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 + '@protobufjs/inquire': 1.1.1 '@protobufjs/float@1.0.2': {} - '@protobufjs/inquire@1.1.0': {} + '@protobufjs/inquire@1.1.1': {} '@protobufjs/path@1.1.2': {} '@protobufjs/pool@1.1.0': {} - '@protobufjs/utf8@1.1.0': {} + '@protobufjs/utf8@1.1.1': {} '@radix-ui/number@1.1.1': {} @@ -14502,251 +14334,148 @@ snapshots: '@slidoapp/emoji-mart@5.8.7': {} - '@smithy/chunked-blob-reader-native@4.2.3': + '@smithy/config-resolver@4.5.1': dependencies: - '@smithy/util-base64': 4.3.2 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/chunked-blob-reader@5.2.2': - dependencies: - tslib: 2.8.1 - - '@smithy/config-resolver@4.4.17': - dependencies: - '@smithy/node-config-provider': 4.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 - '@smithy/util-endpoints': 3.4.2 - '@smithy/util-middleware': 4.2.14 - tslib: 2.8.1 - - '@smithy/core@3.23.17': - dependencies: - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-base64': 4.3.2 - '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 - '@smithy/uuid': 1.1.2 - tslib: 2.8.1 - - '@smithy/credential-provider-imds@4.2.14': - dependencies: - '@smithy/node-config-provider': 4.3.14 - '@smithy/property-provider': 4.2.14 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - tslib: 2.8.1 - - '@smithy/eventstream-codec@4.2.14': + '@smithy/core@3.24.1': dependencies: '@aws-crypto/crc32': 5.2.0 '@smithy/types': 4.14.1 - '@smithy/util-hex-encoding': 4.2.2 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.2.14': + '@smithy/credential-provider-imds@4.3.1': dependencies: - '@smithy/eventstream-serde-universal': 4.2.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.3.14': + '@smithy/eventstream-serde-browser@4.3.1': dependencies: + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-config-resolver@4.4.1': + dependencies: + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-node@4.3.1': + dependencies: + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.4.1': + dependencies: + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.2.14': + '@smithy/hash-blob-browser@4.3.1': dependencies: - '@smithy/eventstream-serde-universal': 4.2.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.2.14': + '@smithy/hash-node@4.3.1': dependencies: - '@smithy/eventstream-codec': 4.2.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.3.17': + '@smithy/hash-stream-node@4.3.1': dependencies: - '@smithy/protocol-http': 5.3.14 - '@smithy/querystring-builder': 4.2.14 - '@smithy/types': 4.14.1 - '@smithy/util-base64': 4.3.2 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/hash-blob-browser@4.2.15': + '@smithy/invalid-dependency@4.3.1': dependencies: - '@smithy/chunked-blob-reader': 5.2.2 - '@smithy/chunked-blob-reader-native': 4.2.3 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/hash-node@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-buffer-from': 4.2.2 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - - '@smithy/hash-stream-node@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - - '@smithy/invalid-dependency@4.2.14': - dependencies: - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.1 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 - '@smithy/is-array-buffer@4.2.2': + '@smithy/md5-js@4.3.1': dependencies: + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/md5-js@4.2.14': + '@smithy/middleware-content-length@4.3.1': dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-utf8': 4.2.2 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/middleware-content-length@4.2.14': + '@smithy/middleware-endpoint@4.5.1': dependencies: - '@smithy/protocol-http': 5.3.14 + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/middleware-retry@4.6.1': + dependencies: + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.3.1': + dependencies: + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/middleware-stack@4.3.1': + dependencies: + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/node-config-provider@4.4.1': + dependencies: + '@smithy/core': 3.24.1 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.7.1': + dependencies: + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.32': + '@smithy/protocol-http@5.4.1': dependencies: - '@smithy/core': 3.23.17 - '@smithy/middleware-serde': 4.2.20 - '@smithy/node-config-provider': 4.3.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-middleware': 4.2.14 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/middleware-retry@4.5.7': + '@smithy/signature-v4@5.4.1': dependencies: - '@smithy/core': 3.23.17 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/service-error-classification': 4.3.1 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/uuid': 1.1.2 - tslib: 2.8.1 - - '@smithy/middleware-serde@4.2.20': - dependencies: - '@smithy/core': 3.23.17 - '@smithy/protocol-http': 5.3.14 + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/middleware-stack@4.2.14': + '@smithy/smithy-client@4.13.1': dependencies: + '@smithy/core': 3.24.1 '@smithy/types': 4.14.1 tslib: 2.8.1 - '@smithy/node-config-provider@4.3.14': - dependencies: - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/node-http-handler@4.6.1': - dependencies: - '@smithy/protocol-http': 5.3.14 - '@smithy/querystring-builder': 4.2.14 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/property-provider@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/protocol-http@5.3.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/querystring-builder@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-uri-escape': 4.2.2 - tslib: 2.8.1 - - '@smithy/querystring-parser@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/service-error-classification@4.3.1': - dependencies: - '@smithy/types': 4.14.1 - - '@smithy/shared-ini-file-loader@4.4.9': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/signature-v4@5.3.14': - dependencies: - '@smithy/is-array-buffer': 4.2.2 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-hex-encoding': 4.2.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-uri-escape': 4.2.2 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - - '@smithy/smithy-client@4.12.13': - dependencies: - '@smithy/core': 3.23.17 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-stack': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.25 - tslib: 2.8.1 - '@smithy/types@4.14.1': dependencies: tslib: 2.8.1 - '@smithy/url-parser@4.2.14': + '@smithy/url-parser@4.3.1': dependencies: - '@smithy/querystring-parser': 4.2.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-base64@4.3.2': + '@smithy/util-base64@4.4.1': dependencies: - '@smithy/util-buffer-from': 4.2.2 - '@smithy/util-utf8': 4.2.2 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-body-length-browser@4.2.2': + '@smithy/util-body-length-browser@4.3.1': dependencies: + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-body-length-node@4.2.3': + '@smithy/util-body-length-node@4.3.1': dependencies: + '@smithy/core': 3.24.1 tslib: 2.8.1 '@smithy/util-buffer-from@2.2.0': @@ -14754,66 +14483,34 @@ snapshots: '@smithy/is-array-buffer': 2.2.0 tslib: 2.8.1 - '@smithy/util-buffer-from@4.2.2': + '@smithy/util-defaults-mode-browser@4.4.1': dependencies: - '@smithy/is-array-buffer': 4.2.2 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-config-provider@4.2.2': + '@smithy/util-defaults-mode-node@4.3.1': dependencies: + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.49': + '@smithy/util-endpoints@3.5.1': dependencies: - '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.54': + '@smithy/util-middleware@4.3.1': dependencies: - '@smithy/config-resolver': 4.4.17 - '@smithy/credential-provider-imds': 4.2.14 - '@smithy/node-config-provider': 4.3.14 - '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-endpoints@3.4.2': + '@smithy/util-retry@4.4.1': dependencies: - '@smithy/node-config-provider': 4.3.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-hex-encoding@4.2.2': - dependencies: - tslib: 2.8.1 - - '@smithy/util-middleware@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/util-retry@4.3.6': - dependencies: - '@smithy/service-error-classification': 4.3.1 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/util-stream@4.5.25': - dependencies: - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.1 - '@smithy/types': 4.14.1 - '@smithy/util-base64': 4.3.2 - '@smithy/util-buffer-from': 4.2.2 - '@smithy/util-hex-encoding': 4.2.2 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - - '@smithy/util-uri-escape@4.2.2': + '@smithy/util-stream@4.6.1': dependencies: + '@smithy/core': 3.24.1 tslib: 2.8.1 '@smithy/util-utf8@2.3.0': @@ -14821,18 +14518,14 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@smithy/util-utf8@4.2.2': + '@smithy/util-utf8@4.3.1': dependencies: - '@smithy/util-buffer-from': 4.2.2 + '@smithy/core': 3.24.1 tslib: 2.8.1 - '@smithy/util-waiter@4.3.0': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/uuid@1.1.2': + '@smithy/util-waiter@4.4.1': dependencies: + '@smithy/core': 3.24.1 tslib: 2.8.1 '@socket.io/component-emitter@3.1.0': {} @@ -16575,11 +16268,6 @@ snapshots: chevrotain: 11.0.3 lodash-es: 4.18.1 - chevrotain-allstar@0.3.1(chevrotain@11.1.2): - dependencies: - chevrotain: 11.1.2 - lodash-es: 4.18.1 - chevrotain@11.0.3: dependencies: '@chevrotain/cst-dts-gen': 11.0.3 @@ -16589,15 +16277,6 @@ snapshots: '@chevrotain/utils': 11.0.3 lodash-es: 4.18.1 - chevrotain@11.1.2: - dependencies: - '@chevrotain/cst-dts-gen': 11.1.2 - '@chevrotain/gast': 11.1.2 - '@chevrotain/regexp-to-ast': 11.1.2 - '@chevrotain/types': 11.1.2 - '@chevrotain/utils': 11.1.2 - lodash-es: 4.18.1 - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -17423,6 +17102,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.46.1: {} + es6-promise-pool@2.5.0: {} esbuild@0.27.4: @@ -17712,7 +17393,7 @@ snapshots: express-rate-limit@8.2.2(express@5.2.1): dependencies: express: 5.2.1 - ip-address: 10.1.0 + ip-address: 10.1.1 express@5.2.1: dependencies: @@ -18112,7 +17793,7 @@ snapshots: highlightjs-sap-abap@0.3.0: {} - hono@4.12.14: {} + hono@4.12.18: {} hookified@1.15.1: {} @@ -18257,7 +17938,7 @@ snapshots: transitivePeerDependencies: - supports-color - ip-address@10.1.0: {} + ip-address@10.1.1: {} ipaddr.js@1.9.1: {} @@ -19005,14 +18686,14 @@ snapshots: klona@2.0.6: {} - kysely-codegen@0.20.0(kysely@0.28.14)(pg@8.16.3)(typescript@5.9.3): + kysely-codegen@0.20.0(kysely@0.29.0)(pg@8.16.3)(typescript@5.9.3): dependencies: chalk: 4.1.2 cosmiconfig: 9.0.0(typescript@5.9.3) diff: 8.0.3 dotenv: 17.2.4 dotenv-expand: 12.0.3 - kysely: 0.28.14 + kysely: 0.29.0 micromatch: 4.0.8 minimist: 1.2.8 pluralize: 8.0.0 @@ -19027,13 +18708,13 @@ snapshots: '@commander-js/extra-typings': 11.1.0(commander@11.1.0) commander: 11.1.0 - kysely-postgres-js@3.0.0(kysely@0.28.14)(postgres@3.4.8): + kysely-postgres-js@3.0.0(kysely@0.29.0)(postgres@3.4.8): dependencies: - kysely: 0.28.14 + kysely: 0.29.0 optionalDependencies: postgres: 3.4.8 - kysely@0.28.14: {} + kysely@0.29.0: {} langium@3.3.1: dependencies: @@ -19043,18 +18724,9 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.0.8 - langium@4.2.1: - dependencies: - chevrotain: 11.1.2 - chevrotain-allstar: 0.3.1(chevrotain@11.1.2) - vscode-languageserver: 9.0.1 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.1.0 - - langsmith@0.5.19(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0): + langsmith@0.7.0(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.2.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0): dependencies: p-queue: 6.6.2 - uuid: 10.0.0 optionalDependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) @@ -19325,11 +18997,11 @@ snapshots: merge-stream@2.0.0: {} - mermaid@11.13.0: + mermaid@11.15.0: dependencies: '@braintree/sanitize-url': 7.1.2 '@iconify/utils': 3.1.0 - '@mermaid-js/parser': 1.0.1 + '@mermaid-js/parser': 1.1.1 '@types/d3': 7.4.3 '@upsetjs/venn.js': 2.0.0 cytoscape: 3.33.1 @@ -19340,14 +19012,14 @@ snapshots: dagre-d3-es: 7.0.14 dayjs: 1.11.19 dompurify: 3.4.1 + es-toolkit: 1.46.1 katex: 0.16.40 khroma: 2.1.0 - lodash-es: 4.18.1 marked: 16.4.2 roughjs: 4.6.6 stylis: 4.3.6 ts-dedent: 2.2.0 - uuid: 11.1.0 + uuid: 14.0.0 methods@1.1.2: {} @@ -19470,11 +19142,11 @@ snapshots: reflect-metadata: 0.2.2 rxjs: 7.8.2 - nestjs-kysely@3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.14)(reflect-metadata@0.2.2): + nestjs-kysely@3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.29.0)(reflect-metadata@0.2.2): dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) - kysely: 0.28.14 + kysely: 0.29.0 reflect-metadata: 0.2.2 nestjs-pino@4.6.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2): @@ -20214,18 +19886,18 @@ snapshots: prosemirror-state: 1.4.3 prosemirror-transform: 1.10.4 - protobufjs@7.5.5: + protobufjs@7.5.6: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 + '@protobufjs/codegen': 2.0.5 '@protobufjs/eventemitter': 1.1.0 '@protobufjs/fetch': 1.1.0 '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 + '@protobufjs/inquire': 1.1.1 '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 + '@protobufjs/utf8': 1.1.1 '@types/node': 25.5.0 long: 5.3.2 @@ -21607,8 +21279,6 @@ snapshots: vscode-uri@3.0.8: {} - vscode-uri@3.1.0: {} - w3c-keyname@2.2.8: {} w3c-xmlserializer@5.0.0: From 3b983a27f62f0341c449773ee8372c6124bfb95d Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Thu, 14 May 2026 03:01:55 +0100 Subject: [PATCH 39/46] sync --- apps/server/package.json | 2 +- apps/server/src/ee | 2 +- pnpm-lock.yaml | 30 +++++++++++++++--------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/server/package.json b/apps/server/package.json index f3e14770d..17d763fb8 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -81,7 +81,7 @@ "ioredis": "^5.10.1", "js-tiktoken": "^1.0.21", "jsonwebtoken": "^9.0.3", - "kysely": "^0.29.0", + "kysely": "^0.28.17", "kysely-migration-cli": "^0.4.2", "kysely-postgres-js": "^3.0.0", "ldapts": "^8.1.7", diff --git a/apps/server/src/ee b/apps/server/src/ee index 71844c097..b30e92f6a 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit 71844c097213ee3d861bf5b0e91eb6766b09d215 +Subproject commit b30e92f6a024b2b1106a8243e5a313122c4b0712 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 58423036b..e7980205a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -637,14 +637,14 @@ importers: specifier: ^9.0.3 version: 9.0.3 kysely: - specifier: ^0.29.0 - version: 0.29.0 + specifier: ^0.28.17 + version: 0.28.17 kysely-migration-cli: specifier: ^0.4.2 version: 0.4.2 kysely-postgres-js: specifier: ^3.0.0 - version: 3.0.0(kysely@0.29.0)(postgres@3.4.8) + version: 3.0.0(kysely@0.28.17)(postgres@3.4.8) ldapts: specifier: ^8.1.7 version: 8.1.7 @@ -668,7 +668,7 @@ importers: version: 6.2.0(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) nestjs-kysely: specifier: ^3.1.2 - version: 3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.29.0)(reflect-metadata@0.2.2) + version: 3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.17)(reflect-metadata@0.2.2) nestjs-pino: specifier: ^4.6.1 version: 4.6.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2) @@ -819,7 +819,7 @@ importers: version: 30.3.0(@types/node@25.5.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.5))(@types/node@25.5.0)(typescript@5.9.3)) kysely-codegen: specifier: ^0.20.0 - version: 0.20.0(kysely@0.29.0)(pg@8.16.3)(typescript@5.9.3) + version: 0.20.0(kysely@0.28.17)(pg@8.16.3)(typescript@5.9.3) prettier: specifier: ^3.8.1 version: 3.8.1 @@ -7815,9 +7815,9 @@ packages: postgres: optional: true - kysely@0.29.0: - resolution: {integrity: sha512-LrQfPUeTW7MXbMvT62moEMnpMTuj9TO3lqjCeLKjM975PJ4Alrl/43f2tlDX7xOsNptKgH4LSNGwIbXwEkLg4g==} - engines: {node: '>=22.0.0'} + kysely@0.28.17: + resolution: {integrity: sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==} + engines: {node: '>=20.0.0'} langium@3.3.1: resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} @@ -18686,14 +18686,14 @@ snapshots: klona@2.0.6: {} - kysely-codegen@0.20.0(kysely@0.29.0)(pg@8.16.3)(typescript@5.9.3): + kysely-codegen@0.20.0(kysely@0.28.17)(pg@8.16.3)(typescript@5.9.3): dependencies: chalk: 4.1.2 cosmiconfig: 9.0.0(typescript@5.9.3) diff: 8.0.3 dotenv: 17.2.4 dotenv-expand: 12.0.3 - kysely: 0.29.0 + kysely: 0.28.17 micromatch: 4.0.8 minimist: 1.2.8 pluralize: 8.0.0 @@ -18708,13 +18708,13 @@ snapshots: '@commander-js/extra-typings': 11.1.0(commander@11.1.0) commander: 11.1.0 - kysely-postgres-js@3.0.0(kysely@0.29.0)(postgres@3.4.8): + kysely-postgres-js@3.0.0(kysely@0.28.17)(postgres@3.4.8): dependencies: - kysely: 0.29.0 + kysely: 0.28.17 optionalDependencies: postgres: 3.4.8 - kysely@0.29.0: {} + kysely@0.28.17: {} langium@3.3.1: dependencies: @@ -19142,11 +19142,11 @@ snapshots: reflect-metadata: 0.2.2 rxjs: 7.8.2 - nestjs-kysely@3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.29.0)(reflect-metadata@0.2.2): + nestjs-kysely@3.1.2(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(kysely@0.28.17)(reflect-metadata@0.2.2): dependencies: '@nestjs/common': 11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.19(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.19)(reflect-metadata@0.2.2)(rxjs@7.8.2) - kysely: 0.29.0 + kysely: 0.28.17 reflect-metadata: 0.2.2 nestjs-pino@4.6.1(@nestjs/common@11.1.19(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2): From f4af4c3fc0957f7cc7005182a09f41ccba0ec032 Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Thu, 14 May 2026 03:48:13 +0100 Subject: [PATCH 40/46] feat(editor): add page break node (#2202) --- .../public/locales/en-US/translation.json | 2 + .../fixed-toolbar/groups/block-type-group.tsx | 7 +++ .../components/slash-menu/menu-items.ts | 9 +++ .../features/editor/extensions/extensions.ts | 2 + .../src/features/editor/styles/index.css | 1 + .../src/features/editor/styles/page-break.css | 50 ++++++++++++++++ .../src/collaboration/collaboration.util.ts | 2 + packages/editor-ext/src/index.ts | 1 + .../editor-ext/src/lib/page-break/index.ts | 1 + .../src/lib/page-break/page-break.ts | 60 +++++++++++++++++++ 10 files changed, 135 insertions(+) create mode 100644 apps/client/src/features/editor/styles/page-break.css create mode 100644 packages/editor-ext/src/lib/page-break/index.ts create mode 100644 packages/editor-ext/src/lib/page-break/page-break.ts diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index 268d696c8..e85f2af23 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -361,6 +361,8 @@ "Create block quote.": "Create block quote.", "Insert code snippet.": "Insert code snippet.", "Insert horizontal rule divider": "Insert horizontal rule divider", + "Page break": "Page break", + "Insert a page break for printing.": "Insert a page break for printing.", "Upload any image from your device.": "Upload any image from your device.", "Upload any video from your device.": "Upload any video from your device.", "Upload any audio from your device.": "Upload any audio from your device.", diff --git a/apps/client/src/features/editor/components/fixed-toolbar/groups/block-type-group.tsx b/apps/client/src/features/editor/components/fixed-toolbar/groups/block-type-group.tsx index 3edb28eda..69911f7cb 100644 --- a/apps/client/src/features/editor/components/fixed-toolbar/groups/block-type-group.tsx +++ b/apps/client/src/features/editor/components/fixed-toolbar/groups/block-type-group.tsx @@ -10,6 +10,7 @@ import { IconH2, IconH3, IconMenu4, + IconPageBreak, IconTypography, } from "@tabler/icons-react"; import { useTranslation } from "react-i18next"; @@ -102,6 +103,12 @@ export const BlockTypeGroup: FC = ({ editor }) => { > {t("Divider")} + } + onClick={() => editor.chain().focus().setPageBreak().run()} + > + {t("Page break")} + ); diff --git a/apps/client/src/features/editor/components/slash-menu/menu-items.ts b/apps/client/src/features/editor/components/slash-menu/menu-items.ts index 4a0532fe3..cddddc35f 100644 --- a/apps/client/src/features/editor/components/slash-menu/menu-items.ts +++ b/apps/client/src/features/editor/components/slash-menu/menu-items.ts @@ -19,6 +19,7 @@ import { IconTable, IconTypography, IconMenu4, + IconPageBreak, IconCalendar, IconAppWindow, IconSitemap, @@ -164,6 +165,14 @@ const CommandGroups: SlashMenuGroupedItemsType = { command: ({ editor, range }: CommandProps) => editor.chain().focus().deleteRange(range).setHorizontalRule().run(), }, + { + title: "Page break", + description: "Insert a page break for printing.", + searchTerms: ["page", "break", "pagebreak", "print"], + icon: IconPageBreak, + command: ({ editor, range }: CommandProps) => + editor.chain().focus().deleteRange(range).setPageBreak().run(), + }, { title: "Image", description: "Upload any image from your device.", diff --git a/apps/client/src/features/editor/extensions/extensions.ts b/apps/client/src/features/editor/extensions/extensions.ts index 1f09bef37..91411daef 100644 --- a/apps/client/src/features/editor/extensions/extensions.ts +++ b/apps/client/src/features/editor/extensions/extensions.ts @@ -42,6 +42,7 @@ import { Excalidraw, Embed, TiptapPdf, + PageBreak, SearchAndReplace, Mention, TableDndExtension, @@ -366,6 +367,7 @@ export const mainExtensions = [ TiptapPdf.configure({ view: PdfView, }), + PageBreak, Subpages.configure({ view: SubpagesView, }), diff --git a/apps/client/src/features/editor/styles/index.css b/apps/client/src/features/editor/styles/index.css index 7abfe1086..52d9268e1 100644 --- a/apps/client/src/features/editor/styles/index.css +++ b/apps/client/src/features/editor/styles/index.css @@ -9,6 +9,7 @@ @import "./media.css"; @import "./code.css"; @import "./print.css"; +@import "./page-break.css"; @import "./find.css"; @import "./mention.css"; @import "./ordered-list.css"; diff --git a/apps/client/src/features/editor/styles/page-break.css b/apps/client/src/features/editor/styles/page-break.css new file mode 100644 index 000000000..6dc97c738 --- /dev/null +++ b/apps/client/src/features/editor/styles/page-break.css @@ -0,0 +1,50 @@ +.ProseMirror .page-break { + position: relative; + margin: 1.5rem 0; + border-top: 1px dashed var(--mantine-color-default-border); + height: 0; + user-select: none; +} + +.ProseMirror[contenteditable="false"] .page-break { + margin: 0; + border: none; + height: 0; +} + +.ProseMirror[contenteditable="false"] .page-break::after { + content: none; +} + +.ProseMirror .page-break::after { + content: "Page break"; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 0 0.5rem; + background: var(--mantine-color-body); + color: var(--mantine-color-dimmed); + font-size: 0.75rem; + line-height: 1; + letter-spacing: 0.02em; + text-transform: uppercase; +} + +.ProseMirror .page-break.ProseMirror-selectednode { + border-top-color: var(--mantine-primary-color-filled); +} + +@media print { + .ProseMirror .page-break { + break-before: always; + page-break-before: always; + visibility: hidden; + border: none; + margin: 0; + } + + .ProseMirror .page-break::after { + content: none; + } +} diff --git a/apps/server/src/collaboration/collaboration.util.ts b/apps/server/src/collaboration/collaboration.util.ts index 5787e2e3a..554aa43bd 100644 --- a/apps/server/src/collaboration/collaboration.util.ts +++ b/apps/server/src/collaboration/collaboration.util.ts @@ -26,6 +26,7 @@ import { TiptapVideo, TiptapAudio, TiptapPdf, + PageBreak, TrailingNode, Attachment, Drawio, @@ -94,6 +95,7 @@ export const tiptapExtensions = [ TiptapVideo, TiptapAudio, TiptapPdf, + PageBreak, Callout, Attachment, CustomCodeBlock, diff --git a/packages/editor-ext/src/index.ts b/packages/editor-ext/src/index.ts index 354b1a617..003d22886 100644 --- a/packages/editor-ext/src/index.ts +++ b/packages/editor-ext/src/index.ts @@ -31,5 +31,6 @@ export * from "./lib/recreate-transform"; export * from "./lib/columns"; export * from "./lib/status"; export * from "./lib/pdf"; +export * from "./lib/page-break"; export * from "./lib/resizable-nodeview"; diff --git a/packages/editor-ext/src/lib/page-break/index.ts b/packages/editor-ext/src/lib/page-break/index.ts new file mode 100644 index 000000000..701b20b78 --- /dev/null +++ b/packages/editor-ext/src/lib/page-break/index.ts @@ -0,0 +1 @@ +export * from "./page-break"; diff --git a/packages/editor-ext/src/lib/page-break/page-break.ts b/packages/editor-ext/src/lib/page-break/page-break.ts new file mode 100644 index 000000000..f8991b266 --- /dev/null +++ b/packages/editor-ext/src/lib/page-break/page-break.ts @@ -0,0 +1,60 @@ +import { mergeAttributes, Node } from "@tiptap/core"; + +export interface PageBreakOptions { + HTMLAttributes: Record; +} + +declare module "@tiptap/core" { + interface Commands { + pageBreak: { + setPageBreak: () => ReturnType; + }; + } +} + +export const PageBreak = Node.create({ + name: "pageBreak", + + group: "block", + + atom: true, + + selectable: true, + + addOptions() { + return { + HTMLAttributes: {}, + }; + }, + + parseHTML() { + return [ + { + tag: `div[data-type="${this.name}"]`, + }, + ]; + }, + + renderHTML({ HTMLAttributes }) { + return [ + "div", + mergeAttributes( + { "data-type": this.name, class: "page-break" }, + this.options.HTMLAttributes, + HTMLAttributes, + ), + ]; + }, + + addCommands() { + return { + setPageBreak: + () => + ({ chain }) => + chain() + .insertContent({ type: this.name }) + .focus() + .run(), + }; + }, +}); From f758091b2af8341758e05ef2a82b27ee32f09672 Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Thu, 14 May 2026 13:11:28 +0100 Subject: [PATCH 41/46] perf(permissions): cache space role and page edit lookups (#2208) --- apps/server/src/common/helpers/cache-keys.ts | 8 ++ apps/server/src/common/helpers/with-cache.ts | 27 ++++ .../repos/page/page-permission.repo.ts | 123 ++++++++---------- .../database/repos/space/space-member.repo.ts | 55 +++++--- 4 files changed, 125 insertions(+), 88 deletions(-) create mode 100644 apps/server/src/common/helpers/with-cache.ts diff --git a/apps/server/src/common/helpers/cache-keys.ts b/apps/server/src/common/helpers/cache-keys.ts index 570c96d88..38b24d20e 100644 --- a/apps/server/src/common/helpers/cache-keys.ts +++ b/apps/server/src/common/helpers/cache-keys.ts @@ -1,3 +1,11 @@ export const CacheKey = { LICENSE_VALID: (workspaceId: string) => `license:valid:${workspaceId}`, + SPACE_ROLES: (userId: string, spaceId: string) => + `perm:space-roles:${userId}:${spaceId}`, + PAGE_CAN_EDIT: (userId: string, pageId: string) => + `perm:can-edit:${userId}:${pageId}`, }; + +// Permission caches dedupe repeated checks within and across short request bursts. +// 5s keeps staleness on revocations bounded. +export const PERMISSION_CACHE_TTL_MS = 5_000; diff --git a/apps/server/src/common/helpers/with-cache.ts b/apps/server/src/common/helpers/with-cache.ts new file mode 100644 index 000000000..2db1d3c02 --- /dev/null +++ b/apps/server/src/common/helpers/with-cache.ts @@ -0,0 +1,27 @@ +import { Cache } from 'cache-manager'; + +export async function withCache( + cacheManager: Cache, + key: string, + ttlMs: number, + fn: () => Promise, +): Promise { + try { + const cached = await cacheManager.get<{ v: T }>(key); + if (cached !== undefined && cached !== null) { + return cached.v; + } + } catch (err) { + console.warn(`[withCache] get failed for "${key}", falling back to source`, err); + } + + const value = await fn(); + + try { + await cacheManager.set(key, { v: value }, ttlMs); + } catch (err) { + console.warn(`[withCache] set failed for "${key}"`, err); + } + + return value; +} diff --git a/apps/server/src/database/repos/page/page-permission.repo.ts b/apps/server/src/database/repos/page/page-permission.repo.ts index fbd7423ce..f753526cd 100644 --- a/apps/server/src/database/repos/page/page-permission.repo.ts +++ b/apps/server/src/database/repos/page/page-permission.repo.ts @@ -1,4 +1,6 @@ -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; +import { Cache } from 'cache-manager'; import { InjectKysely } from 'nestjs-kysely'; import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types'; import { dbOrTx } from '@docmost/db/utils'; @@ -17,6 +19,11 @@ import { executeWithCursorPagination, } from '@docmost/db/pagination/cursor-pagination'; import { PagePermissionMember } from './types/page-permission.types'; +import { withCache } from '../../../common/helpers/with-cache'; +import { + CacheKey, + PERMISSION_CACHE_TTL_MS, +} from '../../../common/helpers/cache-keys'; export { PagePermissionMember } from './types/page-permission.types'; @@ -25,6 +32,7 @@ export class PagePermissionRepo { constructor( @InjectKysely() private readonly db: KyselyDB, private readonly groupRepo: GroupRepo, + @Inject(CACHE_MANAGER) private readonly cacheManager: Cache, ) {} async findPageAccessByPageId( @@ -361,40 +369,8 @@ export class PagePermissionRepo { * Check if user can access a page by verifying they have permission on ALL restricted ancestors. */ async canUserAccessPage(userId: string, pageId: string): Promise { - const deniedAncestor = await this.db - .withRecursive('ancestors', (qb) => - qb - .selectFrom('pages') - .select(['pages.id as ancestorId', 'pages.parentPageId']) - .where('pages.id', '=', pageId) - .unionAll((eb) => - eb - .selectFrom('pages') - .innerJoin('ancestors', 'ancestors.parentPageId', 'pages.id') - .select(['pages.id as ancestorId', 'pages.parentPageId']), - ), - ) - .selectFrom('ancestors') - .innerJoin('pageAccess', 'pageAccess.pageId', 'ancestors.ancestorId') - .leftJoin('pagePermissions', (join) => - join - .onRef('pagePermissions.pageAccessId', '=', 'pageAccess.id') - .on((eb) => - eb.or([ - eb('pagePermissions.userId', '=', userId), - eb( - 'pagePermissions.groupId', - 'in', - this.userGroupIdsSubquery(eb, userId), - ), - ]), - ), - ) - .select('pageAccess.pageId') - .where('pagePermissions.id', 'is', null) - .executeTakeFirst(); - - return !deniedAncestor; + const { canAccess } = await this.canUserEditPage(userId, pageId); + return canAccess; } /** @@ -412,43 +388,50 @@ export class PagePermissionRepo { canAccess: boolean; canEdit: boolean; }> { - const result = await sql<{ - canAccess: boolean | null; - canEdit: boolean | null; - }>` - WITH RECURSIVE ancestors AS ( - SELECT id AS ancestor_id, parent_page_id, 0 AS depth - FROM pages - WHERE id = ${pageId}::uuid - UNION ALL - SELECT p.id, p.parent_page_id, a.depth + 1 - FROM pages p - JOIN ancestors a ON a.parent_page_id = p.id - ) - SELECT - bool_and(pp.id IS NOT NULL) AS "canAccess", - -- nearest restricted ancestor's highest role wins (DESC: 'writer' > 'reader', NULLS LAST: no-permission after real roles) - (array_agg(pp.role ORDER BY a.depth ASC, pp.role DESC NULLS LAST))[1] = 'writer' AS "canEdit" - FROM ancestors a - JOIN page_access pa ON pa.page_id = a.ancestor_id - LEFT JOIN page_permissions pp ON pp.page_access_id = pa.id - AND ( - pp.user_id = ${userId}::uuid - OR pp.group_id IN ( - SELECT gu.group_id FROM group_users gu WHERE gu.user_id = ${userId}::uuid + return withCache( + this.cacheManager, + CacheKey.PAGE_CAN_EDIT(userId, pageId), + PERMISSION_CACHE_TTL_MS, + async () => { + const result = await sql<{ + canAccess: boolean | null; + canEdit: boolean | null; + }>` + WITH RECURSIVE ancestors AS ( + SELECT id AS ancestor_id, parent_page_id, 0 AS depth + FROM pages + WHERE id = ${pageId}::uuid + UNION ALL + SELECT p.id, p.parent_page_id, a.depth + 1 + FROM pages p + JOIN ancestors a ON a.parent_page_id = p.id ) - ) - `.execute(this.db); + SELECT + bool_and(pp.id IS NOT NULL) AS "canAccess", + -- nearest restricted ancestor's highest role wins (DESC: 'writer' > 'reader', NULLS LAST: no-permission after real roles) + (array_agg(pp.role ORDER BY a.depth ASC, pp.role DESC NULLS LAST))[1] = 'writer' AS "canEdit" + FROM ancestors a + JOIN page_access pa ON pa.page_id = a.ancestor_id + LEFT JOIN page_permissions pp ON pp.page_access_id = pa.id + AND ( + pp.user_id = ${userId}::uuid + OR pp.group_id IN ( + SELECT gu.group_id FROM group_users gu WHERE gu.user_id = ${userId}::uuid + ) + ) + `.execute(this.db); - const row = result.rows[0]; - if (!row || row.canAccess === null) { - return { hasAnyRestriction: false, canAccess: true, canEdit: true }; - } - return { - hasAnyRestriction: true, - canAccess: row.canAccess, - canEdit: row.canAccess && (row.canEdit ?? false), - }; + const row = result.rows[0]; + if (!row || row.canAccess === null) { + return { hasAnyRestriction: false, canAccess: true, canEdit: true }; + } + return { + hasAnyRestriction: true, + canAccess: row.canAccess, + canEdit: row.canAccess && (row.canEdit ?? false), + }; + }, + ); } /** diff --git a/apps/server/src/database/repos/space/space-member.repo.ts b/apps/server/src/database/repos/space/space-member.repo.ts index 50961802f..6711c30c7 100644 --- a/apps/server/src/database/repos/space/space-member.repo.ts +++ b/apps/server/src/database/repos/space/space-member.repo.ts @@ -1,4 +1,6 @@ -import { BadRequestException, Injectable } from '@nestjs/common'; +import { BadRequestException, Inject, Injectable } from '@nestjs/common'; +import { CACHE_MANAGER } from '@nestjs/cache-manager'; +import { Cache } from 'cache-manager'; import { InjectKysely } from 'nestjs-kysely'; import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types'; import { dbOrTx } from '@docmost/db/utils'; @@ -13,6 +15,11 @@ import { MemberInfo, UserSpaceRole } from './types'; import { executeWithCursorPagination } from '@docmost/db/pagination/cursor-pagination'; import { GroupRepo } from '@docmost/db/repos/group/group.repo'; import { SpaceRepo } from '@docmost/db/repos/space/space.repo'; +import { withCache } from '../../../common/helpers/with-cache'; +import { + CacheKey, + PERMISSION_CACHE_TTL_MS, +} from '../../../common/helpers/cache-keys'; @Injectable() export class SpaceMemberRepo { @@ -20,6 +27,7 @@ export class SpaceMemberRepo { @InjectKysely() private readonly db: KyselyDB, private readonly groupRepo: GroupRepo, private readonly spaceRepo: SpaceRepo, + @Inject(CACHE_MANAGER) private readonly cacheManager: Cache, ) {} async insertSpaceMember( @@ -214,25 +222,36 @@ export class SpaceMemberRepo { userId: string, spaceId: string, ): Promise { - const roles = await this.db - .selectFrom('spaceMembers') - .select(['userId', 'role']) - .where('userId', '=', userId) - .where('spaceId', '=', spaceId) - .unionAll( - this.db + return withCache( + this.cacheManager, + CacheKey.SPACE_ROLES(userId, spaceId), + PERMISSION_CACHE_TTL_MS, + async () => { + const roles = await this.db .selectFrom('spaceMembers') - .innerJoin('groupUsers', 'groupUsers.groupId', 'spaceMembers.groupId') - .select(['groupUsers.userId', 'spaceMembers.role']) - .where('groupUsers.userId', '=', userId) - .where('spaceMembers.spaceId', '=', spaceId), - ) - .execute(); + .select(['userId', 'role']) + .where('userId', '=', userId) + .where('spaceId', '=', spaceId) + .unionAll( + this.db + .selectFrom('spaceMembers') + .innerJoin( + 'groupUsers', + 'groupUsers.groupId', + 'spaceMembers.groupId', + ) + .select(['groupUsers.userId', 'spaceMembers.role']) + .where('groupUsers.userId', '=', userId) + .where('spaceMembers.spaceId', '=', spaceId), + ) + .execute(); - if (!roles || roles.length === 0) { - return undefined; - } - return roles; + if (!roles || roles.length === 0) { + return undefined; + } + return roles; + }, + ); } async getUserIdsWithSpaceAccess( From 82d065669dfb2617449aa664f34fae4fadd68f7d Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Thu, 14 May 2026 14:15:03 +0200 Subject: [PATCH 42/46] fix: page mode toggle no longer overwrites default preference (#1996) The header edit/read toggle now controls only the current session's mode without saving it as the user's preference. The saved preference (set in profile settings) is applied once on initial load and sticks across page navigations within the session, so navigating to a new page no longer resets the mode mid-session. Fixes #1693 --- .../src/features/editor/atoms/editor-atoms.ts | 5 +++++ .../src/features/editor/full-editor.tsx | 19 ++++++++++++++-- .../src/features/editor/page-editor.tsx | 22 +++++-------------- .../src/features/editor/title-editor.tsx | 21 +++++------------- .../components/header/page-header-menu.tsx | 4 ++-- .../user/components/page-state-pref.tsx | 22 +++++++++++++++++++ 6 files changed, 57 insertions(+), 36 deletions(-) diff --git a/apps/client/src/features/editor/atoms/editor-atoms.ts b/apps/client/src/features/editor/atoms/editor-atoms.ts index 8982765e4..c0873adfa 100644 --- a/apps/client/src/features/editor/atoms/editor-atoms.ts +++ b/apps/client/src/features/editor/atoms/editor-atoms.ts @@ -1,5 +1,6 @@ import { atom } from "jotai"; import { Editor } from "@tiptap/core"; +import { PageEditMode } from "@/features/user/types/user.types.ts"; export const pageEditorAtom = atom(null); @@ -12,3 +13,7 @@ export const yjsConnectionStatusAtom = atom(""); export const showAiMenuAtom = atom(false); export const showLinkMenuAtom = atom(false); + +// Current page's edit mode — initialized from the user's saved preference on +// first load, can be toggled locally without persisting to the server. +export const currentPageEditModeAtom = atom(PageEditMode.Edit); diff --git a/apps/client/src/features/editor/full-editor.tsx b/apps/client/src/features/editor/full-editor.tsx index 69bf2628f..57595b288 100644 --- a/apps/client/src/features/editor/full-editor.tsx +++ b/apps/client/src/features/editor/full-editor.tsx @@ -1,5 +1,5 @@ import classes from "@/features/editor/styles/editor.module.css"; -import React from "react"; +import React, { useEffect } from "react"; import { TitleEditor } from "@/features/editor/title-editor"; import PageEditor from "@/features/editor/page-editor"; import { @@ -24,6 +24,7 @@ import { FixedToolbar } from "@/features/editor/components/fixed-toolbar/fixed-t import { PageEditMode } from "@/features/user/types/user.types.ts"; import useToggleAside from "@/hooks/use-toggle-aside.tsx"; import clsx from "clsx"; +import { currentPageEditModeAtom } from "@/features/editor/atoms/editor-atoms.ts"; const MemoizedTitleEditor = React.memo(TitleEditor); const MemoizedPageEditor = React.memo(PageEditor); @@ -34,6 +35,10 @@ type PageCreator = { avatarUrl: string; }; +// Module-level flag: survives component unmount/remount on page navigation, +// reset only on full page reload (i.e. a new app session). +let defaultEditModeApplied = false; + export interface FullEditorProps { pageId: string; slugId: string; @@ -61,9 +66,19 @@ export function FullEditor({ const fullPageWidth = user.settings?.preferences?.fullPageWidth; const editorToolbarEnabled = user.settings?.preferences?.editorToolbar ?? false; + const [currentPageEditMode, setCurrentPageEditMode] = useAtom(currentPageEditModeAtom); const userPageEditMode = user.settings?.preferences?.pageEditMode ?? PageEditMode.Edit; - const isEditMode = userPageEditMode === PageEditMode.Edit; + const isEditMode = currentPageEditMode === PageEditMode.Edit; + + // Apply the user's saved preference only once on initial load, not on every + // page navigation — so the mode sticks across navigations within a session. + useEffect(() => { + if (!defaultEditModeApplied) { + setCurrentPageEditMode(userPageEditMode); + defaultEditModeApplied = true; + } + }, [userPageEditMode, setCurrentPageEditMode]); return ( Boolean(isComponentMounted.current && editorRef.current), [isComponentMounted], @@ -373,19 +373,9 @@ export default function PageEditor({ return () => clearTimeout(timeout); }, [yjsConnectionStatus, isSynced]); useEffect(() => { - // Only honor user default page edit mode preference and permissions - if (editor) { - if (userPageEditMode && editable) { - if (userPageEditMode === PageEditMode.Edit) { - editor.setEditable(true); - } else if (userPageEditMode === PageEditMode.Read) { - editor.setEditable(false); - } - } else { - editor.setEditable(false); - } - } - }, [userPageEditMode, editor, editable]); + if (!editor) return; + editor.setEditable(editable && currentPageEditMode === PageEditMode.Edit); + }, [currentPageEditMode, editor, editable]); const hasConnectedOnceRef = useRef(false); const [showStatic, setShowStatic] = useState(true); diff --git a/apps/client/src/features/editor/title-editor.tsx b/apps/client/src/features/editor/title-editor.tsx index e61d8c042..3ff2d7614 100644 --- a/apps/client/src/features/editor/title-editor.tsx +++ b/apps/client/src/features/editor/title-editor.tsx @@ -7,6 +7,7 @@ import { Text } from "@tiptap/extension-text"; import { Placeholder } from "@tiptap/extension-placeholder"; import { useAtomValue } from "jotai"; import { + currentPageEditModeAtom, pageEditorAtom, titleEditorAtom, } from "@/features/editor/atoms/editor-atoms"; @@ -24,7 +25,6 @@ import { useTranslation } from "react-i18next"; import EmojiCommand from "@/features/editor/extensions/emoji-command.ts"; import { UpdateEvent } from "@/features/websocket/types"; import localEmitter from "@/lib/local-emitter.ts"; -import { currentUserAtom } from "@/features/user/atoms/current-user-atom.ts"; import { PageEditMode } from "@/features/user/types/user.types.ts"; import { searchSpotlight } from "@/features/search/constants.ts"; import { platformModifierKey } from "@/lib"; @@ -52,9 +52,7 @@ export function TitleEditor({ const emit = useQueryEmit(); const navigate = useNavigate(); const [activePageId, setActivePageId] = useState(pageId); - const [currentUser] = useAtom(currentUserAtom); - const userPageEditMode = - currentUser?.user?.settings?.preferences?.pageEditMode ?? PageEditMode.Edit; + const currentPageEditMode = useAtomValue(currentPageEditModeAtom); const titleEditor = useEditor({ extensions: [ @@ -172,18 +170,9 @@ export function TitleEditor({ }, [pageId]); useEffect(() => { - if (titleEditor) { - if (userPageEditMode && editable) { - if (userPageEditMode === PageEditMode.Edit) { - titleEditor.setEditable(true); - } else if (userPageEditMode === PageEditMode.Read) { - titleEditor.setEditable(false); - } - } else { - titleEditor.setEditable(false); - } - } - }, [userPageEditMode, titleEditor, editable]); + if (!titleEditor) return; + titleEditor.setEditable(editable && currentPageEditMode === PageEditMode.Edit); + }, [currentPageEditMode, titleEditor, editable]); const openSearchDialog = () => { const event = new CustomEvent("openFindDialogFromEditor", {}); diff --git a/apps/client/src/features/page/components/header/page-header-menu.tsx b/apps/client/src/features/page/components/header/page-header-menu.tsx index 6e481b7aa..aaf23d6fd 100644 --- a/apps/client/src/features/page/components/header/page-header-menu.tsx +++ b/apps/client/src/features/page/components/header/page-header-menu.tsx @@ -40,7 +40,7 @@ import { yjsConnectionStatusAtom, } from "@/features/editor/atoms/editor-atoms.ts"; import { formattedDate } from "@/lib/time.ts"; -import { PageStateSegmentedControl } from "@/features/user/components/page-state-pref.tsx"; +import { PageEditModeToggle } from "@/features/user/components/page-state-pref.tsx"; import MovePageModal from "@/features/page/components/move-page-modal.tsx"; import { useTimeAgo } from "@/hooks/use-time-ago.tsx"; import { PageShareModal } from "@/ee/page-permission"; @@ -91,7 +91,7 @@ export default function PageHeaderMenu({ readOnly }: PageHeaderMenuProps) { <> - {!readOnly && } + {!readOnly && } diff --git a/apps/client/src/features/user/components/page-state-pref.tsx b/apps/client/src/features/user/components/page-state-pref.tsx index 712f5152f..c78a2e04b 100644 --- a/apps/client/src/features/user/components/page-state-pref.tsx +++ b/apps/client/src/features/user/components/page-state-pref.tsx @@ -6,6 +6,7 @@ import React, { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { PageEditMode } from "@/features/user/types/user.types.ts"; import { ResponsiveSettingsRow, ResponsiveSettingsContent, ResponsiveSettingsControl } from "@/components/ui/responsive-settings-row"; +import { currentPageEditModeAtom } from "@/features/editor/atoms/editor-atoms.ts"; export default function PageStatePref() { const { t } = useTranslation(); @@ -71,3 +72,24 @@ export function PageStateSegmentedControl({ /> ); } + +// Header variant: updates the current page's mode locally without persisting +// the preference to the server. +export function PageEditModeToggle({ size }: { size?: MantineSize }) { + const { t } = useTranslation(); + const [currentPageEditMode, setCurrentPageEditMode] = useAtom( + currentPageEditModeAtom, + ); + + return ( + setCurrentPageEditMode(v as PageEditMode)} + data={[ + { label: t("Edit"), value: PageEditMode.Edit }, + { label: t("Read"), value: PageEditMode.Read }, + ]} + /> + ); +} From 932c1ad5b73b14b9ea5a1f3ff1db0fea05a380b1 Mon Sep 17 00:00:00 2001 From: Peter Tripp Date: Thu, 14 May 2026 09:41:10 -0400 Subject: [PATCH 43/46] Better trash (#2190) * Better trash I recently lost a bunch of time editing and searching for pages that were actually in the Trash. Docmost intentionally tries to not link to Trashed pages, but the url of that Trashed page and any inbound links still work. This makes it clearer when a page you are interacting with is in the Trash. - /trash - Refactored banner into `trash-banner.tsx` - Refactored "Restore" modal into `use-restore-page-modal.tsx` - Page (when isDeleted) - Add: `trash-banner.tsx` - Add breadcrumbs: `Parent / Child / Page (Deleted)` - Change: Deleted Pages are read-only - Replace "Move to Trash" with "Restore" in page menu (invokes `use-restore-page-modal`) I tried very hard to keep this simple and re-use existing translation strings wherever possible. * cleanup --------- Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com> --- .../public/locales/en-US/translation.json | 3 + .../src/components/layouts/global/aside.tsx | 22 ++- .../src/features/editor/full-editor.tsx | 12 +- .../components/header/page-header-menu.tsx | 9 ++ .../page/hooks/use-restore-page-modal.tsx | 30 ++++ .../src/features/page/queries/page-query.ts | 26 +++- .../trash/components/deleted-page-banner.tsx | 140 ++++++++++++++++++ .../page/trash/components/trash-banner.tsx | 21 +++ .../features/page/trash/components/trash.tsx | 36 +---- apps/client/src/pages/page/page.tsx | 2 +- apps/server/src/core/page/page.controller.ts | 1 + .../src/database/repos/page/page.repo.ts | 5 + 12 files changed, 265 insertions(+), 42 deletions(-) create mode 100644 apps/client/src/features/page/hooks/use-restore-page-modal.tsx create mode 100644 apps/client/src/features/page/trash/components/deleted-page-banner.tsx create mode 100644 apps/client/src/features/page/trash/components/trash-banner.tsx diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index e85f2af23..d59aa94b9 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -71,6 +71,7 @@ "Export": "Export", "Failed to create page": "Failed to create page", "Failed to delete page": "Failed to delete page", + "Failed to restore page": "Failed to restore page", "Failed to fetch recent pages": "Failed to fetch recent pages", "Failed to import pages": "Failed to import pages", "Failed to load page. An error occurred.": "Failed to load page. An error occurred.", @@ -581,6 +582,8 @@ "Move to trash": "Move to trash", "Move this page to trash?": "Move this page to trash?", "Restore page": "Restore page", + "Permanently delete": "Permanently delete", + "{{name}} moved this page to Trash {{time}}.": "{{name}} moved this page to Trash {{time}}.", "Page moved to trash": "Page moved to trash", "Page restored successfully": "Page restored successfully", "Deleted by": "Deleted by", diff --git a/apps/client/src/components/layouts/global/aside.tsx b/apps/client/src/components/layouts/global/aside.tsx index 73e6a381d..23ebe7b7c 100644 --- a/apps/client/src/components/layouts/global/aside.tsx +++ b/apps/client/src/components/layouts/global/aside.tsx @@ -1,4 +1,5 @@ -import { Box, ScrollArea, Text } from "@mantine/core"; +import { ActionIcon, Box, Group, ScrollArea, Text, Tooltip } from "@mantine/core"; +import { IconX } from "@tabler/icons-react"; import CommentListWithTabs from "@/features/comment/components/comment-list-with-tabs.tsx"; import { useAtom } from "jotai"; import { asideStateAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom.ts"; @@ -11,9 +12,10 @@ import AsideChatPanel from "@/ee/ai-chat/components/aside-chat-panel"; import { PageDetailsAside } from "@/features/page-details/components/page-details-aside.tsx"; export default function Aside() { - const [{ tab }] = useAtom(asideStateAtom); + const [{ tab }, setAsideState] = useAtom(asideStateAtom); const { t } = useTranslation(); const pageEditor = useAtomValue(pageEditorAtom); + const closeAside = () => setAsideState((s) => ({ ...s, isAsideOpen: false })); let title: string; let component: ReactNode; @@ -45,9 +47,19 @@ export default function Aside() { {component && ( <> {tab !== "chat" && ( - - {t(title)} - + + {t(title)} + + + + + + )} {tab === "comments" || tab === "chat" ? ( diff --git a/apps/client/src/features/editor/full-editor.tsx b/apps/client/src/features/editor/full-editor.tsx index 57595b288..23a506448 100644 --- a/apps/client/src/features/editor/full-editor.tsx +++ b/apps/client/src/features/editor/full-editor.tsx @@ -23,13 +23,16 @@ import { IContributor } from "@/features/page/types/page.types.ts"; import { FixedToolbar } from "@/features/editor/components/fixed-toolbar/fixed-toolbar"; import { PageEditMode } from "@/features/user/types/user.types.ts"; import useToggleAside from "@/hooks/use-toggle-aside.tsx"; +import { DeletedPageBanner } from "@/features/page/trash/components/deleted-page-banner.tsx"; import clsx from "clsx"; import { currentPageEditModeAtom } from "@/features/editor/atoms/editor-atoms.ts"; const MemoizedTitleEditor = React.memo(TitleEditor); const MemoizedPageEditor = React.memo(PageEditor); +const MemoizedFixedToolbar = React.memo(FixedToolbar); +const MemoizedDeletedPageBanner = React.memo(DeletedPageBanner); -type PageCreator = { +type PageUser = { id: string; name: string; avatarUrl: string; @@ -46,7 +49,7 @@ export interface FullEditorProps { content: string; spaceSlug: string; editable: boolean; - creator?: PageCreator; + creator?: PageUser; contributors?: IContributor[]; canComment?: boolean; } @@ -86,7 +89,8 @@ export function FullEditor({ size={!fullPageWidth && 900} className={classes.editor} > - {editorToolbarEnabled && editable && isEditMode && } + {editorToolbarEnabled && editable && isEditMode && } + diff --git a/apps/client/src/features/page/hooks/use-restore-page-modal.tsx b/apps/client/src/features/page/hooks/use-restore-page-modal.tsx new file mode 100644 index 000000000..f2089f37f --- /dev/null +++ b/apps/client/src/features/page/hooks/use-restore-page-modal.tsx @@ -0,0 +1,30 @@ +import { modals } from "@mantine/modals"; +import { Text } from "@mantine/core"; +import { useTranslation } from "react-i18next"; + +type UseRestoreModalProps = { + title?: string | null; + onConfirm: () => void; +}; + +export function useRestorePageModal() { + const { t } = useTranslation(); + const openRestoreModal = ({ title, onConfirm }: UseRestoreModalProps) => { + modals.openConfirmModal({ + title: t("Restore page"), + children: ( + + {t("Restore '{{title}}' and its sub-pages?", { + title: title || t("Untitled"), + })} + + ), + centered: true, + labels: { confirm: t("Restore"), cancel: t("Cancel") }, + confirmProps: { color: "blue" }, + onConfirm, + }); + }; + + return { openRestoreModal } as const; +} diff --git a/apps/client/src/features/page/queries/page-query.ts b/apps/client/src/features/page/queries/page-query.ts index 1ed704ce1..11ba7f32d 100644 --- a/apps/client/src/features/page/queries/page-query.ts +++ b/apps/client/src/features/page/queries/page-query.ts @@ -117,10 +117,20 @@ export function useUpdatePageMutation() { } export function useRemovePageMutation() { + const { t } = useTranslation(); return useMutation({ mutationFn: (pageId: string) => deletePage(pageId, false), onSuccess: (_, pageId) => { - notifications.show({ message: "Page moved to trash" }); + notifications.show({ message: t("Page moved to trash") }); + + // Stamp deletedAt so a re-visit shows the trash banner, not stale state. + const cached = queryClient.getQueryData(["pages", pageId]); + if (cached) { + const stamped = { ...cached, deletedAt: new Date() }; + queryClient.setQueryData(["pages", cached.id], stamped); + queryClient.setQueryData(["pages", cached.slugId], stamped); + } + invalidateOnDeletePage(pageId); queryClient.invalidateQueries({ predicate: (item) => @@ -128,7 +138,7 @@ export function useRemovePageMutation() { }); }, onError: (error) => { - notifications.show({ message: "Failed to delete page", color: "red" }); + notifications.show({ message: t("Failed to delete page"), color: "red" }); }, }); } @@ -162,13 +172,14 @@ export function useMovePageMutation() { } export function useRestorePageMutation() { + const { t } = useTranslation(); const [treeData, setTreeData] = useAtom(treeDataAtom); const emit = useQueryEmit(); return useMutation({ mutationFn: (pageId: string) => restorePage(pageId), onSuccess: async (restoredPage) => { - notifications.show({ message: "Page restored successfully" }); + notifications.show({ message: t("Page restored successfully") }); // Check if the page already exists in the tree (it shouldn't) if (!treeModel.find(treeData, restoredPage.id)) { @@ -222,9 +233,16 @@ export function useRestorePageMutation() { await queryClient.invalidateQueries({ queryKey: ["trash-list", restoredPage.spaceId], }); + + // Merge — restore endpoint returns a skinny page; + // Replace would strip space/permissions/content and break the editor. + const merge = (cached: IPage | undefined) => + cached ? { ...cached, ...restoredPage } : cached; + queryClient.setQueryData(["pages", restoredPage.id], merge); + queryClient.setQueryData(["pages", restoredPage.slugId], merge); }, onError: (error) => { - notifications.show({ message: "Failed to restore page", color: "red" }); + notifications.show({ message: t("Failed to restore page"), color: "red" }); }, }); } diff --git a/apps/client/src/features/page/trash/components/deleted-page-banner.tsx b/apps/client/src/features/page/trash/components/deleted-page-banner.tsx new file mode 100644 index 000000000..f01a6ab49 --- /dev/null +++ b/apps/client/src/features/page/trash/components/deleted-page-banner.tsx @@ -0,0 +1,140 @@ +import { ActionIcon, Button, Group, Paper, Text, Tooltip } from "@mantine/core"; +import { IconRestore, IconTrash } from "@tabler/icons-react"; +import { useNavigate } from "react-router-dom"; +import { Trans, useTranslation } from "react-i18next"; +import { useTimeAgo } from "@/hooks/use-time-ago.tsx"; +import { useRestorePageModal } from "@/features/page/hooks/use-restore-page-modal.tsx"; +import { useDeletePageModal } from "@/features/page/hooks/use-delete-page-modal.tsx"; +import { + useDeletePageMutation, + usePageQuery, + useRestorePageMutation, +} from "@/features/page/queries/page-query.ts"; +import { getSpaceUrl } from "@/lib/config.ts"; +import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts"; +import { useSpaceAbility } from "@/features/space/permissions/use-space-ability.ts"; +import { + SpaceCaslAction, + SpaceCaslSubject, +} from "@/features/space/permissions/permissions.type.ts"; + +type DeletedPageBannerProps = { + slugId: string; +}; + +export function DeletedPageBanner({ slugId }: DeletedPageBannerProps) { + const { t } = useTranslation(); + const navigate = useNavigate(); + const { data: page } = usePageQuery({ pageId: slugId }); + const { data: space } = useGetSpaceBySlugQuery(page?.space?.slug); + const spaceAbility = useSpaceAbility(space?.membership?.permissions); + const deletedTimeAgo = useTimeAgo(page?.deletedAt); + const restorePageMutation = useRestorePageMutation(); + const deletePageMutation = useDeletePageMutation(); + const { openRestoreModal } = useRestorePageModal(); + const { openDeleteModal } = useDeletePageModal(); + + if (!page?.deletedAt) return null; + + const canRestore = spaceAbility.can( + SpaceCaslAction.Edit, + SpaceCaslSubject.Page, + ); + const canPermanentlyDelete = spaceAbility.can( + SpaceCaslAction.Manage, + SpaceCaslSubject.Settings, + ); + const actorName = page.deletedBy?.name ?? t("Someone"); + + const handleRestore = () => { + openRestoreModal({ + title: page.title, + onConfirm: () => restorePageMutation.mutate(page.id), + }); + }; + + const handlePermanentDelete = () => { + openDeleteModal({ + isPermanent: true, + onConfirm: async () => { + await deletePageMutation.mutateAsync(page.id); + navigate(getSpaceUrl(page.space?.slug)); + }, + }); + }; + + const hasAnyAction = canRestore || canPermanentlyDelete; + + return ( + + + + }} + /> + + {hasAnyAction && ( + <> + + {canRestore && ( + + )} + {canPermanentlyDelete && ( + + )} + + + {canRestore && ( + + + + + + )} + {canPermanentlyDelete && ( + + + + + + )} + + + )} + + + ); +} diff --git a/apps/client/src/features/page/trash/components/trash-banner.tsx b/apps/client/src/features/page/trash/components/trash-banner.tsx new file mode 100644 index 000000000..90ec4a066 --- /dev/null +++ b/apps/client/src/features/page/trash/components/trash-banner.tsx @@ -0,0 +1,21 @@ +import { Alert, Text } from "@mantine/core"; +import { IconInfoCircle } from "@tabler/icons-react"; +import { useAtomValue } from "jotai"; +import { useTranslation } from "react-i18next"; +import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; + +export function TrashBanner() { + const { t } = useTranslation(); + const workspace = useAtomValue(workspaceAtom); + const retentionDays = workspace?.trashRetentionDays ?? 30; + + return ( + } variant="light" color="red"> + + {t("Pages in trash will be permanently deleted after {{count}} days.", { + count: retentionDays, + })} + + + ); +} diff --git a/apps/client/src/features/page/trash/components/trash.tsx b/apps/client/src/features/page/trash/components/trash.tsx index de7e7ca4a..da33d828f 100644 --- a/apps/client/src/features/page/trash/components/trash.tsx +++ b/apps/client/src/features/page/trash/components/trash.tsx @@ -7,17 +7,16 @@ import { Group, ActionIcon, Text, - Alert, Stack, Menu, } from "@mantine/core"; import { - IconInfoCircle, IconDots, IconRestore, IconTrash, IconFileDescription, } from "@tabler/icons-react"; +import { TrashBanner } from "@/features/page/trash/components/trash-banner.tsx"; import { useDeletedPagesQuery, useRestorePageMutation, @@ -31,12 +30,10 @@ import TrashPageContentModal from "@/features/page/trash/components/trash-page-c import { UserInfo } from "@/components/common/user-info.tsx"; import Paginate from "@/components/common/paginate.tsx"; import { useCursorPaginate } from "@/hooks/use-cursor-paginate"; -import { useAtom } from "jotai"; -import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; +import { useRestorePageModal } from "@/features/page/hooks/use-restore-page-modal.tsx"; export default function Trash() { const { t } = useTranslation(); - const [workspace] = useAtom(workspaceAtom); const { spaceSlug } = useParams(); const { cursor, goNext, goPrev } = useCursorPaginate(); const { data: space } = useGetSpaceBySlugQuery(spaceSlug); @@ -45,6 +42,7 @@ export default function Trash() { }); const restorePageMutation = useRestorePageMutation(); const deletePageMutation = useDeletePageMutation(); + const { openRestoreModal } = useRestorePageModal(); const [selectedPage, setSelectedPage] = useState<{ title: string; @@ -78,23 +76,6 @@ export default function Trash() { }); }; - const openRestoreModal = (pageId: string, pageTitle: string) => { - modals.openConfirmModal({ - title: t("Restore page"), - children: ( - - {t("Restore '{{title}}' and its sub-pages?", { - title: pageTitle || "Untitled", - })} - - ), - centered: true, - labels: { confirm: t("Restore"), cancel: t("Cancel") }, - confirmProps: { color: "blue" }, - onConfirm: () => handleRestorePage(pageId), - }); - }; - const hasPages = deletedPages && deletedPages.items.length > 0; const handlePageClick = (page: any) => { @@ -109,11 +90,7 @@ export default function Trash() { {t("Trash")} - } variant="light" color="red"> - - {t("Pages in trash will be permanently deleted after {{count}} days.", { count: workspace?.trashRetentionDays ?? 30 })} - - + {isLoading || !deletedPages ? ( <> @@ -181,7 +158,10 @@ export default function Trash() { } onClick={() => - openRestoreModal(page.id, page.title) + openRestoreModal({ + title: page.title, + onConfirm: () => handleRestorePage(page.id), + }) } > {t("Restore")} diff --git a/apps/client/src/pages/page/page.tsx b/apps/client/src/pages/page/page.tsx index b4e3baa80..1eecd2512 100644 --- a/apps/client/src/pages/page/page.tsx +++ b/apps/client/src/pages/page/page.tsx @@ -52,7 +52,7 @@ function PageContent({ pageSlug }: { pageSlug: string | undefined }) { } = usePageQuery({ pageId: extractPageSlugId(pageSlug) }); const { data: space } = useGetSpaceBySlugQuery(page?.space?.slug); - const canEdit = page?.permissions?.canEdit ?? false; + const canEdit = !page?.deletedAt && (page?.permissions?.canEdit ?? false); const canComment = canEdit || (space?.settings?.comments?.allowViewerComments === true); diff --git a/apps/server/src/core/page/page.controller.ts b/apps/server/src/core/page/page.controller.ts index 5ce077508..773774ea7 100644 --- a/apps/server/src/core/page/page.controller.ts +++ b/apps/server/src/core/page/page.controller.ts @@ -76,6 +76,7 @@ export class PageController { includeCreator: true, includeLastUpdatedBy: true, includeContributors: true, + includeDeletedBy: true, }); if (!page) { diff --git a/apps/server/src/database/repos/page/page.repo.ts b/apps/server/src/database/repos/page/page.repo.ts index 6b17e37f9..259e1bd33 100644 --- a/apps/server/src/database/repos/page/page.repo.ts +++ b/apps/server/src/database/repos/page/page.repo.ts @@ -54,6 +54,7 @@ export class PageRepo { includeCreator?: boolean; includeLastUpdatedBy?: boolean; includeContributors?: boolean; + includeDeletedBy?: boolean; includeHasChildren?: boolean; withLock?: boolean; trx?: KyselyTransaction; @@ -83,6 +84,10 @@ export class PageRepo { query = query.select((eb) => this.withContributors(eb)); } + if (opts?.includeDeletedBy) { + query = query.select((eb) => this.withDeletedBy(eb)); + } + if (opts?.includeSpace) { query = query.select((eb) => this.withSpace(eb)); } From e41518a93db536fd53bcf678a679dd6c983bc862 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Thu, 14 May 2026 14:49:02 +0100 Subject: [PATCH 44/46] fix type --- apps/client/src/features/editor/full-editor.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/client/src/features/editor/full-editor.tsx b/apps/client/src/features/editor/full-editor.tsx index 23a506448..412a3b3de 100644 --- a/apps/client/src/features/editor/full-editor.tsx +++ b/apps/client/src/features/editor/full-editor.tsx @@ -69,7 +69,9 @@ export function FullEditor({ const fullPageWidth = user.settings?.preferences?.fullPageWidth; const editorToolbarEnabled = user.settings?.preferences?.editorToolbar ?? false; - const [currentPageEditMode, setCurrentPageEditMode] = useAtom(currentPageEditModeAtom); + const [currentPageEditMode, setCurrentPageEditMode] = useAtom( + currentPageEditModeAtom, + ); const userPageEditMode = user.settings?.preferences?.pageEditMode ?? PageEditMode.Edit; const isEditMode = currentPageEditMode === PageEditMode.Edit; @@ -78,7 +80,7 @@ export function FullEditor({ // page navigation — so the mode sticks across navigations within a session. useEffect(() => { if (!defaultEditModeApplied) { - setCurrentPageEditMode(userPageEditMode); + setCurrentPageEditMode(userPageEditMode as PageEditMode); defaultEditModeApplied = true; } }, [userPageEditMode, setCurrentPageEditMode]); @@ -89,7 +91,9 @@ export function FullEditor({ size={!fullPageWidth && 900} className={classes.editor} > - {editorToolbarEnabled && editable && isEditMode && } + {editorToolbarEnabled && editable && isEditMode && ( + + )} Date: Thu, 14 May 2026 15:06:51 +0100 Subject: [PATCH 45/46] fix collab module --- .../src/collaboration/server/collab-app.module.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/server/src/collaboration/server/collab-app.module.ts b/apps/server/src/collaboration/server/collab-app.module.ts index f0e27d41a..85738d1cb 100644 --- a/apps/server/src/collaboration/server/collab-app.module.ts +++ b/apps/server/src/collaboration/server/collab-app.module.ts @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'; import { AppController } from '../../app.controller'; import { AppService } from '../../app.service'; import { EnvironmentModule } from '../../integrations/environment/environment.module'; +import { EnvironmentService } from '../../integrations/environment/environment.service'; import { CollaborationModule } from '../collaboration.module'; import { DatabaseModule } from '@docmost/db/database.module'; import { QueueModule } from '../../integrations/queue/queue.module'; @@ -12,6 +13,8 @@ import { LoggerModule } from '../../common/logger/logger.module'; import { RedisModule } from '@nestjs-labs/nestjs-ioredis'; import { RedisConfigService } from '../../integrations/redis/redis-config.service'; import { CaslModule } from '../../core/casl/casl.module'; +import { CacheModule } from '@nestjs/cache-manager'; +import KeyvRedis from '@keyv/redis'; @Module({ imports: [ @@ -26,6 +29,18 @@ import { CaslModule } from '../../core/casl/casl.module'; RedisModule.forRootAsync({ useClass: RedisConfigService, }), + CacheModule.registerAsync({ + isGlobal: true, + useFactory: async (environmentService: EnvironmentService) => { + const redisUrl = environmentService.getRedisUrl(); + + return { + ttl: 5 * 1000, + stores: [new KeyvRedis(redisUrl)], + }; + }, + inject: [EnvironmentService], + }), ], controllers: [ AppController, From b7b99cb3b229196f7f00aaa02fe7a043c0a41134 Mon Sep 17 00:00:00 2001 From: Philip Okugbe <16838612+Philipinho@users.noreply.github.com> Date: Fri, 15 May 2026 02:46:54 +0100 Subject: [PATCH 46/46] fix: code splitting and editor fixes (#2211) * fix table * fix code splitting * fix: editor ready check * fix codeblock/mermaid gap cursor * fix callout --- .../editor/components/audio/audio-menu.tsx | 3 +- .../components/callout/callout-menu.tsx | 4 +- .../components/columns/columns-menu.tsx | 6 +- .../editor/components/drawio/drawio-menu.tsx | 3 +- .../excalidraw/excalidraw-menu-lazy.tsx | 14 ++ .../components/excalidraw/excalidraw-menu.tsx | 3 +- .../excalidraw/excalidraw-view-lazy.tsx | 14 ++ .../editor/components/image/image-menu.tsx | 3 +- .../editor/components/pdf/pdf-menu.tsx | 8 +- .../components/subpages/subpages-menu.tsx | 2 + .../components/table/handle/column-handle.tsx | 7 +- .../components/table/handle/row-handle.tsx | 7 +- .../editor/components/table/table-menu.tsx | 3 +- .../editor/components/video/video-menu.tsx | 3 +- .../features/editor/extensions/extensions.ts | 2 +- .../src/features/editor/page-editor.tsx | 2 +- apps/client/vite.config.ts | 10 +- .../editor-ext/src/lib/callout/callout.ts | 72 +++++++++ .../custom-code-block/custom-code-block.ts | 139 ++++++++++++++++++ packages/editor-ext/src/lib/utils.ts | 9 ++ 20 files changed, 290 insertions(+), 24 deletions(-) create mode 100644 apps/client/src/features/editor/components/excalidraw/excalidraw-menu-lazy.tsx create mode 100644 apps/client/src/features/editor/components/excalidraw/excalidraw-view-lazy.tsx diff --git a/apps/client/src/features/editor/components/audio/audio-menu.tsx b/apps/client/src/features/editor/components/audio/audio-menu.tsx index 3ca1950da..eadc1afe5 100644 --- a/apps/client/src/features/editor/components/audio/audio-menu.tsx +++ b/apps/client/src/features/editor/components/audio/audio-menu.tsx @@ -2,6 +2,7 @@ import { BubbleMenu as BaseBubbleMenu } from "@tiptap/react/menus"; import { findParentNode, posToDOMRect, useEditorState } from "@tiptap/react"; import { useCallback } from "react"; import { Node as PMNode } from "@tiptap/pm/model"; +import { isEditorReady } from "@docmost/editor-ext"; import { EditorMenuProps, ShouldShowProps, @@ -46,7 +47,7 @@ export function AudioMenu({ editor }: EditorMenuProps) { ); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "audio"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/callout/callout-menu.tsx b/apps/client/src/features/editor/components/callout/callout-menu.tsx index 69c836934..3ce022dae 100644 --- a/apps/client/src/features/editor/components/callout/callout-menu.tsx +++ b/apps/client/src/features/editor/components/callout/callout-menu.tsx @@ -16,7 +16,7 @@ import { IconMoodSmile, IconNotes, } from "@tabler/icons-react"; -import { CalloutType, isTextSelected } from "@docmost/editor-ext"; +import { CalloutType, isEditorReady, isTextSelected } from "@docmost/editor-ext"; import { useTranslation } from "react-i18next"; import EmojiPicker from "@/components/ui/emoji-picker.tsx"; import classes from "../common/toolbar-menu.module.css"; @@ -55,7 +55,7 @@ export function CalloutMenu({ editor }: EditorMenuProps) { }); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "callout"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/columns/columns-menu.tsx b/apps/client/src/features/editor/components/columns/columns-menu.tsx index 0ee99508c..4a1f041eb 100644 --- a/apps/client/src/features/editor/components/columns/columns-menu.tsx +++ b/apps/client/src/features/editor/components/columns/columns-menu.tsx @@ -19,7 +19,7 @@ import { IconCopy, IconTrash, } from "@tabler/icons-react"; -import { isTextSelected } from "@docmost/editor-ext"; +import { isEditorReady, isTextSelected } from "@docmost/editor-ext"; import type { WidthMode, ColumnsLayout } from "@docmost/editor-ext"; import { useTranslation } from "react-i18next"; import classes from "../common/toolbar-menu.module.css"; @@ -82,7 +82,7 @@ export function ColumnsMenu({ editor }: EditorMenuProps) { const shouldShow = useCallback( ({ state }: ShouldShowProps) => { - if (!state) return false; + if (!state || !isEditorReady(editor)) return false; if (!editor.isActive("columns")) return false; if (isTextSelected(editor)) return false; if (nodesWithMenus.some((name) => editor.isActive(name))) return false; @@ -121,7 +121,7 @@ export function ColumnsMenu({ editor }: EditorMenuProps) { }); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "columns"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/drawio/drawio-menu.tsx b/apps/client/src/features/editor/components/drawio/drawio-menu.tsx index 869decd71..877911750 100644 --- a/apps/client/src/features/editor/components/drawio/drawio-menu.tsx +++ b/apps/client/src/features/editor/components/drawio/drawio-menu.tsx @@ -2,6 +2,7 @@ import { BubbleMenu as BaseBubbleMenu } from "@tiptap/react/menus"; import { findParentNode, posToDOMRect, useEditorState } from "@tiptap/react"; import { useCallback, useEffect, useRef, useState } from "react"; import { Node as PMNode } from "@tiptap/pm/model"; +import { isEditorReady } from "@docmost/editor-ext"; import { EditorMenuProps, ShouldShowProps, @@ -81,7 +82,7 @@ export function DrawioMenu({ editor }: EditorMenuProps) { ); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "drawio"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/excalidraw/excalidraw-menu-lazy.tsx b/apps/client/src/features/editor/components/excalidraw/excalidraw-menu-lazy.tsx new file mode 100644 index 000000000..acdf5440d --- /dev/null +++ b/apps/client/src/features/editor/components/excalidraw/excalidraw-menu-lazy.tsx @@ -0,0 +1,14 @@ +import { lazy, Suspense } from "react"; +import { EditorMenuProps } from "@/features/editor/components/table/types/types.ts"; + +const ExcalidrawMenu = lazy( + () => import("@/features/editor/components/excalidraw/excalidraw-menu.tsx"), +); + +export default function ExcalidrawMenuLazy(props: EditorMenuProps) { + return ( + + + + ); +} diff --git a/apps/client/src/features/editor/components/excalidraw/excalidraw-menu.tsx b/apps/client/src/features/editor/components/excalidraw/excalidraw-menu.tsx index fd3128062..823c2c213 100644 --- a/apps/client/src/features/editor/components/excalidraw/excalidraw-menu.tsx +++ b/apps/client/src/features/editor/components/excalidraw/excalidraw-menu.tsx @@ -2,6 +2,7 @@ import { BubbleMenu as BaseBubbleMenu } from "@tiptap/react/menus"; import { findParentNode, posToDOMRect, useEditorState } from "@tiptap/react"; import { lazy, Suspense, useCallback, useEffect, useRef, useState } from "react"; import { Node as PMNode } from "@tiptap/pm/model"; +import { isEditorReady } from "@docmost/editor-ext"; import { EditorMenuProps, ShouldShowProps, @@ -94,7 +95,7 @@ export function ExcalidrawMenu({ editor }: EditorMenuProps) { ); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "excalidraw"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/excalidraw/excalidraw-view-lazy.tsx b/apps/client/src/features/editor/components/excalidraw/excalidraw-view-lazy.tsx new file mode 100644 index 000000000..573a25dbd --- /dev/null +++ b/apps/client/src/features/editor/components/excalidraw/excalidraw-view-lazy.tsx @@ -0,0 +1,14 @@ +import { lazy, Suspense } from "react"; +import { NodeViewProps } from "@tiptap/react"; + +const ExcalidrawView = lazy( + () => import("@/features/editor/components/excalidraw/excalidraw-view.tsx"), +); + +export default function ExcalidrawViewLazy(props: NodeViewProps) { + return ( + + + + ); +} diff --git a/apps/client/src/features/editor/components/image/image-menu.tsx b/apps/client/src/features/editor/components/image/image-menu.tsx index 666fab7dc..1b2d00e7e 100644 --- a/apps/client/src/features/editor/components/image/image-menu.tsx +++ b/apps/client/src/features/editor/components/image/image-menu.tsx @@ -2,6 +2,7 @@ import { BubbleMenu as BaseBubbleMenu } from "@tiptap/react/menus"; import { findParentNode, posToDOMRect, useEditorState } from "@tiptap/react"; import React, { useCallback, useRef } from "react"; import { Node as PMNode } from "@tiptap/pm/model"; +import { isEditorReady } from "@docmost/editor-ext"; import { EditorMenuProps, ShouldShowProps, @@ -56,7 +57,7 @@ export function ImageMenu({ editor }: EditorMenuProps) { ); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "image"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/pdf/pdf-menu.tsx b/apps/client/src/features/editor/components/pdf/pdf-menu.tsx index 2104bfbc6..3fc8b6fd1 100644 --- a/apps/client/src/features/editor/components/pdf/pdf-menu.tsx +++ b/apps/client/src/features/editor/components/pdf/pdf-menu.tsx @@ -2,6 +2,7 @@ import { BubbleMenu as BaseBubbleMenu } from "@tiptap/react/menus"; import { findParentNode, posToDOMRect, useEditorState } from "@tiptap/react"; import { useCallback } from "react"; import { Node as PMNode } from "@tiptap/pm/model"; +import { isEditorReady } from "@docmost/editor-ext"; import { EditorMenuProps, ShouldShowProps, @@ -37,9 +38,8 @@ export function PdfMenu({ editor }: EditorMenuProps) { const shouldShow = useCallback( ({ state }: ShouldShowProps) => { - if (!state || !editor.isActive("pdf")) { - return false; - } + if (!state || !isEditorReady(editor)) return false; + if (!editor.isActive("pdf")) return false; const { selection } = state; const dom = editor.view.nodeDOM(selection.from) as HTMLElement | null; @@ -51,7 +51,7 @@ export function PdfMenu({ editor }: EditorMenuProps) { ); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "pdf"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/subpages/subpages-menu.tsx b/apps/client/src/features/editor/components/subpages/subpages-menu.tsx index 9f0544e67..a626e1ee2 100644 --- a/apps/client/src/features/editor/components/subpages/subpages-menu.tsx +++ b/apps/client/src/features/editor/components/subpages/subpages-menu.tsx @@ -6,6 +6,7 @@ import { ActionIcon, Tooltip } from "@mantine/core"; import { IconTrash } from "@tabler/icons-react"; import { useTranslation } from "react-i18next"; import { Editor } from "@tiptap/core"; +import { isEditorReady } from "@docmost/editor-ext"; interface SubpagesMenuProps { editor: Editor; @@ -33,6 +34,7 @@ export const SubpagesMenu = React.memo( ); const getReferenceClientRect = useCallback(() => { + if (!isEditorReady(editor)) return new DOMRect(); const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "subpages"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/table/handle/column-handle.tsx b/apps/client/src/features/editor/components/table/handle/column-handle.tsx index ccc459740..a46ac50d5 100644 --- a/apps/client/src/features/editor/components/table/handle/column-handle.tsx +++ b/apps/client/src/features/editor/components/table/handle/column-handle.tsx @@ -31,7 +31,12 @@ export const ColumnHandle = React.memo(function ColumnHandle({ // (the plugin re-emits `hoveringCell` with the mapped pos a tick later); // unmounting the source element here would make pragmatic-dnd silently // abort the active drag. - const lookupCellDom = editor.view.nodeDOM(anchorPos) as HTMLElement | null; + // `nodeDOM` is typed as `Node | null` — when `anchorPos` goes stale (e.g. + // an external drop reflows the doc before the plugin re-emits + // hoveringCell), it can resolve to a Text node, on which `.closest` is + // undefined. Filter to HTMLElement so downstream consumers stay safe. + const lookupDom = editor.view.nodeDOM(anchorPos); + const lookupCellDom = lookupDom instanceof HTMLElement ? lookupDom : null; const [cellDom, setCellDom] = useState(lookupCellDom); const lastCellDomRef = useRef(lookupCellDom); useEffect(() => { diff --git a/apps/client/src/features/editor/components/table/handle/row-handle.tsx b/apps/client/src/features/editor/components/table/handle/row-handle.tsx index 7a5483558..1f3e3cc51 100644 --- a/apps/client/src/features/editor/components/table/handle/row-handle.tsx +++ b/apps/client/src/features/editor/components/table/handle/row-handle.tsx @@ -29,7 +29,12 @@ export const RowHandle = React.memo(function RowHandle({ // See ColumnHandle for the rationale: keep the last valid cell DOM cached // so the handle div stays mounted across stale-anchor renders, otherwise // pragmatic-dnd silently aborts an in-flight drag. - const lookupCellDom = editor.view.nodeDOM(anchorPos) as HTMLElement | null; + // `nodeDOM` is typed as `Node | null` — when `anchorPos` goes stale (e.g. + // an external drop reflows the doc before the plugin re-emits + // hoveringCell), it can resolve to a Text node, on which `.closest` is + // undefined. Filter to HTMLElement so downstream consumers stay safe. + const lookupDom = editor.view.nodeDOM(anchorPos); + const lookupCellDom = lookupDom instanceof HTMLElement ? lookupDom : null; const [cellDom, setCellDom] = useState(lookupCellDom); const lastCellDomRef = useRef(lookupCellDom); useEffect(() => { diff --git a/apps/client/src/features/editor/components/table/table-menu.tsx b/apps/client/src/features/editor/components/table/table-menu.tsx index 3be7ec539..92cc318e9 100644 --- a/apps/client/src/features/editor/components/table/table-menu.tsx +++ b/apps/client/src/features/editor/components/table/table-menu.tsx @@ -18,7 +18,7 @@ import { IconTrashX, } from "@tabler/icons-react"; import { BubbleMenu } from "@tiptap/react/menus"; -import { isCellSelection, isTextSelected } from "@docmost/editor-ext"; +import { isCellSelection, isEditorReady, isTextSelected } from "@docmost/editor-ext"; import { useTranslation } from "react-i18next"; import classes from "../common/toolbar-menu.module.css"; @@ -38,6 +38,7 @@ export const TableMenu = React.memo( ); const getReferencedVirtualElement = useCallback(() => { + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "table"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/components/video/video-menu.tsx b/apps/client/src/features/editor/components/video/video-menu.tsx index 3f232625f..429e02f87 100644 --- a/apps/client/src/features/editor/components/video/video-menu.tsx +++ b/apps/client/src/features/editor/components/video/video-menu.tsx @@ -2,6 +2,7 @@ import { BubbleMenu as BaseBubbleMenu } from "@tiptap/react/menus"; import { findParentNode, posToDOMRect, useEditorState } from "@tiptap/react"; import { useCallback } from "react"; import { Node as PMNode } from "@tiptap/pm/model"; +import { isEditorReady } from "@docmost/editor-ext"; import { EditorMenuProps, ShouldShowProps, @@ -53,7 +54,7 @@ export function VideoMenu({ editor }: EditorMenuProps) { ); const getReferencedVirtualElement = useCallback(() => { - if (!editor) return; + if (!isEditorReady(editor)) return; const { selection } = editor.state; const predicate = (node: PMNode) => node.type.name === "video"; const parent = findParentNode(predicate)(selection); diff --git a/apps/client/src/features/editor/extensions/extensions.ts b/apps/client/src/features/editor/extensions/extensions.ts index 91411daef..9857b0551 100644 --- a/apps/client/src/features/editor/extensions/extensions.ts +++ b/apps/client/src/features/editor/extensions/extensions.ts @@ -85,7 +85,7 @@ import AudioView from "@/features/editor/components/audio/audio-view.tsx"; import AttachmentView from "@/features/editor/components/attachment/attachment-view.tsx"; import CodeBlockView from "@/features/editor/components/code-block/code-block-view.tsx"; import DrawioView from "../components/drawio/drawio-view"; -import ExcalidrawView from "@/features/editor/components/excalidraw/excalidraw-view.tsx"; +import ExcalidrawView from "@/features/editor/components/excalidraw/excalidraw-view-lazy.tsx"; import EmbedView from "@/features/editor/components/embed/embed-view.tsx"; import PdfView from "@/features/editor/components/pdf/pdf-view.tsx"; import SubpagesView from "@/features/editor/components/subpages/subpages-view.tsx"; diff --git a/apps/client/src/features/editor/page-editor.tsx b/apps/client/src/features/editor/page-editor.tsx index 9d53eec31..8521356ec 100644 --- a/apps/client/src/features/editor/page-editor.tsx +++ b/apps/client/src/features/editor/page-editor.tsx @@ -55,7 +55,7 @@ import { handleFileDrop, handlePaste, } from "@/features/editor/components/common/editor-paste-handler.tsx"; -import ExcalidrawMenu from "./components/excalidraw/excalidraw-menu"; +import ExcalidrawMenu from "./components/excalidraw/excalidraw-menu-lazy"; import DrawioMenu from "./components/drawio/drawio-menu"; import { useCollabToken } from "@/features/auth/queries/auth-query.tsx"; import SearchAndReplaceDialog from "@/features/editor/components/search-and-replace/search-and-replace-dialog.tsx"; diff --git a/apps/client/vite.config.ts b/apps/client/vite.config.ts index e6f9de48c..b230a29ff 100644 --- a/apps/client/vite.config.ts +++ b/apps/client/vite.config.ts @@ -38,12 +38,12 @@ export default defineConfig(({ mode }) => { build: { rolldownOptions: { output: { - codeSplitting: { + advancedChunks: { groups: [ - { name: "vendor-mantine", test: /@mantine/ }, - { name: "vendor-mermaid", test: /mermaid|cytoscape|elkjs/ }, - { name: "vendor-excalidraw", test: /excalidraw/ }, - { name: "vendor-katex", test: /katex/ }, + { + name: "vendor-mantine", + test: /[\\/]node_modules[\\/]@mantine[\\/]/, + }, ], }, }, diff --git a/packages/editor-ext/src/lib/callout/callout.ts b/packages/editor-ext/src/lib/callout/callout.ts index 898fc4152..a07a4a96c 100644 --- a/packages/editor-ext/src/lib/callout/callout.ts +++ b/packages/editor-ext/src/lib/callout/callout.ts @@ -162,6 +162,28 @@ export const Callout = Node.create({ return false; } + // Empty callout: delete the whole node so Backspace inside it isn't + // a no-op (isolating: true blocks the default join with the block + // above). + const calloutDepth = $from.depth - 1; + if (calloutDepth >= 0) { + const calloutNode = $from.node(calloutDepth); + if ( + calloutNode.type === this.type && + calloutNode.childCount === 1 && + calloutNode.firstChild?.content.size === 0 + ) { + const calloutPos = $from.before(calloutDepth); + const { tr } = state; + tr.delete(calloutPos, calloutPos + calloutNode.nodeSize); + tr.setSelection( + TextSelection.near(tr.doc.resolve(calloutPos), -1), + ); + view.dispatch(tr); + return true; + } + } + const previousPosition = $from.before($from.depth) - 1; // If nothing above to join with @@ -207,6 +229,56 @@ export const Callout = Node.create({ } return false; }, + + // Exit the callout into a fresh paragraph below when the cursor sits + // in an empty trailing child. An empty callout (single empty + // paragraph) exits on the first Enter and keeps the empty callout + // intact; a callout with content needs the double-Enter pattern + // (first Enter splits, second Enter on the new trailing empty exits + // and removes that trailing paragraph). + Enter: ({ editor }) => { + const { state, view } = editor; + const { selection } = state; + if (!selection.empty) return false; + + const { $from } = selection; + const calloutDepth = $from.depth - 1; + if (calloutDepth < 0) return false; + + const calloutNode = $from.node(calloutDepth); + if (calloutNode.type !== this.type) return false; + if ($from.parent.content.size !== 0) return false; + if ($from.index(calloutDepth) !== calloutNode.childCount - 1) { + return false; + } + + const paragraphType = state.schema.nodes.paragraph; + const containerDepth = calloutDepth - 1; + const container = $from.node(containerDepth); + const indexAfter = $from.indexAfter(containerDepth); + if ( + !container.canReplaceWith(indexAfter, indexAfter, paragraphType) + ) { + return false; + } + + const calloutEnd = $from.after(calloutDepth); + const paragraph = paragraphType.create(); + const { tr } = state; + + if (calloutNode.childCount === 1) { + tr.insert(calloutEnd, paragraph); + tr.setSelection(TextSelection.create(tr.doc, calloutEnd + 1)); + } else { + tr.delete($from.before(), $from.after()); + const insertPos = tr.mapping.map(calloutEnd); + tr.insert(insertPos, paragraph); + tr.setSelection(TextSelection.create(tr.doc, insertPos + 1)); + } + + view.dispatch(tr); + return true; + }, }; }, diff --git a/packages/editor-ext/src/lib/custom-code-block/custom-code-block.ts b/packages/editor-ext/src/lib/custom-code-block/custom-code-block.ts index 4c4b6ef77..5d67188a3 100644 --- a/packages/editor-ext/src/lib/custom-code-block/custom-code-block.ts +++ b/packages/editor-ext/src/lib/custom-code-block/custom-code-block.ts @@ -1,5 +1,7 @@ import type { CodeBlockOptions } from '@tiptap/extension-code-block'; import CodeBlock from '@tiptap/extension-code-block'; +import { Plugin, Selection, TextSelection } from '@tiptap/pm/state'; +import { GapCursor } from '@tiptap/pm/gapcursor'; import { LowlightPlugin } from './lowlight-plugin.js'; import { ReactNodeViewRenderer } from '@tiptap/react'; @@ -19,7 +21,11 @@ const TAB_CHAR = '\u00A0\u00A0'; * @see https://tiptap.dev/api/nodes/code-block-lowlight */ export const CustomCodeBlock = CodeBlock.extend({ + // Run ahead of Gapcursor (100) so the mermaid arrow-into-source plugin + // can intercept before gapcursor takes over. + priority: 101, selectable: true, + isolating: true, addOptions() { return { @@ -35,8 +41,86 @@ export const CustomCodeBlock = CodeBlock.extend({ }, addKeyboardShortcuts() { + const isMermaid = (node: any) => + node?.type === this.type && node.attrs.language === 'mermaid'; + return { ...this.parent?.(), + // Stop at the gap (or enter mermaid source) instead of jumping + // straight into the next block, so the user can place a cursor + // between two adjacent isolating blocks. + ArrowDown: ({ editor }) => { + const { state } = editor; + const { selection, doc } = state; + const { $from, empty } = selection; + + if (!empty || $from.parent.type !== this.type) return false; + if ($from.parentOffset !== $from.parent.nodeSize - 2) return false; + + const after = $from.after(); + if (after >= doc.content.size) { + return editor.commands.exitCode(); + } + + const $after = doc.resolve(after); + const nodeAfter = $after.nodeAfter; + + if (isMermaid(nodeAfter)) { + return editor.commands.command(({ tr }) => { + tr.setSelection(TextSelection.create(tr.doc, after + 1)); + return true; + }); + } + + if ( + nodeAfter?.type.spec.isolating && + !nodeAfter.type.spec.atom + ) { + return editor.commands.command(({ tr }) => { + tr.setSelection(new GapCursor(tr.doc.resolve(after))); + return true; + }); + } + + return editor.commands.command(({ tr }) => { + tr.setSelection(Selection.near(tr.doc.resolve(after))); + return true; + }); + }, + // Mirror of ArrowDown; upstream has no ArrowUp handler. + ArrowUp: ({ editor }) => { + const { state } = editor; + const { selection, doc } = state; + const { $from, empty } = selection; + + if (!empty || $from.parent.type !== this.type) return false; + if ($from.parentOffset !== 0) return false; + + const before = $from.before(); + if (before <= 0) return false; + + const $before = doc.resolve(before); + const nodeBefore = $before.nodeBefore; + + if (isMermaid(nodeBefore)) { + return editor.commands.command(({ tr }) => { + tr.setSelection(TextSelection.create(tr.doc, before - 1)); + return true; + }); + } + + if ( + nodeBefore?.type.spec.isolating && + !nodeBefore.type.spec.atom + ) { + return editor.commands.command(({ tr }) => { + tr.setSelection(new GapCursor(tr.doc.resolve(before))); + return true; + }); + } + + return false; + }, 'Mod-a': () => { if (this.editor.isActive('codeBlock')) { const { state } = this.editor; @@ -84,6 +168,7 @@ export const CustomCodeBlock = CodeBlock.extend({ }, addProseMirrorPlugins() { + const codeBlockType = this.type; return [ ...(this.parent?.() || []), LowlightPlugin({ @@ -91,6 +176,60 @@ export const CustomCodeBlock = CodeBlock.extend({ lowlight: this.options.lowlight, defaultLanguage: this.options.defaultLanguage, }), + // Mermaid hides its
 when unselected, so the browser's native
+      // vertical caret movement skips past it. Land the cursor inside the
+      // source explicitly.
+      new Plugin({
+        props: {
+          handleKeyDown: (view, event) => {
+            if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown') {
+              return false;
+            }
+            const { state } = view;
+            const { selection } = state;
+            if (
+              !selection.empty ||
+              !(selection instanceof TextSelection)
+            ) {
+              return false;
+            }
+            const { $from } = selection;
+            if ($from.depth === 0 || $from.parent.type === codeBlockType) {
+              return false;
+            }
+            const dir = event.key === 'ArrowUp' ? 'up' : 'down';
+            if (!view.endOfTextblock(dir)) return false;
+
+            const isMermaid = (node: any) =>
+              node?.type === codeBlockType && node.attrs.language === 'mermaid';
+
+            if (event.key === 'ArrowUp') {
+              if ($from.parentOffset !== 0) return false;
+              const beforePos = $from.before();
+              const prev = state.doc.resolve(beforePos).nodeBefore;
+              if (!isMermaid(prev)) return false;
+              const endPos = beforePos - 1;
+              view.dispatch(
+                state.tr.setSelection(
+                  TextSelection.create(state.doc, endPos),
+                ),
+              );
+              return true;
+            }
+            if ($from.parentOffset !== $from.parent.nodeSize - 2) return false;
+            const afterPos = $from.after();
+            const next = state.doc.resolve(afterPos).nodeAfter;
+            if (!isMermaid(next)) return false;
+            const startPos = afterPos + 1;
+            view.dispatch(
+              state.tr.setSelection(
+                TextSelection.create(state.doc, startPos),
+              ),
+            );
+            return true;
+          },
+        },
+      }),
     ];
   },
 });
diff --git a/packages/editor-ext/src/lib/utils.ts b/packages/editor-ext/src/lib/utils.ts
index 3bfd01778..8d03577c7 100644
--- a/packages/editor-ext/src/lib/utils.ts
+++ b/packages/editor-ext/src/lib/utils.ts
@@ -338,6 +338,15 @@ export const isRowGripSelected = ({
   return !!gripRow;
 };
 
+// TipTap's `editor.view` proxy throws if accessed before mount or after destroy.
+// Guard floating-menu callbacks (getReferencedVirtualElement, shouldShow) with
+// this before touching `editor.view.nodeDOM(...)`.
+export function isEditorReady(
+  editor: Editor | null | undefined,
+): editor is Editor {
+  return !!editor && editor.isInitialized;
+}
+
 export function isTextSelected(editor: Editor) {
   const {
     state: {