diff --git a/packages/app/server/src/env.ts b/packages/app/server/src/env.ts index da23dd994..de6590269 100644 --- a/packages/app/server/src/env.ts +++ b/packages/app/server/src/env.ts @@ -45,6 +45,8 @@ export const env = createEnv({ GROQ_API_KEY: z.string().optional(), XAI_API_KEY: z.string().optional(), OPENROUTER_API_KEY: z.string().optional(), + AI_GATEWAY_API_KEY: z.string().optional(), + VERCEL_OIDC_TOKEN: z.string().optional(), TAVILY_API_KEY: z.string().optional(), E2B_API_KEY: z.string().optional(), GOOGLE_SERVICE_ACCOUNT_KEY_ENCODED: z.string().optional(), diff --git a/packages/app/server/src/providers/ProviderFactory.ts b/packages/app/server/src/providers/ProviderFactory.ts index 8bc01e719..c0215211f 100644 --- a/packages/app/server/src/providers/ProviderFactory.ts +++ b/packages/app/server/src/providers/ProviderFactory.ts @@ -20,6 +20,7 @@ import { GPTProvider } from './GPTProvider'; import { OpenAIImageProvider } from './OpenAIImageProvider'; import { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; import { OpenRouterProvider } from './OpenRouterProvider'; +import { VercelAIGatewayProvider } from './VercelAIGatewayProvider'; import { ProviderType } from './ProviderType'; import { XAIProvider } from './XAIProvider'; import { @@ -50,6 +51,9 @@ const createChatModelToProviderMapping = (): Record => { case 'OpenRouter': mapping[modelConfig.model_id] = ProviderType.OPENROUTER; break; + case 'VercelAIGateway': + mapping[modelConfig.model_id] = ProviderType.VERCEL_AI_GATEWAY; + break; case 'Groq': mapping[modelConfig.model_id] = ProviderType.GROQ; break; @@ -192,6 +196,8 @@ export const getProvider = ( return new GroqProvider(stream, model); case ProviderType.XAI: return new XAIProvider(stream, model); + case ProviderType.VERCEL_AI_GATEWAY: + return new VercelAIGatewayProvider(stream, model); default: throw new Error(`Unknown provider type: ${type}`); } diff --git a/packages/app/server/src/providers/ProviderType.ts b/packages/app/server/src/providers/ProviderType.ts index b2514ac80..41ded7703 100644 --- a/packages/app/server/src/providers/ProviderType.ts +++ b/packages/app/server/src/providers/ProviderType.ts @@ -12,4 +12,5 @@ export enum ProviderType { OPENAI_VIDEOS = 'OPENAI_VIDEOS', GROQ = 'GROQ', XAI = 'XAI', + VERCEL_AI_GATEWAY = 'VERCEL_AI_GATEWAY', } diff --git a/packages/app/server/src/providers/VercelAIGatewayProvider.ts b/packages/app/server/src/providers/VercelAIGatewayProvider.ts new file mode 100644 index 000000000..b2fce71c3 --- /dev/null +++ b/packages/app/server/src/providers/VercelAIGatewayProvider.ts @@ -0,0 +1,136 @@ +import { LlmTransactionMetadata, Transaction } from '../types'; +import { BaseProvider } from './BaseProvider'; +import { ProviderType } from './ProviderType'; +import { getCostPerToken } from '../services/AccountingService'; +import logger from '../logger'; +import { env } from '../env'; + +interface TokenUsage { + inputTokens: number; + outputTokens: number; + totalTokens: number; +} + +const VERCEL_AI_GATEWAY_BASE_URL = 'https://ai-gateway.vercel.sh/v1/ai'; + +const toNumber = (value: unknown): number => + typeof value === 'number' && Number.isFinite(value) ? value : 0; + +const readUsage = (value: unknown): TokenUsage => { + if (!value || typeof value !== 'object') { + return { inputTokens: 0, outputTokens: 0, totalTokens: 0 }; + } + + const record = value as Record; + const usage = + record.usage && typeof record.usage === 'object' + ? (record.usage as Record) + : record; + + const inputTokens = + toNumber(usage.inputTokens) || + toNumber(usage.promptTokens) || + toNumber(usage.prompt_tokens) || + toNumber(usage.input_tokens); + const outputTokens = + toNumber(usage.outputTokens) || + toNumber(usage.completionTokens) || + toNumber(usage.completion_tokens) || + toNumber(usage.output_tokens); + const totalTokens = + toNumber(usage.totalTokens) || + toNumber(usage.total_tokens) || + inputTokens + outputTokens; + + return { inputTokens, outputTokens, totalTokens }; +}; + +const parseStreamUsage = (data: string): TokenUsage => { + let inputTokens = 0; + let outputTokens = 0; + let totalTokens = 0; + + for (const line of data.split('\n')) { + const trimmed = line.trim(); + if (!trimmed || trimmed === 'data: [DONE]') continue; + + const jsonLine = trimmed.startsWith('data: ') + ? trimmed.slice('data: '.length) + : trimmed; + + try { + const parsed = JSON.parse(jsonLine); + const usage = readUsage(parsed); + inputTokens += usage.inputTokens; + outputTokens += usage.outputTokens; + totalTokens += usage.totalTokens; + } catch { + // The AI SDK stream may include non-JSON protocol frames; ignore those. + } + } + + return { + inputTokens, + outputTokens, + totalTokens: totalTokens || inputTokens + outputTokens, + }; +}; + +export class VercelAIGatewayProvider extends BaseProvider { + getType(): ProviderType { + return ProviderType.VERCEL_AI_GATEWAY; + } + + getBaseUrl(): string { + return VERCEL_AI_GATEWAY_BASE_URL; + } + + getApiKey(): string | undefined { + return env.AI_GATEWAY_API_KEY || env.VERCEL_OIDC_TOKEN; + } + + override async formatAuthHeaders( + headers: Record + ): Promise> { + const formattedHeaders = await super.formatAuthHeaders(headers); + + return { + ...formattedHeaders, + 'ai-gateway-protocol-version': + headers['ai-gateway-protocol-version'] || '0.0.1', + 'ai-gateway-auth-method': env.AI_GATEWAY_API_KEY ? 'api-key' : 'oidc', + }; + } + + async handleBody(data: string): Promise { + try { + const usage = this.getIsStream() + ? parseStreamUsage(data) + : readUsage(JSON.parse(data)); + + const cost = getCostPerToken( + this.getModel(), + usage.inputTokens, + usage.outputTokens + ); + + const metadata: LlmTransactionMetadata = { + providerId: 'null', + provider: this.getType(), + model: this.getModel(), + inputTokens: usage.inputTokens, + outputTokens: usage.outputTokens, + totalTokens: usage.totalTokens, + }; + + return { + metadata, + rawTransactionCost: cost, + status: 'success', + }; + } catch (error) { + logger.error(`Error processing Vercel AI Gateway data: ${error}`); + throw error; + } + } +} diff --git a/packages/app/server/src/services/AccountingService.ts b/packages/app/server/src/services/AccountingService.ts index 02e51e14e..45f077eb2 100644 --- a/packages/app/server/src/services/AccountingService.ts +++ b/packages/app/server/src/services/AccountingService.ts @@ -10,6 +10,7 @@ import { SupportedImageModel, SupportedVideoModel, XAIModels, + VercelAIGatewayModels, } from '@merit-systems/echo-typescript-sdk'; import { Decimal } from '@prisma/client/runtime/library'; @@ -30,6 +31,7 @@ export const ALL_SUPPORTED_MODELS: SupportedModel[] = [ ...OpenRouterModels, ...GroqModels, ...XAIModels, + ...VercelAIGatewayModels, ]; // Handle image models separately since they have different pricing structure diff --git a/packages/app/server/src/services/RequestDataService.ts b/packages/app/server/src/services/RequestDataService.ts index 2d8c99c3c..1abe70cb8 100644 --- a/packages/app/server/src/services/RequestDataService.ts +++ b/packages/app/server/src/services/RequestDataService.ts @@ -13,6 +13,11 @@ export function extractModelName(req: Request): string | undefined { return model; } + const gatewayModel = req.headers['ai-language-model-id']; + if (typeof gatewayModel === 'string' && gatewayModel.length > 0) { + return gatewayModel; + } + const modelFromPath = extractGeminiModelName(req); if (modelFromPath && modelFromPath !== undefined) { @@ -55,6 +60,11 @@ export function extractIsStream(req: Request): boolean { return stream; } + const gatewayStream = req.headers['ai-language-model-streaming']; + if (gatewayStream === 'true') { + return true; + } + if (isGeminiStreamingPath(req.path)) { return true; } diff --git a/packages/sdk/ts/package.json b/packages/sdk/ts/package.json index f2a7f1066..94ef7e038 100644 --- a/packages/sdk/ts/package.json +++ b/packages/sdk/ts/package.json @@ -41,7 +41,6 @@ "author": "Merit Systems", "license": "MIT", "devDependencies": { - "@ai-sdk/gateway": "^1.0.12", "@types/node": "^24.3.1", "@typescript-eslint/eslint-plugin": "^8.34.1", "@typescript-eslint/parser": "^8.34.1", @@ -63,6 +62,7 @@ "@ai-sdk/openai": "2.0.32", "@ai-sdk/xai": "2.0.16", "@openrouter/ai-sdk-provider": "1.2.0", - "ai": "5.0.47" + "ai": "5.0.47", + "@ai-sdk/gateway": "^1.0.12" } } diff --git a/packages/sdk/ts/src/index.ts b/packages/sdk/ts/src/index.ts index 521a30f93..a82e95033 100644 --- a/packages/sdk/ts/src/index.ts +++ b/packages/sdk/ts/src/index.ts @@ -45,6 +45,8 @@ export { GeminiModels } from './supported-models/chat/gemini'; export type { GeminiModel } from './supported-models/chat/gemini'; export { OpenRouterModels } from './supported-models/chat/openrouter'; export type { OpenRouterModel } from './supported-models/chat/openrouter'; +export { VercelAIGatewayModels } from './supported-models/chat/vercel-ai-gateway'; +export type { VercelAIGatewayModel } from './supported-models/chat/vercel-ai-gateway'; export { GroqModels } from './supported-models/chat/groq'; export type { GroqModel } from './supported-models/chat/groq'; export { XAIModels } from './supported-models/chat/xai'; diff --git a/packages/sdk/ts/src/providers/index.ts b/packages/sdk/ts/src/providers/index.ts index 62f54fac8..06a3221e5 100644 --- a/packages/sdk/ts/src/providers/index.ts +++ b/packages/sdk/ts/src/providers/index.ts @@ -4,6 +4,7 @@ export * from './groq'; export * from './xai'; export * from './openai'; export * from './openrouter'; +export * from './vercel-ai-gateway'; export function echoFetch( originalFetch: typeof fetch, @@ -62,4 +63,5 @@ export { type GoogleGenerativeAIProvider } from '@ai-sdk/google'; export { type GroqProvider } from '@ai-sdk/groq'; export { type OpenAIProvider } from '@ai-sdk/openai'; export { type OpenRouterProvider } from '@openrouter/ai-sdk-provider'; +export { type GatewayProvider } from '@ai-sdk/gateway'; export { type XaiProvider } from '@ai-sdk/xai'; diff --git a/packages/sdk/ts/src/providers/vercel-ai-gateway.ts b/packages/sdk/ts/src/providers/vercel-ai-gateway.ts new file mode 100644 index 000000000..9e653e99e --- /dev/null +++ b/packages/sdk/ts/src/providers/vercel-ai-gateway.ts @@ -0,0 +1,23 @@ +import { createGatewayProvider, GatewayProvider } from '@ai-sdk/gateway'; +import { ROUTER_BASE_URL } from 'config'; +import { EchoConfig } from '../types'; +import { validateAppId } from '../utils/validation'; +import { echoFetch } from './index'; + +export function createEchoVercelAIGateway( + { appId, baseRouterUrl = ROUTER_BASE_URL }: EchoConfig, + getTokenFn: (appId: string) => Promise, + onInsufficientFunds?: () => void +): GatewayProvider { + validateAppId(appId, 'createEchoVercelAIGateway'); + + return createGatewayProvider({ + baseURL: baseRouterUrl, + apiKey: 'placeholder_replaced_by_echoFetch', + fetch: echoFetch( + fetch, + async () => await getTokenFn(appId), + onInsufficientFunds + ), + }); +} diff --git a/packages/sdk/ts/src/resources/models.ts b/packages/sdk/ts/src/resources/models.ts index ee4064d98..cb727f5eb 100644 --- a/packages/sdk/ts/src/resources/models.ts +++ b/packages/sdk/ts/src/resources/models.ts @@ -5,6 +5,7 @@ import { AnthropicModels, GeminiModels, OpenRouterModels, + VercelAIGatewayModels, OpenAIImageModels, SupportedModel, SupportedImageModel, @@ -26,6 +27,7 @@ export class ModelsResource extends BaseResource { ...AnthropicModels, ...GeminiModels, ...OpenRouterModels, + ...VercelAIGatewayModels, ]; return allModels; diff --git a/packages/sdk/ts/src/supported-models/chat/vercel-ai-gateway.ts b/packages/sdk/ts/src/supported-models/chat/vercel-ai-gateway.ts new file mode 100644 index 000000000..0d15e7983 --- /dev/null +++ b/packages/sdk/ts/src/supported-models/chat/vercel-ai-gateway.ts @@ -0,0 +1,105 @@ +import { SupportedModel } from '../types'; + +// Union type of Vercel AI Gateway language model IDs supported through Echo. +export type VercelAIGatewayModel = + | 'openai/gpt-4o' + | 'openai/gpt-4o-mini' + | 'openai/gpt-4.1' + | 'openai/gpt-4.1-mini' + | 'openai/gpt-4.1-nano' + | 'openai/gpt-5' + | 'openai/gpt-5-mini' + | 'openai/gpt-5-nano' + | 'anthropic/claude-sonnet-4' + | 'anthropic/claude-opus-4' + | 'google/gemini-2.5-flash' + | 'google/gemini-2.5-pro' + | 'xai/grok-4' + | 'xai/grok-code-fast-1'; + +export const VercelAIGatewayModels: SupportedModel[] = [ + { + model_id: 'openai/gpt-4o', + input_cost_per_token: 0.0000025, + output_cost_per_token: 0.00001, + provider: 'VercelAIGateway', + }, + { + model_id: 'openai/gpt-4o-mini', + input_cost_per_token: 0.00000015, + output_cost_per_token: 0.0000006, + provider: 'VercelAIGateway', + }, + { + model_id: 'openai/gpt-4.1', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000008, + provider: 'VercelAIGateway', + }, + { + model_id: 'openai/gpt-4.1-mini', + input_cost_per_token: 0.0000004, + output_cost_per_token: 0.0000016, + provider: 'VercelAIGateway', + }, + { + model_id: 'openai/gpt-4.1-nano', + input_cost_per_token: 0.0000001, + output_cost_per_token: 0.0000004, + provider: 'VercelAIGateway', + }, + { + model_id: 'openai/gpt-5', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'VercelAIGateway', + }, + { + model_id: 'openai/gpt-5-mini', + input_cost_per_token: 0.00000025, + output_cost_per_token: 0.000002, + provider: 'VercelAIGateway', + }, + { + model_id: 'openai/gpt-5-nano', + input_cost_per_token: 0.00000005, + output_cost_per_token: 0.0000004, + provider: 'VercelAIGateway', + }, + { + model_id: 'anthropic/claude-sonnet-4', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + provider: 'VercelAIGateway', + }, + { + model_id: 'anthropic/claude-opus-4', + input_cost_per_token: 0.000015, + output_cost_per_token: 0.000075, + provider: 'VercelAIGateway', + }, + { + model_id: 'google/gemini-2.5-flash', + input_cost_per_token: 0.0000003, + output_cost_per_token: 0.0000025, + provider: 'VercelAIGateway', + }, + { + model_id: 'google/gemini-2.5-pro', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'VercelAIGateway', + }, + { + model_id: 'xai/grok-4', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + provider: 'VercelAIGateway', + }, + { + model_id: 'xai/grok-code-fast-1', + input_cost_per_token: 0.0000002, + output_cost_per_token: 0.0000015, + provider: 'VercelAIGateway', + }, +]; diff --git a/packages/sdk/ts/src/supported-models/index.ts b/packages/sdk/ts/src/supported-models/index.ts index 3f641501d..531645421 100644 --- a/packages/sdk/ts/src/supported-models/index.ts +++ b/packages/sdk/ts/src/supported-models/index.ts @@ -4,6 +4,7 @@ export * from './chat/anthropic'; export * from './chat/gemini'; export * from './chat/openai'; export * from './chat/openrouter'; +export * from './chat/vercel-ai-gateway'; export * from './image/openai'; export * from './responses/openai'; export * from './video/gemini'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06985ade8..431411126 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,7 +37,7 @@ importers: version: 10.1.5(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)) + version: 2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-prefer-arrow: specifier: ^1.2.3 version: 1.2.3(eslint@9.35.0(jiti@2.5.1)) @@ -1197,6 +1197,9 @@ importers: '@ai-sdk/anthropic': specifier: 2.0.17 version: 2.0.17(zod@4.1.11) + '@ai-sdk/gateway': + specifier: ^1.0.12 + version: 1.0.24(zod@4.1.11) '@ai-sdk/google': specifier: 2.0.14 version: 2.0.14(zod@4.1.11) @@ -1216,9 +1219,6 @@ importers: specifier: 5.0.47 version: 5.0.47(zod@4.1.11) devDependencies: - '@ai-sdk/gateway': - specifier: ^1.0.12 - version: 1.0.24(zod@4.1.11) '@types/node': specifier: ^24.3.1 version: 24.3.1 @@ -2569,9 +2569,11 @@ packages: '@metamask/sdk-analytics@0.0.5': resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} + deprecated: No longer maintained, superseded by @metamask/connect-analytics '@metamask/sdk-communication-layer@0.33.1': resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} + deprecated: No longer maintained, superseded by https://docs.metamask.io/metamask-connect peerDependencies: cross-fetch: ^4.0.0 eciesjs: '*' @@ -2581,9 +2583,11 @@ packages: '@metamask/sdk-install-modal-web@0.32.1': resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} + deprecated: No longer maintained, superseded by https://docs.metamask.io/metamask-connect '@metamask/sdk@0.33.1': resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==} + deprecated: No longer maintained, superseded by https://docs.metamask.io/metamask-connect '@metamask/superstruct@3.2.1': resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} @@ -4441,6 +4445,7 @@ packages: '@safe-global/safe-gateway-typescript-sdk@3.23.1': resolution: {integrity: sha512-6ORQfwtEJYpalCeVO21L4XXGSdbEMfyp2hEv6cP82afKXSwvse6d3sdelgaPWUxHIsFRkWvHDdzh8IyyKHZKxw==} engines: {node: '>=16'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. '@scure/base@1.1.9': resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} @@ -5488,6 +5493,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@unrs/resolver-binding-android-arm-eabi@1.9.0': resolution: {integrity: sha512-h1T2c2Di49ekF2TE8ZCoJkb+jwETKUIPDJ/nO3tJBKlLFPu+fyd93f0rGP/BvArKx2k2HlRM4kqkNarj3dvZlg==} @@ -7955,11 +7961,13 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@11.0.3: resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@11.12.0: @@ -10998,6 +11006,7 @@ packages: tar@7.4.3: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me teeny-request@9.0.0: resolution: {integrity: sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==} @@ -11512,6 +11521,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: @@ -11520,10 +11530,12 @@ packages: uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + 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@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + 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 v8-compile-cache-lib@3.0.1: @@ -11730,6 +11742,7 @@ packages: whatwg-encoding@3.1.1: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} @@ -21903,8 +21916,8 @@ snapshots: '@typescript-eslint/parser': 8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) eslint: 9.35.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-react: 7.37.5(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.35.0(jiti@2.5.1)) @@ -21962,21 +21975,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0)(eslint@9.35.0(jiti@2.5.1)): - dependencies: - '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.1 - eslint: 9.35.0(jiti@2.5.1) - get-tsconfig: 4.10.1 - is-bun-module: 2.0.0 - stable-hash: 0.0.5 - tinyglobby: 0.2.15 - unrs-resolver: 1.9.0 - optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)) - transitivePeerDependencies: - - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1)): dependencies: debug: 3.2.7 @@ -21988,17 +21986,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) - eslint: 9.35.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0)(eslint@9.35.0(jiti@2.5.1)) - transitivePeerDependencies: - - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)): dependencies: '@rtsao/scc': 1.1.0 @@ -22028,35 +22015,6 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1)): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.35.0(jiti@2.5.1) - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.34.1(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.35.0(jiti@2.5.1)): dependencies: aria-query: 5.3.2