This commit is contained in:
Zai Shi 2025-07-30 09:46:02 -07:00
parent 4e25c869aa
commit 13bb68e081
8 changed files with 259 additions and 329 deletions

View File

@ -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",

View File

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "ProjectUser" ADD COLUMN "profileImageKey" TEXT;
-- AlterTable
ALTER TABLE "Team" ADD COLUMN "profileImageKey" TEXT;

View File

@ -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?

View File

@ -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();

View File

@ -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,
});

View File

@ -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,
};
}

View File

@ -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),
};
}

View File

@ -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