diff --git a/apps/backend/package.json b/apps/backend/package.json index 89c5d2f6f..5b54bd42b 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -70,9 +70,12 @@ "ai": "^4.3.17", "bcrypt": "^5.1.1", "chokidar-cli": "^3.0.0", + "data-uri-to-buffer": "^6.0.2", "dotenv": "^16.4.5", "dotenv-cli": "^7.3.0", + "file-type": "^21.0.0", "freestyle-sandboxes": "^0.0.92", + "image-size": "^2.0.2", "jose": "^5.2.2", "json-diff": "^1.0.6", "next": "15.4.1", diff --git a/apps/backend/prisma/migrations/20250730164439_profile_image_key/migration.sql b/apps/backend/prisma/migrations/20250730164439_profile_image_key/migration.sql new file mode 100644 index 000000000..c498bbc84 --- /dev/null +++ b/apps/backend/prisma/migrations/20250730164439_profile_image_key/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE "ProjectUser" ADD COLUMN "profileImageKey" TEXT; + +-- AlterTable +ALTER TABLE "Team" ADD COLUMN "profileImageKey" TEXT; diff --git a/apps/backend/prisma/schema.prisma b/apps/backend/prisma/schema.prisma index 9b04c8400..8fd10344e 100644 --- a/apps/backend/prisma/schema.prisma +++ b/apps/backend/prisma/schema.prisma @@ -75,11 +75,16 @@ model Team { updatedAt DateTime @updatedAt displayName String - profileImageUrl String? clientMetadata Json? clientReadOnlyMetadata Json? serverMetadata Json? + // if profileImageKey is set, we fetch the image from S3 + // otherwise if the profileImageUrl is set, we send the user to the URL. + // if neither is set, we return null. + profileImageKey String? + profileImageUrl String? + teamMembers TeamMember[] projectApiKey ProjectApiKey[] @@ -157,7 +162,12 @@ model ProjectUser { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - profileImageUrl String? + // if profileImageKey is set, we fetch the image from S3 + // otherwise if the profileImageUrl is set, we send the user to the URL. + // if neither is set, we return null. + profileImageKey String? + profileImageUrl String? + displayName String? serverMetadata Json? clientReadOnlyMetadata Json? diff --git a/apps/backend/scripts/db-migrations.ts b/apps/backend/scripts/db-migrations.ts index 6fc82700a..037604f4a 100644 --- a/apps/backend/scripts/db-migrations.ts +++ b/apps/backend/scripts/db-migrations.ts @@ -70,6 +70,8 @@ const main = async () => { break; } case 'generate-migration-file': { + await promptDropDb(); + execSync('pnpm prisma migrate reset --force --skip-seed', { stdio: 'inherit' }); execSync('pnpm prisma migrate dev --skip-seed', { stdio: 'inherit' }); await dropSchema(); await migrate(); diff --git a/apps/backend/src/app/api/latest/users/crud.tsx b/apps/backend/src/app/api/latest/users/crud.tsx index fb5e28dba..71d4c7baf 100644 --- a/apps/backend/src/app/api/latest/users/crud.tsx +++ b/apps/backend/src/app/api/latest/users/crud.tsx @@ -7,6 +7,7 @@ import { PrismaTransaction } from "@/lib/types"; import { sendTeamMembershipDeletedWebhook, sendUserCreatedWebhook, sendUserDeletedWebhook, sendUserUpdatedWebhook } from "@/lib/webhooks"; import { RawQuery, getPrismaClientForSourceOfTruth, getPrismaClientForTenancy, getPrismaSchemaForSourceOfTruth, getPrismaSchemaForTenancy, globalPrismaClient, rawQuery, retryTransaction, sqlQuoteIdent } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; +import { checkImageString, getS3PublicUrl, uploadBase64Image } from "@/s3"; import { log } from "@/utils/telemetry"; import { runAsynchronouslyAndWaitUntil } from "@/utils/vercel"; import { BooleanTrue, Prisma } from "@prisma/client"; @@ -65,7 +66,7 @@ export const userPrismaToCrud = ( primary_email: primaryEmailContactChannel?.value || null, primary_email_verified: !!primaryEmailContactChannel?.isVerified, primary_email_auth_enabled: !!primaryEmailContactChannel?.usedForAuth, - profile_image_url: prisma.profileImageUrl, + profile_image_url: prisma.profileImageKey ? getS3PublicUrl(prisma.profileImageKey) : prisma.profileImageUrl, signed_up_at_millis: prisma.createdAt.getTime(), client_metadata: prisma.clientMetadata, client_read_only_metadata: prisma.clientReadOnlyMetadata, @@ -304,7 +305,7 @@ export function getUserQuery(projectId: string, branchId: string, userId: string primary_email: primaryEmailContactChannel?.value || null, primary_email_verified: primaryEmailContactChannel?.isVerified || false, primary_email_auth_enabled: primaryEmailContactChannel?.usedForAuth === 'TRUE' ? true : false, - profile_image_url: row.profileImageUrl, + profile_image_url: row.profileImageKey ? getS3PublicUrl(row.profileImageKey) : row.profileImageUrl, signed_up_at_millis: new Date(row.createdAt + "Z").getTime(), client_metadata: row.clientMetadata, client_read_only_metadata: row.clientReadOnlyMetadata, @@ -346,6 +347,37 @@ export function getUserIfOnGlobalPrismaClientQuery(projectId: string, branchId: }; } +async function getProfileImageUrl(input: string | null | undefined) { + let profileImageKey: string | null | undefined = undefined; + let profileImageUrl: string | null | undefined = undefined; + if (input) { + const checkResult = checkImageString(input); + if (checkResult.isBase64Image) { + const { key } = await uploadBase64Image({ input, folderName: "profile-images" }); + profileImageKey = key; + } else if (checkResult.isUrl) { + profileImageUrl = input; + } else { + throw new StatusError(StatusError.BadRequest, "Invalid profile image URL"); + } + + return { + profileImageKey, + profileImageUrl, + }; + } else if (input === null) { + return { + profileImageKey: null, + profileImageUrl: null, + }; + } else { + return { + profileImageKey: undefined, + profileImageUrl: undefined, + }; + } +} + export async function getUser(options: { userId: string } & ({ projectId: string, branchId: string } | { tenancyId: string })) { let projectId, branchId; if (!("tenancyId" in options)) { @@ -476,6 +508,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC const config = auth.tenancy.completeConfig; + const newUser = await tx.projectUser.create({ data: { tenancyId: auth.tenancy.id, @@ -485,9 +518,9 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC clientMetadata: data.client_metadata === null ? Prisma.JsonNull : data.client_metadata, clientReadOnlyMetadata: data.client_read_only_metadata === null ? Prisma.JsonNull : data.client_read_only_metadata, serverMetadata: data.server_metadata === null ? Prisma.JsonNull : data.server_metadata, - profileImageUrl: data.profile_image_url, totpSecret: data.totp_secret_base64 == null ? data.totp_secret_base64 : Buffer.from(decodeBase64(data.totp_secret_base64)), isAnonymous: data.is_anonymous ?? false, + ...await getProfileImageUrl(data.profile_image_url) }, include: userFullInclude, }); @@ -940,10 +973,10 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC clientMetadata: data.client_metadata === null ? Prisma.JsonNull : data.client_metadata, clientReadOnlyMetadata: data.client_read_only_metadata === null ? Prisma.JsonNull : data.client_read_only_metadata, serverMetadata: data.server_metadata === null ? Prisma.JsonNull : data.server_metadata, - profileImageUrl: data.profile_image_url, requiresTotpMfa: data.totp_secret_base64 === undefined ? undefined : (data.totp_secret_base64 !== null), totpSecret: data.totp_secret_base64 == null ? data.totp_secret_base64 : Buffer.from(decodeBase64(data.totp_secret_base64)), isAnonymous: data.is_anonymous ?? undefined, + ...await getProfileImageUrl(data.profile_image_url) }, include: userFullInclude, }); diff --git a/apps/backend/src/lib/images.tsx b/apps/backend/src/lib/images.tsx new file mode 100644 index 000000000..d86d8b8c9 --- /dev/null +++ b/apps/backend/src/lib/images.tsx @@ -0,0 +1,90 @@ +import sharp from 'sharp'; + +class ImageProcessingError extends Error { + constructor(message: string) { + super(message); + this.name = 'ImageProcessingError'; + } +} + +export async function parseBase64Image(input: string, options: { + maxBytes?: number, + maxWidth?: number, + maxHeight?: number, + allowTypes?: string[], +} = { + maxBytes: 10 * 1024, + maxWidth: 4096, + maxHeight: 4096, + allowTypes: ['image/jpeg', 'image/png', 'image/webp'], +}) { + // Remove data URL prefix if present (e.g., "data:image/jpeg;base64,") + const base64Data = input.replace(/^data:image\/[a-z]+;base64,/, ''); + + if (base64Data.length > options.maxBytes!) { + throw new ImageProcessingError(`Image size (${base64Data.length} bytes) exceeds maximum allowed size (${options.maxBytes} bytes)`); + } + + // Convert base64 to buffer + let imageBuffer: Buffer; + try { + imageBuffer = Buffer.from(base64Data, 'base64'); + } catch (error) { + throw new Error('Invalid base64 image data'); + } + + // Check file size + if (options.maxBytes && imageBuffer.length > options.maxBytes) { + throw new Error(`Image size (${imageBuffer.length} bytes) exceeds maximum allowed size (${options.maxBytes} bytes)`); + } + + // Use Sharp to load image and get metadata + let sharpImage: sharp.Sharp; + let metadata: sharp.Metadata; + + try { + sharpImage = sharp(imageBuffer); + metadata = await sharpImage.metadata(); + } catch (error) { + throw new ImageProcessingError('Invalid image format or corrupted image data'); + } + + // Validate image format + if (!metadata.format) { + throw new ImageProcessingError('Unable to determine image format'); + } + + const mimeType = `image/${metadata.format}`; + if (options.allowTypes && !options.allowTypes.includes(mimeType)) { + throw new ImageProcessingError(`Image type ${mimeType} is not allowed. Allowed types: ${options.allowTypes.join(', ')}`); + } + + if (!metadata.width || !metadata.height) { + throw new ImageProcessingError('Unable to determine image dimensions'); + } + + if (options.maxWidth && metadata.width > options.maxWidth) { + throw new ImageProcessingError(`Image width (${metadata.width}px) exceeds maximum allowed width (${options.maxWidth}px)`); + } + + if (options.maxHeight && metadata.height > options.maxHeight) { + throw new ImageProcessingError(`Image height (${metadata.height}px) exceeds maximum allowed height (${options.maxHeight}px)`); + } + + // Return the validated image data and metadata + return { + buffer: imageBuffer, + metadata: { + format: metadata.format, + mimeType, + width: metadata.width, + height: metadata.height, + size: imageBuffer.length, + channels: metadata.channels, + density: metadata.density, + hasProfile: metadata.hasProfile, + hasAlpha: metadata.hasAlpha, + }, + sharp: sharpImage, + }; +} diff --git a/apps/backend/src/s3.tsx b/apps/backend/src/s3.tsx index 7c22b0534..8c4ac22c5 100644 --- a/apps/backend/src/s3.tsx +++ b/apps/backend/src/s3.tsx @@ -1,5 +1,6 @@ -import { S3Client } from "@aws-sdk/client-s3"; +import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { getEnvVariable } from "@stackframe/stack-shared/dist/utils/env"; +import { parseBase64Image } from "./lib/images"; export const s3 = new S3Client({ region: getEnvVariable("STACK_S3_REGION"), @@ -11,9 +12,43 @@ export const s3 = new S3Client({ }, }); -export const S3_BUCKET = getEnvVariable("STACK_S3_BUCKET", "stack-storage"); +export const S3_BUCKET = getEnvVariable("STACK_S3_BUCKET"); export const S3_ENDPOINT = getEnvVariable("STACK_S3_ENDPOINT"); export function getS3PublicUrl(key: string): string { return `${S3_ENDPOINT}/${S3_BUCKET}/${key}`; } + +export async function uploadBase64Image({ + input, + maxBytes = 1024 * 100, + folderName, +}: { + input: string, + maxBytes?: number, + folderName: string, +}) { + const { buffer, metadata } = await parseBase64Image(input, { maxBytes }); + + const key = `${folderName}/${crypto.randomUUID()}.${metadata.format}`; + + const command = new PutObjectCommand({ + Bucket: S3_BUCKET, + Key: key, + Body: buffer, + }); + + await s3.send(command); + + return { + key, + url: getS3PublicUrl(key), + }; +} + +export function checkImageString(input: string) { + return { + isBase64Image: /^data:image\/[a-z]+;base64,/.test(input), + isUrl: /^https?:\/\//.test(input), + }; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8fed7342..82ce5b284 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -195,15 +195,24 @@ importers: chokidar-cli: specifier: ^3.0.0 version: 3.0.0 + data-uri-to-buffer: + specifier: ^6.0.2 + version: 6.0.2 dotenv: specifier: ^16.4.5 version: 16.4.7 dotenv-cli: specifier: ^7.3.0 version: 7.4.1 + file-type: + specifier: ^21.0.0 + version: 21.0.0 freestyle-sandboxes: specifier: ^0.0.92 version: 0.0.92(encoding@0.1.13)(expo-constants@17.1.7(expo@53.0.17(@babel/core@7.26.0)(@expo/metro-runtime@4.0.1(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0)))(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0))(react@19.0.0))(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0)))(expo-linking@7.0.5(expo@53.0.17(@babel/core@7.26.0)(@expo/metro-runtime@4.0.1(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0)))(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0))(react@19.0.0))(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0))(react@19.0.0))(expo@53.0.17(@babel/core@7.26.0)(@expo/metro-runtime@4.0.1(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0)))(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0))(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react-native-safe-area-context@5.5.1(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0))(react@19.0.0))(react-native-screens@4.11.1(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0))(react@19.0.0))(react-native@0.80.1(@babel/core@7.26.0)(@types/react@18.3.12)(react@19.0.0))(ws@8.18.3) + image-size: + specifier: ^2.0.2 + version: 2.0.2 jose: specifier: ^5.2.2 version: 5.4.0 @@ -501,28 +510,6 @@ importers: specifier: ^5.2.2 version: 5.6.3 - apps/mcp-server: - dependencies: - '@modelcontextprotocol/sdk': - specifier: ^1.7.0 - version: 1.7.0 - '@stackframe/js': - specifier: workspace:* - version: link:../../packages/js - dotenv-cli: - specifier: ^7.3.0 - version: 7.4.1 - openapi-types: - specifier: ^12.1.3 - version: 12.1.3 - devDependencies: - '@types/node': - specifier: 20.17.6 - version: 20.17.6 - typescript: - specifier: 5.3.3 - version: 5.3.3 - apps/mock-oauth-server: dependencies: '@types/express': @@ -4413,10 +4400,6 @@ packages: '@mermaid-js/parser@0.4.0': resolution: {integrity: sha512-wla8XOWvQAwuqy+gxiZqY+c7FokraOTHRWMsbB4AgRx9Sy7zKslNyejy7E+a77qHfey5GXw/ik3IXv/NHMJgaA==} - '@modelcontextprotocol/sdk@1.7.0': - resolution: {integrity: sha512-IYPe/FLpvF3IZrd/f5p5ffmWhMc3aEMuM2wGJASDqC2Ge7qatVCdbfPx3n/5xFeb19xN0j/911M2AaFuircsWA==} - engines: {node: '>=18'} - '@monaco-editor/loader@1.5.0': resolution: {integrity: sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==} @@ -7197,6 +7180,13 @@ packages: '@types/react': optional: true + '@tokenizer/inflate@0.2.7': + resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + '@ts-morph/common@0.27.0': resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==} @@ -7878,10 +7868,6 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - accessor-fn@1.5.1: resolution: {integrity: sha512-zZpFYBqIL1Aqg+f2qmYHJ8+yIZF7/tP6PUGx2/QM0uGPSO5UegpinmkNwDohxWtOj586BpMPVRUjce2HI6xB3A==} engines: {node: '>=12'} @@ -8301,10 +8287,6 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@2.1.0: - resolution: {integrity: sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==} - engines: {node: '>=18'} - boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -8848,10 +8830,6 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} - content-disposition@1.0.0: - resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} - engines: {node: '>= 0.6'} - content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} @@ -8865,10 +8843,6 @@ packages: cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} @@ -8894,10 +8868,6 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - cose-base@1.0.3: resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} @@ -9133,6 +9103,10 @@ packages: resolution: {integrity: sha512-tMK0m4OVGqiA3zkn8JmO6YAqD8UwJqIAx4AAwFl1SKTtKAqcXePuT+n2aayiX9uITtlN3DFtKKTOxJRUc2+HvQ==} engines: {node: '>=12'} + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -9193,15 +9167,6 @@ packages: supports-color: optional: true - debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -9918,14 +9883,6 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.0: - resolution: {integrity: sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==} - engines: {node: '>=18.0.0'} - - eventsource@3.0.5: - resolution: {integrity: sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==} - engines: {node: '>=18.0.0'} - exec-async@2.2.0: resolution: {integrity: sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==} @@ -10034,20 +9991,10 @@ packages: resolution: {integrity: sha512-6CX17Cu+rC2Fi2CyZ4CkgVG3hLl6BFsdAxfXiZkmDFIDY4mRx2y2spdeH6dqPHI9rP+AsHEfGeKz84Uuw7+Pmg==} engines: {node: ^v12.20.0 || >=v14.13.0} - express-rate-limit@7.5.0: - resolution: {integrity: sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==} - engines: {node: '>= 16'} - peerDependencies: - express: ^4.11 || 5 || ^5.0.0-beta.1 - express@4.21.2: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} - express@5.0.1: - resolution: {integrity: sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==} - engines: {node: '>= 18'} - exsolve@1.0.5: resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} @@ -10143,6 +10090,9 @@ packages: fflate@0.4.8: resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -10151,6 +10101,10 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-type@21.0.0: + resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} + engines: {node: '>=20'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -10167,10 +10121,6 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} - find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} @@ -10269,10 +10219,6 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -10787,10 +10733,6 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - iconv-lite@0.5.2: - resolution: {integrity: sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==} - engines: {node: '>=0.10.0'} - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -11066,9 +11008,6 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} @@ -11782,20 +11721,12 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -12001,10 +11932,6 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.0: - resolution: {integrity: sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==} - engines: {node: '>= 0.6'} - mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -12528,9 +12455,6 @@ packages: openapi-sampler@1.6.1: resolution: {integrity: sha512-s1cIatOqrrhSj2tmJ4abFYZQK6l5v+V4toO5q1Pa0DyN8mtyqy2I+Qrj5W9vOELEtybIMQs/TBZGVO/DtTFK8w==} - openapi-types@12.1.3: - resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} - openapi@1.0.1: resolution: {integrity: sha512-hiQ6/K2Q2eFqlOoPQb8V2hzsVsbv31ipMCKfuwZQmqf+MnLzVUcYMBy0h/Y+Sv/HeDCTN4mf0GoOmET4EoJS8A==} hasBin: true @@ -12709,10 +12633,6 @@ packages: path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} - path-to-regexp@8.2.0: - resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} - engines: {node: '>=16'} - path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -12797,10 +12717,6 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} - pkce-challenge@4.1.0: - resolution: {integrity: sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==} - engines: {node: '>=16.20.0'} - pkg-types@1.2.1: resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} @@ -13109,10 +13025,6 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} - quansync@0.2.10: resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} @@ -13161,10 +13073,6 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} - rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -13683,10 +13591,6 @@ packages: roughjs@4.6.6: resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} - router@2.1.0: - resolution: {integrity: sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==} - engines: {node: '>= 18'} - rrweb-cssom@0.7.1: resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} @@ -13793,10 +13697,6 @@ packages: resolution: {integrity: sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==} engines: {node: '>= 0.8.0'} - send@1.1.0: - resolution: {integrity: sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==} - engines: {node: '>= 18'} - sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} @@ -13814,10 +13714,6 @@ packages: resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} engines: {node: '>= 0.8.0'} - serve-static@2.1.0: - resolution: {integrity: sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==} - engines: {node: '>= 18'} - serve@14.2.4: resolution: {integrity: sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==} engines: {node: '>= 14'} @@ -14145,6 +14041,10 @@ packages: strnum@2.1.1: resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} + strtok3@10.3.4: + resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} + engines: {node: '>=18'} + structured-headers@0.4.1: resolution: {integrity: sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==} @@ -14444,6 +14344,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + token-types@6.0.4: + resolution: {integrity: sha512-MD9MjpVNhVyH4fyd5rKphjvt/1qj+PtQUz65aFqAZA6XniWAuSFRjLk3e2VALEFlh9OwBpXUN7rfeqSnT/Fmkw==} + engines: {node: '>=14.16'} + toposort@2.0.2: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} @@ -14666,10 +14570,6 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - type-is@2.0.0: - resolution: {integrity: sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==} - engines: {node: '>= 0.6'} - typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -14711,6 +14611,10 @@ packages: engines: {node: '>=0.8.0'} hasBin: true + uint8array-extras@1.4.0: + resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + engines: {node: '>=18'} + unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} @@ -15455,11 +15359,6 @@ packages: yup@1.4.0: resolution: {integrity: sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==} - zod-to-json-schema@3.24.4: - resolution: {integrity: sha512-0uNlcvgabyrni9Ag8Vghj21drk7+7tp7VTwwR7KxxXXc/3pbXz2PHlDgj3cICahgF1kHm4dExBFj7BXrZJXzig==} - peerDependencies: - zod: ^3.24.1 - zod-to-json-schema@3.24.6: resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} peerDependencies: @@ -18739,20 +18638,6 @@ snapshots: dependencies: langium: 3.3.1 - '@modelcontextprotocol/sdk@1.7.0': - dependencies: - content-type: 1.0.5 - cors: 2.8.5 - eventsource: 3.0.5 - express: 5.0.1 - express-rate-limit: 7.5.0(express@5.0.1) - pkce-challenge: 4.1.0 - raw-body: 3.0.0 - zod: 3.25.76 - zod-to-json-schema: 3.24.4(zod@3.25.76) - transitivePeerDependencies: - - supports-color - '@monaco-editor/loader@1.5.0': dependencies: state-local: 1.0.7 @@ -22286,6 +22171,16 @@ snapshots: optionalDependencies: '@types/react': 18.3.12 + '@tokenizer/inflate@0.2.7': + dependencies: + debug: 4.4.1 + fflate: 0.8.2 + token-types: 6.0.4 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + '@ts-morph/common@0.27.0': dependencies: fast-glob: 3.3.3 @@ -23225,11 +23120,6 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - accepts@2.0.0: - dependencies: - mime-types: 3.0.0 - negotiator: 1.0.0 - accessor-fn@1.5.1: {} acorn-import-attributes@1.9.5(acorn@8.14.0): @@ -23787,20 +23677,6 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.1.0: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.0 - http-errors: 2.0.0 - iconv-lite: 0.5.2 - on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.0 - type-is: 2.0.0 - transitivePeerDependencies: - - supports-color - boolbase@1.0.0: {} bowser@2.11.0: {} @@ -24402,10 +24278,6 @@ snapshots: dependencies: safe-buffer: 5.2.1 - content-disposition@1.0.0: - dependencies: - safe-buffer: 5.2.1 - content-type@1.0.5: {} convert-source-map@1.9.0: {} @@ -24414,8 +24286,6 @@ snapshots: cookie-signature@1.0.6: {} - cookie-signature@1.2.2: {} - cookie@0.6.0: {} cookie@0.7.1: {} @@ -24435,11 +24305,6 @@ snapshots: core-util-is@1.0.3: {} - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - cose-base@1.0.3: dependencies: layout-base: 1.0.2 @@ -24721,6 +24586,8 @@ snapshots: dependencies: index-array-by: 1.4.2 + data-uri-to-buffer@6.0.2: {} + data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 @@ -24770,10 +24637,6 @@ snapshots: dependencies: ms: 2.1.2 - debug@4.3.6: - dependencies: - ms: 2.1.2 - debug@4.3.7: dependencies: ms: 2.1.3 @@ -25943,12 +25806,6 @@ snapshots: events@3.3.0: {} - eventsource-parser@3.0.0: {} - - eventsource@3.0.5: - dependencies: - eventsource-parser: 3.0.0 - exec-async@2.2.0: {} execa@5.1.1: @@ -26107,10 +25964,6 @@ snapshots: export-to-csv@1.4.0: {} - express-rate-limit@7.5.0(express@5.0.1): - dependencies: - express: 5.0.1 - express@4.21.2: dependencies: accepts: 1.3.8 @@ -26147,43 +26000,6 @@ snapshots: transitivePeerDependencies: - supports-color - express@5.0.1: - dependencies: - accepts: 2.0.0 - body-parser: 2.1.0 - content-disposition: 1.0.0 - content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.2.2 - debug: 4.3.6 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.0 - fresh: 2.0.0 - http-errors: 2.0.0 - merge-descriptors: 2.0.0 - methods: 1.1.2 - mime-types: 3.0.0 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.13.0 - range-parser: 1.2.1 - router: 2.1.0 - safe-buffer: 5.2.1 - send: 1.1.0 - serve-static: 2.1.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 2.0.0 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - exsolve@1.0.5: {} extend-shallow@2.0.1: @@ -26272,6 +26088,8 @@ snapshots: fflate@0.4.8: {} + fflate@0.8.2: {} + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 @@ -26280,6 +26098,15 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-type@21.0.0: + dependencies: + '@tokenizer/inflate': 0.2.7 + strtok3: 10.3.4 + token-types: 6.0.4 + uint8array-extras: 1.4.0 + transitivePeerDependencies: + - supports-color + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -26310,17 +26137,6 @@ snapshots: transitivePeerDependencies: - supports-color - finalhandler@2.1.0: - dependencies: - debug: 4.4.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - find-root@1.1.0: {} find-up@3.0.0: @@ -26457,8 +26273,6 @@ snapshots: fresh@0.5.2: {} - fresh@2.0.0: {} - fs-constants@1.0.0: {} fs-extra@11.2.0: @@ -27218,10 +27032,6 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.5.2: - dependencies: - safer-buffer: 2.1.2 - iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -27466,8 +27276,6 @@ snapshots: is-potential-custom-element-name@1.0.1: {} - is-promise@4.0.0: {} - is-reference@1.2.1: dependencies: '@types/estree': 1.0.6 @@ -28301,14 +28109,10 @@ snapshots: media-typer@0.3.0: {} - media-typer@1.1.0: {} - memoize-one@5.2.1: {} merge-descriptors@1.0.3: {} - merge-descriptors@2.0.0: {} - merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -28803,10 +28607,6 @@ snapshots: dependencies: mime-db: 1.52.0 - mime-types@3.0.0: - dependencies: - mime-db: 1.53.0 - mime@1.6.0: {} mimic-fn@1.2.0: {} @@ -29474,8 +29274,6 @@ snapshots: fast-xml-parser: 4.5.3 json-pointer: 0.6.2 - openapi-types@12.1.3: {} - openapi@1.0.1(encoding@0.1.13): dependencies: '@types/jest': 26.0.24 @@ -29682,8 +29480,6 @@ snapshots: path-to-regexp@6.2.2: {} - path-to-regexp@8.2.0: {} - path-type@4.0.0: {} path@0.12.7: @@ -29750,8 +29546,6 @@ snapshots: pirates@4.0.7: {} - pkce-challenge@4.1.0: {} - pkg-types@1.2.1: dependencies: confbox: 0.1.8 @@ -30099,10 +29893,6 @@ snapshots: dependencies: side-channel: 1.0.6 - qs@6.14.0: - dependencies: - side-channel: 1.1.0 - quansync@0.2.10: {} query-string@7.1.3: @@ -30149,13 +29939,6 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.0: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.6.3 - unpipe: 1.0.0 - rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -30940,12 +30723,6 @@ snapshots: points-on-curve: 0.2.0 points-on-path: 0.2.1 - router@2.1.0: - dependencies: - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.2.0 - rrweb-cssom@0.7.1: {} rsvp@3.2.1: {} @@ -31069,23 +30846,6 @@ snapshots: transitivePeerDependencies: - supports-color - send@1.1.0: - dependencies: - debug: 4.4.0 - destroy: 1.2.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime-types: 2.1.35 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - sentence-case@3.0.4: dependencies: no-case: 3.0.4 @@ -31117,15 +30877,6 @@ snapshots: transitivePeerDependencies: - supports-color - serve-static@2.1.0: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.1.0 - transitivePeerDependencies: - - supports-color - serve@14.2.4: dependencies: '@zeit/schemas': 2.36.0 @@ -31535,6 +31286,10 @@ snapshots: strnum@2.1.1: {} + strtok3@10.3.4: + dependencies: + '@tokenizer/token': 0.3.0 + structured-headers@0.4.1: {} style-to-js@1.1.16: @@ -31948,6 +31703,11 @@ snapshots: toidentifier@1.0.1: {} + token-types@6.0.4: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + toposort@2.0.2: {} totalist@3.0.1: {} @@ -32257,12 +32017,6 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - type-is@2.0.0: - dependencies: - content-type: 1.0.5 - media-typer: 1.1.0 - mime-types: 3.0.0 - typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.8 @@ -32314,6 +32068,8 @@ snapshots: uglify-js@3.18.0: optional: true + uint8array-extras@1.4.0: {} + unbox-primitive@1.0.2: dependencies: call-bind: 1.0.8 @@ -33131,10 +32887,6 @@ snapshots: toposort: 2.0.2 type-fest: 2.19.0 - zod-to-json-schema@3.24.4(zod@3.25.76): - dependencies: - zod: 3.25.76 - zod-to-json-schema@3.24.6(zod@3.25.76): dependencies: zod: 3.25.76