├── .gitignore ├── .prettierrc ├── .changeset └── config.json ├── tsconfig.json ├── LICENSE ├── package.json ├── CHANGELOG.md ├── src ├── mock-model.ts ├── index.ts └── index.test.ts ├── README.md └── pnpm-lock.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | esm 4 | .env 5 | .env.* 6 | coverage 7 | .DS_Store 8 | *.log 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "jsxSingleQuote": true, 4 | "tabWidth": 4, 5 | "semi": false, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.4.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "linked": [], 6 | "access": "public", 7 | "baseBranch": "main", 8 | "githubRelease": true, 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "module": "NodeNext", 5 | // "allowJs": true, 6 | "moduleResolution": "NodeNext", 7 | 8 | "lib": ["es2017", "es2022", "es7", "es6", "dom"], 9 | "declaration": true, 10 | "declarationMap": true, 11 | "strict": true, 12 | "noImplicitAny": false, 13 | "downlevelIteration": true, 14 | "esModuleInterop": true, 15 | "sourceMap": true, 16 | "jsx": "react-jsx", 17 | "skipLibCheck": true, 18 | "rootDir": "src", 19 | "outDir": "dist" 20 | }, 21 | "include": ["src"] 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Tommy D. Rossi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ai-fallback", 3 | "version": "1.0.8", 4 | "description": "Automatically switch AI SDK model provider when one of the providers has downtime", 5 | "type": "module", 6 | "main": "dist/index.js", 7 | "types": "dist/index.d.ts", 8 | "repository": "https://github.com/remorses/ai-fallback", 9 | "scripts": { 10 | "build": "tsc", 11 | "prepublishOnly": "pnpm build", 12 | "test": "doppler run -- vitest", 13 | "watch": "tsc -w" 14 | }, 15 | "files": [ 16 | "dist", 17 | "src", 18 | "esm" 19 | ], 20 | "keywords": [], 21 | "author": "Tommaso De Rossi, morse ", 22 | "license": "", 23 | "dependencies": { 24 | "@ai-sdk/provider": "2.0.0", 25 | "@ai-sdk/provider-utils": "3.0.7" 26 | }, 27 | "devDependencies": { 28 | "@ai-sdk/anthropic": "2.0.9", 29 | "@ai-sdk/groq": "2.0.16", 30 | "@ai-sdk/openai": "2.0.23", 31 | "@changesets/cli": "^2.29.6", 32 | "@types/node": "^24.3.0", 33 | "ai": "5.0.30", 34 | "typescript": "^5.9.2", 35 | "vitest": "^3.2.4", 36 | "zod": "^4.1.5" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ai-fallback 2 | 3 | ## 1.0.8 4 | 5 | ### Patch Changes 6 | 7 | - Handle more error string variants for rate limiting (camelCase, PascalCase, with spaces, without underscores) 8 | 9 | ## 1.0.7 10 | 11 | ### Patch Changes 12 | 13 | - handle groq status 498 14 | 15 | ## 1.0.6 16 | 17 | ### Patch Changes 18 | 19 | - Upgrade old ai packages 20 | 21 | ## 1.0.5 22 | 23 | ### Patch Changes 24 | 25 | - Export defaultShouldRetryThisError 26 | 27 | ## 1.0.4 28 | 29 | ### Patch Changes 30 | 31 | - Use latest version of ai packages 32 | 33 | ## 1.0.3 34 | 35 | ### Patch Changes 36 | 37 | - fix infinite retries 38 | 39 | ## 1.0.2 40 | 41 | ### Patch Changes 42 | 43 | - Handle anthropic errors after stream start as part errors 44 | 45 | ## 1.0.1 46 | 47 | ### Patch Changes 48 | 49 | - Add support for object errors thrown by anthropic 50 | 51 | ## 1.0.0 52 | 53 | ### Major Changes 54 | 55 | - 423b412: Add support for AI sdk v5 56 | 57 | ## 0.1.5 58 | 59 | ### Patch Changes 60 | 61 | - Softer deps versions to prevent tsc issues 62 | 63 | ## 0.1.4 64 | 65 | ### Patch Changes 66 | 67 | - Do not store model id globally 68 | 69 | ## 0.1.3 70 | 71 | ### Patch Changes 72 | 73 | - Do not throw in case a model throws a non Error instance 74 | 75 | ## 0.1.2 76 | 77 | ### Patch Changes 78 | 79 | - Update deps 80 | 81 | ## 0.1.1 82 | 83 | ### Patch Changes 84 | 85 | - Removed wrong module export in package.json 86 | 87 | ## 0.1.0 88 | 89 | ### Minor Changes 90 | 91 | - Handle more status code errors 92 | 93 | ## 0.0.6 94 | 95 | ### Patch Changes 96 | 97 | - use error status code if available 98 | 99 | ## 0.0.5 100 | 101 | ### Patch Changes 102 | 103 | - Handle more errors like service unavailable 104 | 105 | ## 0.0.4 106 | 107 | ### Patch Changes 108 | 109 | - Add retryAfterOutput to retry even if error is thrown after stream started 110 | 111 | ## 0.0.3 112 | 113 | ### Patch Changes 114 | 115 | - Removed logger option 116 | 117 | ## 0.0.2 118 | 119 | ### Patch Changes 120 | 121 | - Fix repo url 122 | 123 | ## 0.0.1 124 | 125 | ### Patch Changes 126 | 127 | - Init 128 | -------------------------------------------------------------------------------- /src/mock-model.ts: -------------------------------------------------------------------------------- 1 | import { LanguageModelV2 } from '@ai-sdk/provider' 2 | 3 | function notImplemented(): never { 4 | throw new Error('Not implemented') 5 | } 6 | 7 | export class MockLanguageModelV2 implements LanguageModelV2 { 8 | readonly specificationVersion = 'v2' 9 | 10 | private _supportedUrls: () => LanguageModelV2['supportedUrls'] 11 | 12 | readonly provider: LanguageModelV2['provider'] 13 | readonly modelId: LanguageModelV2['modelId'] 14 | 15 | doGenerate: LanguageModelV2['doGenerate'] 16 | doStream: LanguageModelV2['doStream'] 17 | 18 | doGenerateCalls: Parameters[0][] = [] 19 | doStreamCalls: Parameters[0][] = [] 20 | 21 | constructor({ 22 | provider = 'mock-provider', 23 | modelId = 'mock-model-id', 24 | supportedUrls = {}, 25 | doGenerate = notImplemented, 26 | doStream = notImplemented, 27 | }: { 28 | provider?: LanguageModelV2['provider'] 29 | modelId?: LanguageModelV2['modelId'] 30 | supportedUrls?: 31 | | LanguageModelV2['supportedUrls'] 32 | | (() => LanguageModelV2['supportedUrls']) 33 | doGenerate?: 34 | | LanguageModelV2['doGenerate'] 35 | | Awaited> 36 | | Awaited>[] 37 | doStream?: 38 | | LanguageModelV2['doStream'] 39 | | Awaited> 40 | | Awaited>[] 41 | } = {}) { 42 | this.provider = provider 43 | this.modelId = modelId 44 | this.doGenerate = async (options) => { 45 | this.doGenerateCalls.push(options) 46 | 47 | if (typeof doGenerate === 'function') { 48 | return doGenerate(options) 49 | } else if (Array.isArray(doGenerate)) { 50 | return doGenerate[this.doGenerateCalls.length] 51 | } else { 52 | return doGenerate 53 | } 54 | } 55 | this.doStream = async (options) => { 56 | this.doStreamCalls.push(options) 57 | 58 | if (typeof doStream === 'function') { 59 | return doStream(options) 60 | } else if (Array.isArray(doStream)) { 61 | return doStream[this.doStreamCalls.length] 62 | } else { 63 | return doStream 64 | } 65 | } 66 | this._supportedUrls = 67 | typeof supportedUrls === 'function' 68 | ? supportedUrls 69 | : async () => supportedUrls 70 | } 71 | 72 | get supportedUrls() { 73 | return this._supportedUrls() 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### AI Fallback 2 | 3 | Automatically switch between AI model providers when one experiences downtime or errors. 4 | 5 | > [!warning] 6 | > **Version compatibility:** 7 | > - Use `ai-fallback` **version 0** for **AI SDK v4**.
8 | > - Use `ai-fallback` **version 1** for **AI SDK v5** (currently in beta). 9 | 10 | #### Why? 11 | 12 | AI providers can encounter: 13 | 14 | - Rate limiting 15 | - Service outages 16 | - API errors 17 | - Capacity issues 18 | - Timeouts 19 | 20 | This package ensures reliability by specifying multiple AI models as fallbacks. It automatically switches to the next available model if the primary fails, maintaining application uptime. 21 | 22 | --- 23 | 24 | ### Installation 25 | 26 | ```bash 27 | npm install ai-fallback@0 # use version 0.x.x for AI sdk v4 28 | ``` 29 | 30 | --- 31 | 32 | ### Models Fallback Reset 33 | 34 | Reset to the primary model after a delay (e.g., 1 minute): 35 | 36 | ```javascript 37 | const model = createFallback({ 38 | models: [ 39 | anthropic('claude-3-haiku-20240307'), // Use Claude as preferred model 40 | openai('gpt-3.5-turbo'), 41 | ], 42 | onError: (error, modelId) => { 43 | console.error(`Error with model ${modelId}:`, error) 44 | }, 45 | modelResetInterval: 60000, // Reset to first model after 1 minute of the first error 46 | }) 47 | ``` 48 | 49 | --- 50 | 51 | ### Usage 52 | 53 | #### Create a Fallback Model 54 | 55 | ```javascript 56 | import { createFallback } from 'ai-fallback' 57 | import { openai } from '@ai-sdk/openai' 58 | import { anthropic } from '@ai-sdk/anthropic' 59 | 60 | const model = createFallback({ 61 | models: [anthropic('claude-3-haiku-20240307'), openai('gpt-3.5-turbo')], 62 | }) 63 | ``` 64 | 65 | 66 | --- 67 | 68 | ### Text Generation 69 | 70 | Generate text with automatic fallback: 71 | 72 | ```javascript 73 | const result = await generateText({ 74 | model, 75 | system: 'You are a helpful assistant.', 76 | messages: [{ role: 'user', content: 'Count from 1 to 5.' }], 77 | }) 78 | ``` 79 | 80 | --- 81 | 82 | ### Streaming Responses 83 | 84 | Stream text responses: 85 | 86 | ```javascript 87 | const stream = await streamText({ 88 | model, 89 | system: 'You are a helpful assistant.', 90 | messages: [{ role: 'user', content: 'Count from 1 to 5.' }], 91 | }) 92 | 93 | for await (const chunk of stream.textStream) { 94 | console.log(chunk) 95 | } 96 | ``` 97 | 98 | --- 99 | 100 | ### Structured Output 101 | 102 | Stream typed objects using `Zod` schemas: 103 | 104 | ```javascript 105 | import { z } from 'zod' 106 | 107 | const stream = await streamObject({ 108 | model, 109 | system: 'You are a helpful assistant.', 110 | messages: [ 111 | { 112 | role: 'user', 113 | content: 'Give me a person object with name and age properties.', 114 | }, 115 | ], 116 | schema: z.object({ 117 | name: z.string(), 118 | age: z.number(), 119 | }), 120 | }) 121 | 122 | for await (const chunk of stream.partialObjectStream) { 123 | console.log(chunk) 124 | } 125 | ``` 126 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | LanguageModelV2, 3 | LanguageModelV2CallOptions, 4 | LanguageModelV2CallWarning, 5 | LanguageModelV2FinishReason, 6 | LanguageModelV2StreamPart, 7 | LanguageModelV2Content, 8 | LanguageModelV2Usage, 9 | SharedV2ProviderMetadata, 10 | } from '@ai-sdk/provider' 11 | 12 | interface Settings { 13 | models: Array 14 | retryAfterOutput?: boolean 15 | modelResetInterval?: number 16 | shouldRetryThisError?: (error: Error) => boolean 17 | onError?: (error: Error, modelId: string) => void | Promise 18 | } 19 | 20 | export function createFallback(settings: Settings): FallbackModel { 21 | return new FallbackModel(settings) 22 | } 23 | 24 | const retryableStatusCodes = [ 25 | 401, // wrong API key 26 | 403, // permission error, like cannot access model or from a non accessible region 27 | 408, // request timeout 28 | 409, // conflict 29 | 413, // payload too large 30 | 429, // too many requests/rate limits 31 | 498, // groq flex rate limit https://console.groq.com/docs/errors 32 | 500, // server error (and above) 33 | ] 34 | // Common error messages/codes that indicate server overload or temporary issues 35 | const retryableErrors = [ 36 | 'overloaded', 37 | 'service unavailable', 38 | 'bad gateway', 39 | 'too many requests', 40 | 'toomanyrequests', // camelCase/PascalCase variant 41 | 'too many requests', // camelCase/PascalCase variant 42 | 'internal server error', 43 | 'gateway timeout', 44 | 'rate_limit', 45 | 'ratelimit', // variant without underscore 46 | 'rate limit', // variant with space 47 | 'wrong-key', 48 | 'unexpected', 49 | 'capacity', 50 | 'timeout', 51 | 'server_error', 52 | '429', // Too Many Requests 53 | '500', // Internal Server Error 54 | '502', // Bad Gateway 55 | '503', // Service Unavailable 56 | '504', // Gateway Timeout 57 | ] 58 | 59 | export function defaultShouldRetryThisError(error: any): boolean { 60 | let statusCode = error?.['statusCode'] 61 | 62 | if ( 63 | statusCode && 64 | (retryableStatusCodes.includes(statusCode) || statusCode > 500) 65 | ) { 66 | return true 67 | } 68 | 69 | if (error?.message) { 70 | const errorString = error.message.toLowerCase() || '' 71 | return retryableErrors.some((errType) => errorString.includes(errType)) 72 | } 73 | if (error && typeof error === 'object') { 74 | const errorString = JSON.stringify(error).toLowerCase() || '' 75 | return retryableErrors.some((errType) => errorString.includes(errType)) 76 | } 77 | return false 78 | } 79 | 80 | export class FallbackModel implements LanguageModelV2 { 81 | readonly specificationVersion = 'v2' 82 | 83 | get supportedUrls(): 84 | | Record 85 | | PromiseLike> { 86 | return this.settings.models[this.currentModelIndex].supportedUrls 87 | } 88 | 89 | get modelId(): string { 90 | return this.settings.models[this.currentModelIndex].modelId 91 | } 92 | readonly settings: Settings 93 | 94 | currentModelIndex: number = 0 95 | private lastModelReset: number = Date.now() 96 | private readonly modelResetInterval: number 97 | retryAfterOutput: boolean 98 | constructor(settings: Settings) { 99 | this.settings = settings 100 | this.modelResetInterval = settings.modelResetInterval ?? 3 * 60 * 1000 // Default 3 minutes in ms 101 | this.retryAfterOutput = settings.retryAfterOutput ?? true 102 | 103 | if (!this.settings.models[this.currentModelIndex]) { 104 | throw new Error('No models available in settings') 105 | } 106 | } 107 | 108 | get provider(): string { 109 | return this.settings.models[this.currentModelIndex].provider 110 | } 111 | 112 | private checkAndResetModel() { 113 | const now = Date.now() 114 | if ( 115 | now - this.lastModelReset >= this.modelResetInterval && 116 | this.currentModelIndex !== 0 117 | ) { 118 | this.currentModelIndex = 0 119 | this.lastModelReset = now 120 | } 121 | } 122 | 123 | private switchToNextModel() { 124 | this.currentModelIndex = 125 | (this.currentModelIndex + 1) % this.settings.models.length 126 | } 127 | 128 | private async retry(fn: () => PromiseLike): Promise { 129 | let lastError: Error | undefined 130 | const initialModel = this.currentModelIndex 131 | 132 | do { 133 | try { 134 | return await fn() 135 | } catch (error) { 136 | lastError = error as Error 137 | // Only retry if it's a server/capacity error 138 | const shouldRetry = 139 | this.settings.shouldRetryThisError || 140 | defaultShouldRetryThisError 141 | if (!shouldRetry(lastError)) { 142 | throw lastError 143 | } 144 | 145 | if (this.settings.onError) { 146 | await this.settings.onError(lastError, this.modelId) 147 | } 148 | this.switchToNextModel() 149 | 150 | // If we've tried all models, throw the last error 151 | if (this.currentModelIndex === initialModel) { 152 | throw lastError 153 | } 154 | } 155 | } while (true) 156 | } 157 | 158 | doGenerate(options: LanguageModelV2CallOptions): PromiseLike<{ 159 | content: LanguageModelV2Content[] 160 | finishReason: LanguageModelV2FinishReason 161 | usage: LanguageModelV2Usage 162 | providerMetadata?: SharedV2ProviderMetadata 163 | request?: { body?: unknown } 164 | response?: { 165 | headers?: Record 166 | id?: string 167 | timestamp?: Date 168 | modelId?: string 169 | } 170 | warnings: LanguageModelV2CallWarning[] 171 | }> { 172 | this.checkAndResetModel() 173 | return this.retry(() => 174 | this.settings.models[this.currentModelIndex].doGenerate(options), 175 | ) 176 | } 177 | 178 | doStream(options: LanguageModelV2CallOptions): PromiseLike<{ 179 | stream: ReadableStream 180 | request?: { body?: unknown } 181 | response?: { headers?: Record } 182 | }> { 183 | this.checkAndResetModel() 184 | let self = this 185 | const shouldRetry = 186 | this.settings.shouldRetryThisError || defaultShouldRetryThisError 187 | return this.retry(async () => { 188 | const result = 189 | await self.settings.models[this.currentModelIndex].doStream( 190 | options, 191 | ) 192 | 193 | let hasStreamedAny = false 194 | // Wrap the stream to handle errors and switch providers if needed 195 | const wrappedStream = new ReadableStream( 196 | { 197 | async start(controller) { 198 | let reader: ReadableStreamDefaultReader | null = 199 | null 200 | let nextReader: ReadableStreamDefaultReader | null = 201 | null 202 | 203 | try { 204 | reader = result.stream.getReader() 205 | 206 | while (true) { 207 | const result = await reader.read() 208 | 209 | const { done, value } = result 210 | if ( 211 | !hasStreamedAny && 212 | value && 213 | typeof value === 'object' && 214 | 'error' in value 215 | ) { 216 | const error = value.error as any 217 | if (shouldRetry(error)) { 218 | throw error 219 | } 220 | } 221 | 222 | if (done) break 223 | controller.enqueue(value) 224 | 225 | if (value?.type !== 'stream-start') { 226 | hasStreamedAny = true 227 | } 228 | } 229 | controller.close() 230 | } catch (error) { 231 | if (self.settings.onError) { 232 | await self.settings.onError( 233 | error as Error, 234 | self.modelId, 235 | ) 236 | } 237 | 238 | if (!hasStreamedAny || self.retryAfterOutput) { 239 | self.switchToNextModel() 240 | 241 | // TODO should be initialModel instead? 242 | if (self.currentModelIndex === 0) { 243 | controller.error(error) 244 | return 245 | } 246 | 247 | try { 248 | const nextResult = 249 | await self.doStream(options) 250 | nextReader = nextResult.stream.getReader() 251 | while (true) { 252 | const { done, value } = 253 | await nextReader.read() 254 | if (done) break 255 | controller.enqueue(value) 256 | } 257 | controller.close() 258 | } catch (nextError) { 259 | controller.error(nextError) 260 | } finally { 261 | try { 262 | nextReader?.releaseLock() 263 | } catch (e) { 264 | // Ignore release errors 265 | } 266 | } 267 | return 268 | } 269 | controller.error(error) 270 | } finally { 271 | try { 272 | reader?.releaseLock() 273 | } catch (e) { 274 | // Ignore release errors 275 | } 276 | } 277 | }, 278 | }, 279 | ) 280 | 281 | return { 282 | ...result, 283 | stream: wrappedStream, 284 | request: result.request, 285 | response: result.response, 286 | } 287 | }) 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest' 2 | import { z } from 'zod' 3 | import { createFallback } from './index.js' 4 | import { createOpenAI } from '@ai-sdk/openai' 5 | import { createGroq } from '@ai-sdk/groq' 6 | import { createAnthropic } from '@ai-sdk/anthropic' 7 | import { generateText, streamText, streamObject, tool } from 'ai' 8 | import { convertArrayToReadableStream } from '@ai-sdk/provider-utils/test' 9 | import { 10 | LanguageModelV2StreamPart, 11 | LanguageModelV2CallWarning, 12 | } from '@ai-sdk/provider' 13 | import { MockLanguageModelV2 } from './mock-model.js' 14 | 15 | const openai = createOpenAI({ 16 | apiKey: process.env.OPENAI_KEY, 17 | }) 18 | 19 | const anthropic = createAnthropic({ 20 | apiKey: process.env.ANTHROPIC_API_KEY, 21 | }) 22 | 23 | test('createProvider works', async () => { 24 | const model = createFallback({ 25 | models: [anthropic('claude-3-haiku-20240307'), openai('gpt-3.5-turbo')], 26 | }) 27 | 28 | const result = await generateText({ 29 | model, 30 | system: 'You are a sentiment analysis expert. Analyze the sentiment of any text provided and respond with either POSITIVE, NEGATIVE, or NEUTRAL.', 31 | messages: [ 32 | { role: 'user', content: 'I love this product! It works great.' }, 33 | ], 34 | }) 35 | 36 | expect(result.text).toMatchInlineSnapshot('"POSITIVE"') 37 | }) 38 | 39 | test('switches model on error', async () => { 40 | const model = createFallback({ 41 | models: [ 42 | createOpenAI({ apiKey: 'wrong-key' })('gpt-3.5-turbo'), 43 | anthropic('claude-3-haiku-20240307'), 44 | ], 45 | }) 46 | 47 | model.currentModelIndex = 0 48 | 49 | const result = await generateText({ 50 | model, 51 | system: 'You only respond hello', 52 | messages: [{ role: 'user', content: 'Say hello' }], 53 | }) 54 | 55 | // After error with OpenAI, should have switched to Anthropic 56 | expect(model.currentModelIndex).toBe(1) 57 | expect(model.modelId).toBe('claude-3-haiku-20240307') 58 | expect(result.text).toBeTruthy() 59 | model.currentModelIndex = 0 60 | }) 61 | 62 | test('groq switches model on error, switches to third model', async () => { 63 | const model = createFallback({ 64 | models: [ 65 | createGroq({ apiKey: 'wrong-key' })('gpt-3.5-turbo'), 66 | createOpenAI({ apiKey: 'wrong-key' })('gpt-3.5-turbo'), 67 | anthropic('claude-3-haiku-20240307'), 68 | ], 69 | }) 70 | 71 | model.currentModelIndex = 0 72 | 73 | const result = await generateText({ 74 | model, 75 | system: 'You only respond hello', 76 | messages: [{ role: 'user', content: 'Say hello' }], 77 | }) 78 | 79 | // After error with OpenAI, should have switched to Anthropic 80 | expect(model.currentModelIndex).toBe(2) 81 | expect(model.modelId).toMatchInlineSnapshot(`"claude-3-haiku-20240307"`) 82 | expect(result.text).toBeTruthy() 83 | model.currentModelIndex = 0 84 | }) 85 | 86 | test('shouldRetryThisError works with non-existent model error', async () => { 87 | let called = false 88 | const model = createFallback({ 89 | models: [ 90 | openai('non-existent-model'), 91 | anthropic('claude-3-haiku-20240307'), 92 | ], 93 | shouldRetryThisError: (error) => { 94 | called = true 95 | // console.error(error) 96 | return error.message.toLowerCase().includes('does not exist') 97 | }, 98 | }) 99 | 100 | model.currentModelIndex = 0 101 | 102 | const result = await generateText({ 103 | model, 104 | system: 'You only respond hello', 105 | messages: [{ role: 'user', content: 'Say hello' }], 106 | }) 107 | expect(called).toBe(true) 108 | 109 | // Should switch to Anthropic after OpenAI error 110 | expect(model.currentModelIndex).toBe(1) 111 | expect(model.modelId).toBe('claude-3-haiku-20240307') 112 | expect(result.text).toBeTruthy() 113 | model.currentModelIndex = 0 114 | }) 115 | 116 | test('streamText works', async () => { 117 | const model = createFallback({ 118 | models: [anthropic('claude-3-haiku-20240307'), openai('gpt-3.5-turbo')], 119 | }) 120 | 121 | const stream = await streamText({ 122 | model, 123 | system: 'You are a helpful assistant.', 124 | messages: [{ role: 'user', content: 'Count from 1 to 5.' }], 125 | }) 126 | 127 | let text = '' 128 | for await (const chunk of stream.textStream) { 129 | text += chunk 130 | } 131 | 132 | expect(text).toContain('1') 133 | expect(text).toContain('5') 134 | }) 135 | 136 | test('streamObject works', async () => { 137 | const model = createFallback({ 138 | models: [openai('gpt-4.1-mini'), anthropic('claude-3-haiku-20240307')], 139 | }) 140 | 141 | const stream = await streamObject({ 142 | model, 143 | system: 'You are a helpful assistant.', 144 | messages: [ 145 | { 146 | role: 'user', 147 | content: 148 | 'Give me a person object with name set to "Tommy" and age set to 5 properties.', 149 | }, 150 | ], 151 | schema: z.object({ 152 | name: z.string(), 153 | age: z.number(), 154 | }), 155 | }) 156 | 157 | let result 158 | for await (const chunk of stream.partialObjectStream) { 159 | result = chunk 160 | } 161 | expect(await stream.object).toMatchInlineSnapshot(` 162 | { 163 | "age": 5, 164 | "name": "Tommy", 165 | } 166 | `) 167 | 168 | expect(result).toHaveProperty('name') 169 | expect(result).toHaveProperty('age') 170 | expect(typeof result.name).toBe('string') 171 | expect(typeof result.age).toBe('number') 172 | }) 173 | 174 | test('ReadableStream works like i expect', async () => { 175 | // Create a stream that will error 176 | const errorStream = new ReadableStream({ 177 | start(controller) { 178 | controller.error(new Error('Test stream error')) 179 | }, 180 | }) 181 | 182 | // Test that the error is thrown when consuming the stream 183 | let error: Error | undefined 184 | try { 185 | const reader = errorStream.getReader() 186 | while (true) { 187 | const { done, value } = await reader.read() 188 | if (done) break 189 | // Should not get here 190 | console.log(value) 191 | } 192 | } catch (e) { 193 | error = e as Error 194 | } 195 | 196 | expect(error).toBeDefined() 197 | expect(error?.message).toBe('Test stream error') 198 | }) 199 | 200 | test('fallback switches models on stream error before any output', async () => { 201 | // Create OpenAI client that errors immediately 202 | const errorOpenAI = createOpenAI({ 203 | apiKey: process.env.OPENAI_KEY, 204 | fetch: async (url, options) => { 205 | const stream = new ReadableStream({ 206 | start(controller) { 207 | // Error immediately before streaming any data 208 | controller.error(new Error('Injected immediate error')) 209 | }, 210 | }) 211 | 212 | return new Response(stream, { 213 | // headers: result.headers, 214 | // status: result.status, 215 | // statusText: result.statusText, 216 | }) 217 | }, 218 | }) 219 | 220 | let err 221 | const model = createFallback({ 222 | models: [errorOpenAI('gpt-3.5-turbo'), openai('gpt-3.5-turbo')], 223 | onError(error, modelId) { 224 | err = error 225 | }, 226 | }) 227 | model.currentModelIndex = 0 228 | 229 | const { textStream } = await streamText({ 230 | model, 231 | messages: [ 232 | { 233 | role: 'user', 234 | content: 'Say only "hello". only that and nothing else', 235 | }, 236 | ], 237 | }) 238 | 239 | let text = '' 240 | for await (const chunk of textStream) { 241 | text += chunk 242 | } 243 | 244 | expect(err?.message).toBe('Injected immediate error') 245 | console.log({ text }) 246 | expect(text).toBeTruthy() // Verify we got some text after fallback 247 | expect(model.currentModelIndex).toBe(1) // Should have switched to second model 248 | }) 249 | 250 | test('fallback switches models on stream error after some output', { timeout: 10000 }, async () => { 251 | // Create OpenAI client that errors after first token 252 | const errorOpenAI = createOpenAI({ 253 | apiKey: process.env.OPENAI_KEY, 254 | fetch: async (url, options) => { 255 | const result = await fetch(url, options) 256 | const originalBody = result.body 257 | if (!originalBody) throw new Error('No response body') 258 | 259 | const reader = originalBody.getReader() 260 | const stream = new ReadableStream({ 261 | async start(controller) { 262 | { 263 | const { value } = await reader.read() 264 | // console.log(new TextDecoder().decode(value)) 265 | controller.enqueue(value) 266 | } 267 | { 268 | const { value } = await reader.read() 269 | // console.log(new TextDecoder().decode(value)) 270 | controller.enqueue(value) 271 | } 272 | 273 | controller.error( 274 | new Error('Injected error after first token'), 275 | ) 276 | }, 277 | }) 278 | 279 | return new Response(stream, { 280 | headers: result.headers, 281 | status: result.status, 282 | statusText: result.statusText, 283 | }) 284 | }, 285 | }) 286 | 287 | let err 288 | let text = '' 289 | const model = createFallback({ 290 | models: [errorOpenAI('gpt-3.5-turbo'), openai('gpt-3.5-turbo')], 291 | retryAfterOutput: true, 292 | onError(error, modelId) { 293 | err = error 294 | text += 'ERROR' 295 | }, 296 | }) 297 | model.currentModelIndex = 0 298 | 299 | const { textStream } = await streamText({ 300 | model, 301 | messages: [ 302 | { 303 | role: 'user', 304 | content: 'Say only "hello" 3 times. only that and nothing else', 305 | }, 306 | ], 307 | }) 308 | 309 | for await (const chunk of textStream) { 310 | text += chunk 311 | } 312 | 313 | expect(err?.message).toBe('Injected error after first token') 314 | console.log({ text }) 315 | expect(text).toBeTruthy() // Verify we got some text after fallback 316 | expect(model.currentModelIndex).toBe(1) // Should have switched to second model 317 | }) 318 | 319 | function sleep(ms: number) { 320 | return new Promise((resolve) => setTimeout(resolve, ms)) 321 | } 322 | 323 | test( 324 | 'handles overloaded_error from reader.read() and retries with fallback model', 325 | async () => { 326 | const encounteredErrors: any[] = [] 327 | 328 | const model = createFallback({ 329 | models: [ 330 | new MockLanguageModelV2({ 331 | doStream: async () => ({ 332 | stream: convertArrayToReadableStream([ 333 | { 334 | type: 'stream-start', 335 | }, 336 | { 337 | type: 'error', 338 | error: 'Overloaded', 339 | }, 340 | ] as LanguageModelV2StreamPart[]), 341 | }), 342 | }), 343 | openai('gpt-4.1-mini'), 344 | anthropic('claude-3-haiku-20240307'), 345 | ], 346 | shouldRetryThisError: (error) => { 347 | encounteredErrors.push(error) 348 | return true 349 | }, 350 | onError: async (error, modelId) => { 351 | console.log(`Error from model ${modelId}:`, error) 352 | }, 353 | }) 354 | 355 | model.currentModelIndex = 0 356 | 357 | const res = streamText({ 358 | model, 359 | 360 | temperature: 0, 361 | onError: ({ error }) => { 362 | console.log('Error in streamText:', error) 363 | throw error 364 | }, 365 | 366 | messages: [ 367 | { 368 | role: 'user', 369 | content: 370 | 'say "hello" 3 times with spaces. exactly that and nothing else', 371 | }, 372 | ], 373 | }) 374 | await res.consumeStream() 375 | const result = await res.text 376 | expect(result).toBeTruthy() 377 | expect(result).toMatchInlineSnapshot(`"hello hello hello"`) 378 | expect(encounteredErrors.length).toMatchInlineSnapshot(`1`) 379 | expect(encounteredErrors[0]).toMatchInlineSnapshot(`"Overloaded"`) 380 | 381 | expect(model.currentModelIndex).toMatchInlineSnapshot(`1`) 382 | expect(model.modelId).toMatchInlineSnapshot(`"gpt-4.1-mini"`) 383 | }, 384 | 1000 * 20, 385 | ) 386 | 387 | test( 388 | 'Handle consecutive errors from reader.read() and retries with fallback model', 389 | async () => { 390 | const encounteredErrors: any[] = [] 391 | 392 | const model = createFallback({ 393 | models: [ 394 | new MockLanguageModelV2({ 395 | doStream: async () => ({ 396 | stream: convertArrayToReadableStream([ 397 | { 398 | type: 'stream-start', 399 | }, 400 | { 401 | type: 'error', 402 | error: 'Overloaded', 403 | }, 404 | ] as LanguageModelV2StreamPart[]), 405 | }), 406 | }), 407 | new MockLanguageModelV2({ 408 | doStream: async () => ({ 409 | stream: convertArrayToReadableStream([ 410 | { 411 | type: 'stream-start', 412 | }, 413 | { 414 | type: 'error', 415 | error: 'Overloaded', 416 | }, 417 | ] as LanguageModelV2StreamPart[]), 418 | }), 419 | }), 420 | new MockLanguageModelV2({ 421 | doStream: async () => ({ 422 | stream: convertArrayToReadableStream([ 423 | { 424 | type: 'stream-start', 425 | }, 426 | { 427 | type: 'error', 428 | error: 'Overloaded', 429 | }, 430 | ] as LanguageModelV2StreamPart[]), 431 | }), 432 | }), 433 | ], 434 | shouldRetryThisError: (error) => { 435 | encounteredErrors.push(error) 436 | return true 437 | }, 438 | onError: async (error, modelId) => { 439 | console.log(`Error from model ${modelId}:`, error) 440 | }, 441 | }) 442 | 443 | model.currentModelIndex = 0 444 | 445 | const res = streamText({ 446 | model, 447 | 448 | temperature: 0, 449 | onError: ({ error }) => { 450 | console.log('Error in streamText:', error) 451 | throw error 452 | }, 453 | 454 | messages: [ 455 | { 456 | role: 'user', 457 | content: 458 | 'say "hello" 3 times with spaces. exactly that and nothing else', 459 | }, 460 | ], 461 | }) 462 | 463 | // Since all models return errors, this should throw after trying all models 464 | await res.consumeStream() 465 | expect(encounteredErrors.length).toBe(3) 466 | expect(encounteredErrors.every(err => err === 'Overloaded')).toBe(true) 467 | expect(model.currentModelIndex).toBe(0) 468 | }, 469 | 1000 * 20, 470 | ) -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@ai-sdk/provider': 12 | specifier: 2.0.0 13 | version: 2.0.0 14 | '@ai-sdk/provider-utils': 15 | specifier: 3.0.7 16 | version: 3.0.7(zod@4.1.5) 17 | devDependencies: 18 | '@ai-sdk/anthropic': 19 | specifier: 2.0.9 20 | version: 2.0.9(zod@4.1.5) 21 | '@ai-sdk/groq': 22 | specifier: 2.0.16 23 | version: 2.0.16(zod@4.1.5) 24 | '@ai-sdk/openai': 25 | specifier: 2.0.23 26 | version: 2.0.23(zod@4.1.5) 27 | '@changesets/cli': 28 | specifier: ^2.29.6 29 | version: 2.29.6(@types/node@24.3.0) 30 | '@types/node': 31 | specifier: ^24.3.0 32 | version: 24.3.0 33 | ai: 34 | specifier: 5.0.30 35 | version: 5.0.30(zod@4.1.5) 36 | typescript: 37 | specifier: ^5.9.2 38 | version: 5.9.2 39 | vitest: 40 | specifier: ^3.2.4 41 | version: 3.2.4(@types/node@24.3.0) 42 | zod: 43 | specifier: ^4.1.5 44 | version: 4.1.5 45 | 46 | packages: 47 | 48 | '@ai-sdk/anthropic@2.0.9': 49 | resolution: {integrity: sha512-1kQgL2A3PeqfEcHHmqy4NxRc8rbgLS71bHBuvDFfDz3VAAyndkilPMCLNDSP2mJVGAej2EMWJ1sShRAxzn70jA==} 50 | engines: {node: '>=18'} 51 | peerDependencies: 52 | zod: ^3.25.76 || ^4 53 | 54 | '@ai-sdk/gateway@1.0.15': 55 | resolution: {integrity: sha512-xySXoQ29+KbGuGfmDnABx+O6vc7Gj7qugmj1kGpn0rW0rQNn6UKUuvscKMzWyv1Uv05GyC1vqHq8ZhEOLfXscQ==} 56 | engines: {node: '>=18'} 57 | peerDependencies: 58 | zod: ^3.25.76 || ^4 59 | 60 | '@ai-sdk/groq@2.0.16': 61 | resolution: {integrity: sha512-oW/bty0qy56jq4bOhu8IXPDovZyAn73bQVblIwpOMyruAO9CjGMncZmcSju68ZXwT/im8+qUq/vVFLqjdHgHig==} 62 | engines: {node: '>=18'} 63 | peerDependencies: 64 | zod: ^3.25.76 || ^4 65 | 66 | '@ai-sdk/openai@2.0.23': 67 | resolution: {integrity: sha512-uOXk8HzmMUoCmD0JMX/Y1HC/ABOR/Jza2Z2rkCaJISDYz3fp5pnb6eNjcPRL48JSMzRAGp9UP5p0OpxS06IJZg==} 68 | engines: {node: '>=18'} 69 | peerDependencies: 70 | zod: ^3.25.76 || ^4 71 | 72 | '@ai-sdk/provider-utils@3.0.7': 73 | resolution: {integrity: sha512-o3BS5/t8KnBL3ubP8k3w77AByOypLm+pkIL/DCw0qKkhDbvhCy+L3hRTGPikpdb8WHcylAeKsjgwOxhj4cqTUA==} 74 | engines: {node: '>=18'} 75 | peerDependencies: 76 | zod: ^3.25.76 || ^4 77 | 78 | '@ai-sdk/provider@2.0.0': 79 | resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} 80 | engines: {node: '>=18'} 81 | 82 | '@babel/runtime@7.28.3': 83 | resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} 84 | engines: {node: '>=6.9.0'} 85 | 86 | '@changesets/apply-release-plan@7.0.12': 87 | resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} 88 | 89 | '@changesets/assemble-release-plan@6.0.9': 90 | resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} 91 | 92 | '@changesets/changelog-git@0.2.1': 93 | resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} 94 | 95 | '@changesets/cli@2.29.6': 96 | resolution: {integrity: sha512-6qCcVsIG1KQLhpQ5zE8N0PckIx4+9QlHK3z6/lwKnw7Tir71Bjw8BeOZaxA/4Jt00pcgCnCSWZnyuZf5Il05QQ==} 97 | hasBin: true 98 | 99 | '@changesets/config@3.1.1': 100 | resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} 101 | 102 | '@changesets/errors@0.2.0': 103 | resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} 104 | 105 | '@changesets/get-dependents-graph@2.1.3': 106 | resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} 107 | 108 | '@changesets/get-release-plan@4.0.13': 109 | resolution: {integrity: sha512-DWG1pus72FcNeXkM12tx+xtExyH/c9I1z+2aXlObH3i9YA7+WZEVaiHzHl03thpvAgWTRaH64MpfHxozfF7Dvg==} 110 | 111 | '@changesets/get-version-range-type@0.4.0': 112 | resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} 113 | 114 | '@changesets/git@3.0.4': 115 | resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} 116 | 117 | '@changesets/logger@0.1.1': 118 | resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} 119 | 120 | '@changesets/parse@0.4.1': 121 | resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} 122 | 123 | '@changesets/pre@2.0.2': 124 | resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} 125 | 126 | '@changesets/read@0.6.5': 127 | resolution: {integrity: sha512-UPzNGhsSjHD3Veb0xO/MwvasGe8eMyNrR/sT9gR8Q3DhOQZirgKhhXv/8hVsI0QpPjR004Z9iFxoJU6in3uGMg==} 128 | 129 | '@changesets/should-skip-package@0.1.2': 130 | resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} 131 | 132 | '@changesets/types@4.1.0': 133 | resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} 134 | 135 | '@changesets/types@6.1.0': 136 | resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} 137 | 138 | '@changesets/write@0.4.0': 139 | resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} 140 | 141 | '@esbuild/aix-ppc64@0.25.9': 142 | resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} 143 | engines: {node: '>=18'} 144 | cpu: [ppc64] 145 | os: [aix] 146 | 147 | '@esbuild/android-arm64@0.25.9': 148 | resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} 149 | engines: {node: '>=18'} 150 | cpu: [arm64] 151 | os: [android] 152 | 153 | '@esbuild/android-arm@0.25.9': 154 | resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} 155 | engines: {node: '>=18'} 156 | cpu: [arm] 157 | os: [android] 158 | 159 | '@esbuild/android-x64@0.25.9': 160 | resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} 161 | engines: {node: '>=18'} 162 | cpu: [x64] 163 | os: [android] 164 | 165 | '@esbuild/darwin-arm64@0.25.9': 166 | resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} 167 | engines: {node: '>=18'} 168 | cpu: [arm64] 169 | os: [darwin] 170 | 171 | '@esbuild/darwin-x64@0.25.9': 172 | resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} 173 | engines: {node: '>=18'} 174 | cpu: [x64] 175 | os: [darwin] 176 | 177 | '@esbuild/freebsd-arm64@0.25.9': 178 | resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} 179 | engines: {node: '>=18'} 180 | cpu: [arm64] 181 | os: [freebsd] 182 | 183 | '@esbuild/freebsd-x64@0.25.9': 184 | resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} 185 | engines: {node: '>=18'} 186 | cpu: [x64] 187 | os: [freebsd] 188 | 189 | '@esbuild/linux-arm64@0.25.9': 190 | resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} 191 | engines: {node: '>=18'} 192 | cpu: [arm64] 193 | os: [linux] 194 | 195 | '@esbuild/linux-arm@0.25.9': 196 | resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} 197 | engines: {node: '>=18'} 198 | cpu: [arm] 199 | os: [linux] 200 | 201 | '@esbuild/linux-ia32@0.25.9': 202 | resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} 203 | engines: {node: '>=18'} 204 | cpu: [ia32] 205 | os: [linux] 206 | 207 | '@esbuild/linux-loong64@0.25.9': 208 | resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} 209 | engines: {node: '>=18'} 210 | cpu: [loong64] 211 | os: [linux] 212 | 213 | '@esbuild/linux-mips64el@0.25.9': 214 | resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} 215 | engines: {node: '>=18'} 216 | cpu: [mips64el] 217 | os: [linux] 218 | 219 | '@esbuild/linux-ppc64@0.25.9': 220 | resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} 221 | engines: {node: '>=18'} 222 | cpu: [ppc64] 223 | os: [linux] 224 | 225 | '@esbuild/linux-riscv64@0.25.9': 226 | resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} 227 | engines: {node: '>=18'} 228 | cpu: [riscv64] 229 | os: [linux] 230 | 231 | '@esbuild/linux-s390x@0.25.9': 232 | resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} 233 | engines: {node: '>=18'} 234 | cpu: [s390x] 235 | os: [linux] 236 | 237 | '@esbuild/linux-x64@0.25.9': 238 | resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} 239 | engines: {node: '>=18'} 240 | cpu: [x64] 241 | os: [linux] 242 | 243 | '@esbuild/netbsd-arm64@0.25.9': 244 | resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} 245 | engines: {node: '>=18'} 246 | cpu: [arm64] 247 | os: [netbsd] 248 | 249 | '@esbuild/netbsd-x64@0.25.9': 250 | resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} 251 | engines: {node: '>=18'} 252 | cpu: [x64] 253 | os: [netbsd] 254 | 255 | '@esbuild/openbsd-arm64@0.25.9': 256 | resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} 257 | engines: {node: '>=18'} 258 | cpu: [arm64] 259 | os: [openbsd] 260 | 261 | '@esbuild/openbsd-x64@0.25.9': 262 | resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} 263 | engines: {node: '>=18'} 264 | cpu: [x64] 265 | os: [openbsd] 266 | 267 | '@esbuild/openharmony-arm64@0.25.9': 268 | resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} 269 | engines: {node: '>=18'} 270 | cpu: [arm64] 271 | os: [openharmony] 272 | 273 | '@esbuild/sunos-x64@0.25.9': 274 | resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} 275 | engines: {node: '>=18'} 276 | cpu: [x64] 277 | os: [sunos] 278 | 279 | '@esbuild/win32-arm64@0.25.9': 280 | resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} 281 | engines: {node: '>=18'} 282 | cpu: [arm64] 283 | os: [win32] 284 | 285 | '@esbuild/win32-ia32@0.25.9': 286 | resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} 287 | engines: {node: '>=18'} 288 | cpu: [ia32] 289 | os: [win32] 290 | 291 | '@esbuild/win32-x64@0.25.9': 292 | resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} 293 | engines: {node: '>=18'} 294 | cpu: [x64] 295 | os: [win32] 296 | 297 | '@inquirer/external-editor@1.0.1': 298 | resolution: {integrity: sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==} 299 | engines: {node: '>=18'} 300 | peerDependencies: 301 | '@types/node': '>=18' 302 | peerDependenciesMeta: 303 | '@types/node': 304 | optional: true 305 | 306 | '@jridgewell/sourcemap-codec@1.5.5': 307 | resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} 308 | 309 | '@manypkg/find-root@1.1.0': 310 | resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} 311 | 312 | '@manypkg/get-packages@1.1.3': 313 | resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} 314 | 315 | '@nodelib/fs.scandir@2.1.5': 316 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 317 | engines: {node: '>= 8'} 318 | 319 | '@nodelib/fs.stat@2.0.5': 320 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 321 | engines: {node: '>= 8'} 322 | 323 | '@nodelib/fs.walk@1.2.8': 324 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 325 | engines: {node: '>= 8'} 326 | 327 | '@opentelemetry/api@1.9.0': 328 | resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} 329 | engines: {node: '>=8.0.0'} 330 | 331 | '@rollup/rollup-android-arm-eabi@4.50.0': 332 | resolution: {integrity: sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==} 333 | cpu: [arm] 334 | os: [android] 335 | 336 | '@rollup/rollup-android-arm64@4.50.0': 337 | resolution: {integrity: sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==} 338 | cpu: [arm64] 339 | os: [android] 340 | 341 | '@rollup/rollup-darwin-arm64@4.50.0': 342 | resolution: {integrity: sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==} 343 | cpu: [arm64] 344 | os: [darwin] 345 | 346 | '@rollup/rollup-darwin-x64@4.50.0': 347 | resolution: {integrity: sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==} 348 | cpu: [x64] 349 | os: [darwin] 350 | 351 | '@rollup/rollup-freebsd-arm64@4.50.0': 352 | resolution: {integrity: sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==} 353 | cpu: [arm64] 354 | os: [freebsd] 355 | 356 | '@rollup/rollup-freebsd-x64@4.50.0': 357 | resolution: {integrity: sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==} 358 | cpu: [x64] 359 | os: [freebsd] 360 | 361 | '@rollup/rollup-linux-arm-gnueabihf@4.50.0': 362 | resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==} 363 | cpu: [arm] 364 | os: [linux] 365 | 366 | '@rollup/rollup-linux-arm-musleabihf@4.50.0': 367 | resolution: {integrity: sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==} 368 | cpu: [arm] 369 | os: [linux] 370 | 371 | '@rollup/rollup-linux-arm64-gnu@4.50.0': 372 | resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==} 373 | cpu: [arm64] 374 | os: [linux] 375 | 376 | '@rollup/rollup-linux-arm64-musl@4.50.0': 377 | resolution: {integrity: sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==} 378 | cpu: [arm64] 379 | os: [linux] 380 | 381 | '@rollup/rollup-linux-loongarch64-gnu@4.50.0': 382 | resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==} 383 | cpu: [loong64] 384 | os: [linux] 385 | 386 | '@rollup/rollup-linux-ppc64-gnu@4.50.0': 387 | resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==} 388 | cpu: [ppc64] 389 | os: [linux] 390 | 391 | '@rollup/rollup-linux-riscv64-gnu@4.50.0': 392 | resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==} 393 | cpu: [riscv64] 394 | os: [linux] 395 | 396 | '@rollup/rollup-linux-riscv64-musl@4.50.0': 397 | resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==} 398 | cpu: [riscv64] 399 | os: [linux] 400 | 401 | '@rollup/rollup-linux-s390x-gnu@4.50.0': 402 | resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==} 403 | cpu: [s390x] 404 | os: [linux] 405 | 406 | '@rollup/rollup-linux-x64-gnu@4.50.0': 407 | resolution: {integrity: sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==} 408 | cpu: [x64] 409 | os: [linux] 410 | 411 | '@rollup/rollup-linux-x64-musl@4.50.0': 412 | resolution: {integrity: sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==} 413 | cpu: [x64] 414 | os: [linux] 415 | 416 | '@rollup/rollup-openharmony-arm64@4.50.0': 417 | resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==} 418 | cpu: [arm64] 419 | os: [openharmony] 420 | 421 | '@rollup/rollup-win32-arm64-msvc@4.50.0': 422 | resolution: {integrity: sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==} 423 | cpu: [arm64] 424 | os: [win32] 425 | 426 | '@rollup/rollup-win32-ia32-msvc@4.50.0': 427 | resolution: {integrity: sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==} 428 | cpu: [ia32] 429 | os: [win32] 430 | 431 | '@rollup/rollup-win32-x64-msvc@4.50.0': 432 | resolution: {integrity: sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==} 433 | cpu: [x64] 434 | os: [win32] 435 | 436 | '@standard-schema/spec@1.0.0': 437 | resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} 438 | 439 | '@types/chai@5.2.2': 440 | resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} 441 | 442 | '@types/deep-eql@4.0.2': 443 | resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} 444 | 445 | '@types/estree@1.0.8': 446 | resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 447 | 448 | '@types/node@12.20.55': 449 | resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} 450 | 451 | '@types/node@24.3.0': 452 | resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} 453 | 454 | '@vitest/expect@3.2.4': 455 | resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} 456 | 457 | '@vitest/mocker@3.2.4': 458 | resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} 459 | peerDependencies: 460 | msw: ^2.4.9 461 | vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 462 | peerDependenciesMeta: 463 | msw: 464 | optional: true 465 | vite: 466 | optional: true 467 | 468 | '@vitest/pretty-format@3.2.4': 469 | resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} 470 | 471 | '@vitest/runner@3.2.4': 472 | resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} 473 | 474 | '@vitest/snapshot@3.2.4': 475 | resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} 476 | 477 | '@vitest/spy@3.2.4': 478 | resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} 479 | 480 | '@vitest/utils@3.2.4': 481 | resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} 482 | 483 | ai@5.0.30: 484 | resolution: {integrity: sha512-u7WdsDde9BasP+h8Q64CtU32GFShCYmxVtBa2h5dxM1f0w/AMKwzpmIDI1t3M3ean+L6uBiwOtRs8B2KA+OHgQ==} 485 | engines: {node: '>=18'} 486 | peerDependencies: 487 | zod: ^3.25.76 || ^4 488 | 489 | ansi-colors@4.1.3: 490 | resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} 491 | engines: {node: '>=6'} 492 | 493 | ansi-regex@5.0.1: 494 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 495 | engines: {node: '>=8'} 496 | 497 | argparse@1.0.10: 498 | resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} 499 | 500 | array-union@2.1.0: 501 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 502 | engines: {node: '>=8'} 503 | 504 | assertion-error@2.0.1: 505 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 506 | engines: {node: '>=12'} 507 | 508 | better-path-resolve@1.0.0: 509 | resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} 510 | engines: {node: '>=4'} 511 | 512 | braces@3.0.3: 513 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 514 | engines: {node: '>=8'} 515 | 516 | cac@6.7.14: 517 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 518 | engines: {node: '>=8'} 519 | 520 | chai@5.3.3: 521 | resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} 522 | engines: {node: '>=18'} 523 | 524 | chardet@2.1.0: 525 | resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} 526 | 527 | check-error@2.1.1: 528 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} 529 | engines: {node: '>= 16'} 530 | 531 | ci-info@3.9.0: 532 | resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} 533 | engines: {node: '>=8'} 534 | 535 | cross-spawn@7.0.6: 536 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 537 | engines: {node: '>= 8'} 538 | 539 | debug@4.4.1: 540 | resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} 541 | engines: {node: '>=6.0'} 542 | peerDependencies: 543 | supports-color: '*' 544 | peerDependenciesMeta: 545 | supports-color: 546 | optional: true 547 | 548 | deep-eql@5.0.2: 549 | resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 550 | engines: {node: '>=6'} 551 | 552 | detect-indent@6.1.0: 553 | resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} 554 | engines: {node: '>=8'} 555 | 556 | dir-glob@3.0.1: 557 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 558 | engines: {node: '>=8'} 559 | 560 | enquirer@2.4.1: 561 | resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} 562 | engines: {node: '>=8.6'} 563 | 564 | es-module-lexer@1.7.0: 565 | resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} 566 | 567 | esbuild@0.25.9: 568 | resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} 569 | engines: {node: '>=18'} 570 | hasBin: true 571 | 572 | esprima@4.0.1: 573 | resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} 574 | engines: {node: '>=4'} 575 | hasBin: true 576 | 577 | estree-walker@3.0.3: 578 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 579 | 580 | eventsource-parser@3.0.6: 581 | resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} 582 | engines: {node: '>=18.0.0'} 583 | 584 | expect-type@1.2.2: 585 | resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} 586 | engines: {node: '>=12.0.0'} 587 | 588 | extendable-error@0.1.7: 589 | resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} 590 | 591 | fast-glob@3.3.3: 592 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 593 | engines: {node: '>=8.6.0'} 594 | 595 | fastq@1.19.1: 596 | resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} 597 | 598 | fdir@6.5.0: 599 | resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} 600 | engines: {node: '>=12.0.0'} 601 | peerDependencies: 602 | picomatch: ^3 || ^4 603 | peerDependenciesMeta: 604 | picomatch: 605 | optional: true 606 | 607 | fill-range@7.1.1: 608 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 609 | engines: {node: '>=8'} 610 | 611 | find-up@4.1.0: 612 | resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} 613 | engines: {node: '>=8'} 614 | 615 | fs-extra@7.0.1: 616 | resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} 617 | engines: {node: '>=6 <7 || >=8'} 618 | 619 | fs-extra@8.1.0: 620 | resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} 621 | engines: {node: '>=6 <7 || >=8'} 622 | 623 | fsevents@2.3.3: 624 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 625 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 626 | os: [darwin] 627 | 628 | glob-parent@5.1.2: 629 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 630 | engines: {node: '>= 6'} 631 | 632 | globby@11.1.0: 633 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 634 | engines: {node: '>=10'} 635 | 636 | graceful-fs@4.2.11: 637 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 638 | 639 | human-id@4.1.1: 640 | resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} 641 | hasBin: true 642 | 643 | iconv-lite@0.6.3: 644 | resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} 645 | engines: {node: '>=0.10.0'} 646 | 647 | ignore@5.3.2: 648 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 649 | engines: {node: '>= 4'} 650 | 651 | is-extglob@2.1.1: 652 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 653 | engines: {node: '>=0.10.0'} 654 | 655 | is-glob@4.0.3: 656 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 657 | engines: {node: '>=0.10.0'} 658 | 659 | is-number@7.0.0: 660 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 661 | engines: {node: '>=0.12.0'} 662 | 663 | is-subdir@1.2.0: 664 | resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} 665 | engines: {node: '>=4'} 666 | 667 | is-windows@1.0.2: 668 | resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} 669 | engines: {node: '>=0.10.0'} 670 | 671 | isexe@2.0.0: 672 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 673 | 674 | js-tokens@9.0.1: 675 | resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} 676 | 677 | js-yaml@3.14.1: 678 | resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} 679 | hasBin: true 680 | 681 | json-schema@0.4.0: 682 | resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} 683 | 684 | jsonfile@4.0.0: 685 | resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 686 | 687 | locate-path@5.0.0: 688 | resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} 689 | engines: {node: '>=8'} 690 | 691 | lodash.startcase@4.4.0: 692 | resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} 693 | 694 | loupe@3.2.1: 695 | resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} 696 | 697 | magic-string@0.30.18: 698 | resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} 699 | 700 | merge2@1.4.1: 701 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 702 | engines: {node: '>= 8'} 703 | 704 | micromatch@4.0.8: 705 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 706 | engines: {node: '>=8.6'} 707 | 708 | mri@1.2.0: 709 | resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 710 | engines: {node: '>=4'} 711 | 712 | ms@2.1.3: 713 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 714 | 715 | nanoid@3.3.11: 716 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 717 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 718 | hasBin: true 719 | 720 | outdent@0.5.0: 721 | resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} 722 | 723 | p-filter@2.1.0: 724 | resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} 725 | engines: {node: '>=8'} 726 | 727 | p-limit@2.3.0: 728 | resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} 729 | engines: {node: '>=6'} 730 | 731 | p-locate@4.1.0: 732 | resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} 733 | engines: {node: '>=8'} 734 | 735 | p-map@2.1.0: 736 | resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} 737 | engines: {node: '>=6'} 738 | 739 | p-try@2.2.0: 740 | resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} 741 | engines: {node: '>=6'} 742 | 743 | package-manager-detector@0.2.11: 744 | resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} 745 | 746 | path-exists@4.0.0: 747 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 748 | engines: {node: '>=8'} 749 | 750 | path-key@3.1.1: 751 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 752 | engines: {node: '>=8'} 753 | 754 | path-type@4.0.0: 755 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 756 | engines: {node: '>=8'} 757 | 758 | pathe@2.0.3: 759 | resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 760 | 761 | pathval@2.0.1: 762 | resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} 763 | engines: {node: '>= 14.16'} 764 | 765 | picocolors@1.1.1: 766 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 767 | 768 | picomatch@2.3.1: 769 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 770 | engines: {node: '>=8.6'} 771 | 772 | picomatch@4.0.3: 773 | resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} 774 | engines: {node: '>=12'} 775 | 776 | pify@4.0.1: 777 | resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} 778 | engines: {node: '>=6'} 779 | 780 | postcss@8.5.6: 781 | resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} 782 | engines: {node: ^10 || ^12 || >=14} 783 | 784 | prettier@2.8.8: 785 | resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} 786 | engines: {node: '>=10.13.0'} 787 | hasBin: true 788 | 789 | quansync@0.2.11: 790 | resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} 791 | 792 | queue-microtask@1.2.3: 793 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 794 | 795 | read-yaml-file@1.1.0: 796 | resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} 797 | engines: {node: '>=6'} 798 | 799 | resolve-from@5.0.0: 800 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 801 | engines: {node: '>=8'} 802 | 803 | reusify@1.1.0: 804 | resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} 805 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 806 | 807 | rollup@4.50.0: 808 | resolution: {integrity: sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==} 809 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 810 | hasBin: true 811 | 812 | run-parallel@1.2.0: 813 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 814 | 815 | safer-buffer@2.1.2: 816 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 817 | 818 | semver@7.7.2: 819 | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} 820 | engines: {node: '>=10'} 821 | hasBin: true 822 | 823 | shebang-command@2.0.0: 824 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 825 | engines: {node: '>=8'} 826 | 827 | shebang-regex@3.0.0: 828 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 829 | engines: {node: '>=8'} 830 | 831 | siginfo@2.0.0: 832 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 833 | 834 | signal-exit@4.1.0: 835 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 836 | engines: {node: '>=14'} 837 | 838 | slash@3.0.0: 839 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 840 | engines: {node: '>=8'} 841 | 842 | source-map-js@1.2.1: 843 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 844 | engines: {node: '>=0.10.0'} 845 | 846 | spawndamnit@3.0.1: 847 | resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} 848 | 849 | sprintf-js@1.0.3: 850 | resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 851 | 852 | stackback@0.0.2: 853 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 854 | 855 | std-env@3.9.0: 856 | resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} 857 | 858 | strip-ansi@6.0.1: 859 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 860 | engines: {node: '>=8'} 861 | 862 | strip-bom@3.0.0: 863 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 864 | engines: {node: '>=4'} 865 | 866 | strip-literal@3.0.0: 867 | resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} 868 | 869 | term-size@2.2.1: 870 | resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} 871 | engines: {node: '>=8'} 872 | 873 | tinybench@2.9.0: 874 | resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} 875 | 876 | tinyexec@0.3.2: 877 | resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} 878 | 879 | tinyglobby@0.2.14: 880 | resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} 881 | engines: {node: '>=12.0.0'} 882 | 883 | tinypool@1.1.1: 884 | resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} 885 | engines: {node: ^18.0.0 || >=20.0.0} 886 | 887 | tinyrainbow@2.0.0: 888 | resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} 889 | engines: {node: '>=14.0.0'} 890 | 891 | tinyspy@4.0.3: 892 | resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} 893 | engines: {node: '>=14.0.0'} 894 | 895 | to-regex-range@5.0.1: 896 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 897 | engines: {node: '>=8.0'} 898 | 899 | typescript@5.9.2: 900 | resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} 901 | engines: {node: '>=14.17'} 902 | hasBin: true 903 | 904 | undici-types@7.10.0: 905 | resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} 906 | 907 | universalify@0.1.2: 908 | resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 909 | engines: {node: '>= 4.0.0'} 910 | 911 | vite-node@3.2.4: 912 | resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} 913 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 914 | hasBin: true 915 | 916 | vite@7.1.4: 917 | resolution: {integrity: sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw==} 918 | engines: {node: ^20.19.0 || >=22.12.0} 919 | hasBin: true 920 | peerDependencies: 921 | '@types/node': ^20.19.0 || >=22.12.0 922 | jiti: '>=1.21.0' 923 | less: ^4.0.0 924 | lightningcss: ^1.21.0 925 | sass: ^1.70.0 926 | sass-embedded: ^1.70.0 927 | stylus: '>=0.54.8' 928 | sugarss: ^5.0.0 929 | terser: ^5.16.0 930 | tsx: ^4.8.1 931 | yaml: ^2.4.2 932 | peerDependenciesMeta: 933 | '@types/node': 934 | optional: true 935 | jiti: 936 | optional: true 937 | less: 938 | optional: true 939 | lightningcss: 940 | optional: true 941 | sass: 942 | optional: true 943 | sass-embedded: 944 | optional: true 945 | stylus: 946 | optional: true 947 | sugarss: 948 | optional: true 949 | terser: 950 | optional: true 951 | tsx: 952 | optional: true 953 | yaml: 954 | optional: true 955 | 956 | vitest@3.2.4: 957 | resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} 958 | engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 959 | hasBin: true 960 | peerDependencies: 961 | '@edge-runtime/vm': '*' 962 | '@types/debug': ^4.1.12 963 | '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 964 | '@vitest/browser': 3.2.4 965 | '@vitest/ui': 3.2.4 966 | happy-dom: '*' 967 | jsdom: '*' 968 | peerDependenciesMeta: 969 | '@edge-runtime/vm': 970 | optional: true 971 | '@types/debug': 972 | optional: true 973 | '@types/node': 974 | optional: true 975 | '@vitest/browser': 976 | optional: true 977 | '@vitest/ui': 978 | optional: true 979 | happy-dom: 980 | optional: true 981 | jsdom: 982 | optional: true 983 | 984 | which@2.0.2: 985 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 986 | engines: {node: '>= 8'} 987 | hasBin: true 988 | 989 | why-is-node-running@2.3.0: 990 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 991 | engines: {node: '>=8'} 992 | hasBin: true 993 | 994 | zod@4.1.5: 995 | resolution: {integrity: sha512-rcUUZqlLJgBC33IT3PNMgsCq6TzLQEG/Ei/KTCU0PedSWRMAXoOUN+4t/0H+Q8bdnLPdqUYnvboJT0bn/229qg==} 996 | 997 | snapshots: 998 | 999 | '@ai-sdk/anthropic@2.0.9(zod@4.1.5)': 1000 | dependencies: 1001 | '@ai-sdk/provider': 2.0.0 1002 | '@ai-sdk/provider-utils': 3.0.7(zod@4.1.5) 1003 | zod: 4.1.5 1004 | 1005 | '@ai-sdk/gateway@1.0.15(zod@4.1.5)': 1006 | dependencies: 1007 | '@ai-sdk/provider': 2.0.0 1008 | '@ai-sdk/provider-utils': 3.0.7(zod@4.1.5) 1009 | zod: 4.1.5 1010 | 1011 | '@ai-sdk/groq@2.0.16(zod@4.1.5)': 1012 | dependencies: 1013 | '@ai-sdk/provider': 2.0.0 1014 | '@ai-sdk/provider-utils': 3.0.7(zod@4.1.5) 1015 | zod: 4.1.5 1016 | 1017 | '@ai-sdk/openai@2.0.23(zod@4.1.5)': 1018 | dependencies: 1019 | '@ai-sdk/provider': 2.0.0 1020 | '@ai-sdk/provider-utils': 3.0.7(zod@4.1.5) 1021 | zod: 4.1.5 1022 | 1023 | '@ai-sdk/provider-utils@3.0.7(zod@4.1.5)': 1024 | dependencies: 1025 | '@ai-sdk/provider': 2.0.0 1026 | '@standard-schema/spec': 1.0.0 1027 | eventsource-parser: 3.0.6 1028 | zod: 4.1.5 1029 | 1030 | '@ai-sdk/provider@2.0.0': 1031 | dependencies: 1032 | json-schema: 0.4.0 1033 | 1034 | '@babel/runtime@7.28.3': {} 1035 | 1036 | '@changesets/apply-release-plan@7.0.12': 1037 | dependencies: 1038 | '@changesets/config': 3.1.1 1039 | '@changesets/get-version-range-type': 0.4.0 1040 | '@changesets/git': 3.0.4 1041 | '@changesets/should-skip-package': 0.1.2 1042 | '@changesets/types': 6.1.0 1043 | '@manypkg/get-packages': 1.1.3 1044 | detect-indent: 6.1.0 1045 | fs-extra: 7.0.1 1046 | lodash.startcase: 4.4.0 1047 | outdent: 0.5.0 1048 | prettier: 2.8.8 1049 | resolve-from: 5.0.0 1050 | semver: 7.7.2 1051 | 1052 | '@changesets/assemble-release-plan@6.0.9': 1053 | dependencies: 1054 | '@changesets/errors': 0.2.0 1055 | '@changesets/get-dependents-graph': 2.1.3 1056 | '@changesets/should-skip-package': 0.1.2 1057 | '@changesets/types': 6.1.0 1058 | '@manypkg/get-packages': 1.1.3 1059 | semver: 7.7.2 1060 | 1061 | '@changesets/changelog-git@0.2.1': 1062 | dependencies: 1063 | '@changesets/types': 6.1.0 1064 | 1065 | '@changesets/cli@2.29.6(@types/node@24.3.0)': 1066 | dependencies: 1067 | '@changesets/apply-release-plan': 7.0.12 1068 | '@changesets/assemble-release-plan': 6.0.9 1069 | '@changesets/changelog-git': 0.2.1 1070 | '@changesets/config': 3.1.1 1071 | '@changesets/errors': 0.2.0 1072 | '@changesets/get-dependents-graph': 2.1.3 1073 | '@changesets/get-release-plan': 4.0.13 1074 | '@changesets/git': 3.0.4 1075 | '@changesets/logger': 0.1.1 1076 | '@changesets/pre': 2.0.2 1077 | '@changesets/read': 0.6.5 1078 | '@changesets/should-skip-package': 0.1.2 1079 | '@changesets/types': 6.1.0 1080 | '@changesets/write': 0.4.0 1081 | '@inquirer/external-editor': 1.0.1(@types/node@24.3.0) 1082 | '@manypkg/get-packages': 1.1.3 1083 | ansi-colors: 4.1.3 1084 | ci-info: 3.9.0 1085 | enquirer: 2.4.1 1086 | fs-extra: 7.0.1 1087 | mri: 1.2.0 1088 | p-limit: 2.3.0 1089 | package-manager-detector: 0.2.11 1090 | picocolors: 1.1.1 1091 | resolve-from: 5.0.0 1092 | semver: 7.7.2 1093 | spawndamnit: 3.0.1 1094 | term-size: 2.2.1 1095 | transitivePeerDependencies: 1096 | - '@types/node' 1097 | 1098 | '@changesets/config@3.1.1': 1099 | dependencies: 1100 | '@changesets/errors': 0.2.0 1101 | '@changesets/get-dependents-graph': 2.1.3 1102 | '@changesets/logger': 0.1.1 1103 | '@changesets/types': 6.1.0 1104 | '@manypkg/get-packages': 1.1.3 1105 | fs-extra: 7.0.1 1106 | micromatch: 4.0.8 1107 | 1108 | '@changesets/errors@0.2.0': 1109 | dependencies: 1110 | extendable-error: 0.1.7 1111 | 1112 | '@changesets/get-dependents-graph@2.1.3': 1113 | dependencies: 1114 | '@changesets/types': 6.1.0 1115 | '@manypkg/get-packages': 1.1.3 1116 | picocolors: 1.1.1 1117 | semver: 7.7.2 1118 | 1119 | '@changesets/get-release-plan@4.0.13': 1120 | dependencies: 1121 | '@changesets/assemble-release-plan': 6.0.9 1122 | '@changesets/config': 3.1.1 1123 | '@changesets/pre': 2.0.2 1124 | '@changesets/read': 0.6.5 1125 | '@changesets/types': 6.1.0 1126 | '@manypkg/get-packages': 1.1.3 1127 | 1128 | '@changesets/get-version-range-type@0.4.0': {} 1129 | 1130 | '@changesets/git@3.0.4': 1131 | dependencies: 1132 | '@changesets/errors': 0.2.0 1133 | '@manypkg/get-packages': 1.1.3 1134 | is-subdir: 1.2.0 1135 | micromatch: 4.0.8 1136 | spawndamnit: 3.0.1 1137 | 1138 | '@changesets/logger@0.1.1': 1139 | dependencies: 1140 | picocolors: 1.1.1 1141 | 1142 | '@changesets/parse@0.4.1': 1143 | dependencies: 1144 | '@changesets/types': 6.1.0 1145 | js-yaml: 3.14.1 1146 | 1147 | '@changesets/pre@2.0.2': 1148 | dependencies: 1149 | '@changesets/errors': 0.2.0 1150 | '@changesets/types': 6.1.0 1151 | '@manypkg/get-packages': 1.1.3 1152 | fs-extra: 7.0.1 1153 | 1154 | '@changesets/read@0.6.5': 1155 | dependencies: 1156 | '@changesets/git': 3.0.4 1157 | '@changesets/logger': 0.1.1 1158 | '@changesets/parse': 0.4.1 1159 | '@changesets/types': 6.1.0 1160 | fs-extra: 7.0.1 1161 | p-filter: 2.1.0 1162 | picocolors: 1.1.1 1163 | 1164 | '@changesets/should-skip-package@0.1.2': 1165 | dependencies: 1166 | '@changesets/types': 6.1.0 1167 | '@manypkg/get-packages': 1.1.3 1168 | 1169 | '@changesets/types@4.1.0': {} 1170 | 1171 | '@changesets/types@6.1.0': {} 1172 | 1173 | '@changesets/write@0.4.0': 1174 | dependencies: 1175 | '@changesets/types': 6.1.0 1176 | fs-extra: 7.0.1 1177 | human-id: 4.1.1 1178 | prettier: 2.8.8 1179 | 1180 | '@esbuild/aix-ppc64@0.25.9': 1181 | optional: true 1182 | 1183 | '@esbuild/android-arm64@0.25.9': 1184 | optional: true 1185 | 1186 | '@esbuild/android-arm@0.25.9': 1187 | optional: true 1188 | 1189 | '@esbuild/android-x64@0.25.9': 1190 | optional: true 1191 | 1192 | '@esbuild/darwin-arm64@0.25.9': 1193 | optional: true 1194 | 1195 | '@esbuild/darwin-x64@0.25.9': 1196 | optional: true 1197 | 1198 | '@esbuild/freebsd-arm64@0.25.9': 1199 | optional: true 1200 | 1201 | '@esbuild/freebsd-x64@0.25.9': 1202 | optional: true 1203 | 1204 | '@esbuild/linux-arm64@0.25.9': 1205 | optional: true 1206 | 1207 | '@esbuild/linux-arm@0.25.9': 1208 | optional: true 1209 | 1210 | '@esbuild/linux-ia32@0.25.9': 1211 | optional: true 1212 | 1213 | '@esbuild/linux-loong64@0.25.9': 1214 | optional: true 1215 | 1216 | '@esbuild/linux-mips64el@0.25.9': 1217 | optional: true 1218 | 1219 | '@esbuild/linux-ppc64@0.25.9': 1220 | optional: true 1221 | 1222 | '@esbuild/linux-riscv64@0.25.9': 1223 | optional: true 1224 | 1225 | '@esbuild/linux-s390x@0.25.9': 1226 | optional: true 1227 | 1228 | '@esbuild/linux-x64@0.25.9': 1229 | optional: true 1230 | 1231 | '@esbuild/netbsd-arm64@0.25.9': 1232 | optional: true 1233 | 1234 | '@esbuild/netbsd-x64@0.25.9': 1235 | optional: true 1236 | 1237 | '@esbuild/openbsd-arm64@0.25.9': 1238 | optional: true 1239 | 1240 | '@esbuild/openbsd-x64@0.25.9': 1241 | optional: true 1242 | 1243 | '@esbuild/openharmony-arm64@0.25.9': 1244 | optional: true 1245 | 1246 | '@esbuild/sunos-x64@0.25.9': 1247 | optional: true 1248 | 1249 | '@esbuild/win32-arm64@0.25.9': 1250 | optional: true 1251 | 1252 | '@esbuild/win32-ia32@0.25.9': 1253 | optional: true 1254 | 1255 | '@esbuild/win32-x64@0.25.9': 1256 | optional: true 1257 | 1258 | '@inquirer/external-editor@1.0.1(@types/node@24.3.0)': 1259 | dependencies: 1260 | chardet: 2.1.0 1261 | iconv-lite: 0.6.3 1262 | optionalDependencies: 1263 | '@types/node': 24.3.0 1264 | 1265 | '@jridgewell/sourcemap-codec@1.5.5': {} 1266 | 1267 | '@manypkg/find-root@1.1.0': 1268 | dependencies: 1269 | '@babel/runtime': 7.28.3 1270 | '@types/node': 12.20.55 1271 | find-up: 4.1.0 1272 | fs-extra: 8.1.0 1273 | 1274 | '@manypkg/get-packages@1.1.3': 1275 | dependencies: 1276 | '@babel/runtime': 7.28.3 1277 | '@changesets/types': 4.1.0 1278 | '@manypkg/find-root': 1.1.0 1279 | fs-extra: 8.1.0 1280 | globby: 11.1.0 1281 | read-yaml-file: 1.1.0 1282 | 1283 | '@nodelib/fs.scandir@2.1.5': 1284 | dependencies: 1285 | '@nodelib/fs.stat': 2.0.5 1286 | run-parallel: 1.2.0 1287 | 1288 | '@nodelib/fs.stat@2.0.5': {} 1289 | 1290 | '@nodelib/fs.walk@1.2.8': 1291 | dependencies: 1292 | '@nodelib/fs.scandir': 2.1.5 1293 | fastq: 1.19.1 1294 | 1295 | '@opentelemetry/api@1.9.0': {} 1296 | 1297 | '@rollup/rollup-android-arm-eabi@4.50.0': 1298 | optional: true 1299 | 1300 | '@rollup/rollup-android-arm64@4.50.0': 1301 | optional: true 1302 | 1303 | '@rollup/rollup-darwin-arm64@4.50.0': 1304 | optional: true 1305 | 1306 | '@rollup/rollup-darwin-x64@4.50.0': 1307 | optional: true 1308 | 1309 | '@rollup/rollup-freebsd-arm64@4.50.0': 1310 | optional: true 1311 | 1312 | '@rollup/rollup-freebsd-x64@4.50.0': 1313 | optional: true 1314 | 1315 | '@rollup/rollup-linux-arm-gnueabihf@4.50.0': 1316 | optional: true 1317 | 1318 | '@rollup/rollup-linux-arm-musleabihf@4.50.0': 1319 | optional: true 1320 | 1321 | '@rollup/rollup-linux-arm64-gnu@4.50.0': 1322 | optional: true 1323 | 1324 | '@rollup/rollup-linux-arm64-musl@4.50.0': 1325 | optional: true 1326 | 1327 | '@rollup/rollup-linux-loongarch64-gnu@4.50.0': 1328 | optional: true 1329 | 1330 | '@rollup/rollup-linux-ppc64-gnu@4.50.0': 1331 | optional: true 1332 | 1333 | '@rollup/rollup-linux-riscv64-gnu@4.50.0': 1334 | optional: true 1335 | 1336 | '@rollup/rollup-linux-riscv64-musl@4.50.0': 1337 | optional: true 1338 | 1339 | '@rollup/rollup-linux-s390x-gnu@4.50.0': 1340 | optional: true 1341 | 1342 | '@rollup/rollup-linux-x64-gnu@4.50.0': 1343 | optional: true 1344 | 1345 | '@rollup/rollup-linux-x64-musl@4.50.0': 1346 | optional: true 1347 | 1348 | '@rollup/rollup-openharmony-arm64@4.50.0': 1349 | optional: true 1350 | 1351 | '@rollup/rollup-win32-arm64-msvc@4.50.0': 1352 | optional: true 1353 | 1354 | '@rollup/rollup-win32-ia32-msvc@4.50.0': 1355 | optional: true 1356 | 1357 | '@rollup/rollup-win32-x64-msvc@4.50.0': 1358 | optional: true 1359 | 1360 | '@standard-schema/spec@1.0.0': {} 1361 | 1362 | '@types/chai@5.2.2': 1363 | dependencies: 1364 | '@types/deep-eql': 4.0.2 1365 | 1366 | '@types/deep-eql@4.0.2': {} 1367 | 1368 | '@types/estree@1.0.8': {} 1369 | 1370 | '@types/node@12.20.55': {} 1371 | 1372 | '@types/node@24.3.0': 1373 | dependencies: 1374 | undici-types: 7.10.0 1375 | 1376 | '@vitest/expect@3.2.4': 1377 | dependencies: 1378 | '@types/chai': 5.2.2 1379 | '@vitest/spy': 3.2.4 1380 | '@vitest/utils': 3.2.4 1381 | chai: 5.3.3 1382 | tinyrainbow: 2.0.0 1383 | 1384 | '@vitest/mocker@3.2.4(vite@7.1.4(@types/node@24.3.0))': 1385 | dependencies: 1386 | '@vitest/spy': 3.2.4 1387 | estree-walker: 3.0.3 1388 | magic-string: 0.30.18 1389 | optionalDependencies: 1390 | vite: 7.1.4(@types/node@24.3.0) 1391 | 1392 | '@vitest/pretty-format@3.2.4': 1393 | dependencies: 1394 | tinyrainbow: 2.0.0 1395 | 1396 | '@vitest/runner@3.2.4': 1397 | dependencies: 1398 | '@vitest/utils': 3.2.4 1399 | pathe: 2.0.3 1400 | strip-literal: 3.0.0 1401 | 1402 | '@vitest/snapshot@3.2.4': 1403 | dependencies: 1404 | '@vitest/pretty-format': 3.2.4 1405 | magic-string: 0.30.18 1406 | pathe: 2.0.3 1407 | 1408 | '@vitest/spy@3.2.4': 1409 | dependencies: 1410 | tinyspy: 4.0.3 1411 | 1412 | '@vitest/utils@3.2.4': 1413 | dependencies: 1414 | '@vitest/pretty-format': 3.2.4 1415 | loupe: 3.2.1 1416 | tinyrainbow: 2.0.0 1417 | 1418 | ai@5.0.30(zod@4.1.5): 1419 | dependencies: 1420 | '@ai-sdk/gateway': 1.0.15(zod@4.1.5) 1421 | '@ai-sdk/provider': 2.0.0 1422 | '@ai-sdk/provider-utils': 3.0.7(zod@4.1.5) 1423 | '@opentelemetry/api': 1.9.0 1424 | zod: 4.1.5 1425 | 1426 | ansi-colors@4.1.3: {} 1427 | 1428 | ansi-regex@5.0.1: {} 1429 | 1430 | argparse@1.0.10: 1431 | dependencies: 1432 | sprintf-js: 1.0.3 1433 | 1434 | array-union@2.1.0: {} 1435 | 1436 | assertion-error@2.0.1: {} 1437 | 1438 | better-path-resolve@1.0.0: 1439 | dependencies: 1440 | is-windows: 1.0.2 1441 | 1442 | braces@3.0.3: 1443 | dependencies: 1444 | fill-range: 7.1.1 1445 | 1446 | cac@6.7.14: {} 1447 | 1448 | chai@5.3.3: 1449 | dependencies: 1450 | assertion-error: 2.0.1 1451 | check-error: 2.1.1 1452 | deep-eql: 5.0.2 1453 | loupe: 3.2.1 1454 | pathval: 2.0.1 1455 | 1456 | chardet@2.1.0: {} 1457 | 1458 | check-error@2.1.1: {} 1459 | 1460 | ci-info@3.9.0: {} 1461 | 1462 | cross-spawn@7.0.6: 1463 | dependencies: 1464 | path-key: 3.1.1 1465 | shebang-command: 2.0.0 1466 | which: 2.0.2 1467 | 1468 | debug@4.4.1: 1469 | dependencies: 1470 | ms: 2.1.3 1471 | 1472 | deep-eql@5.0.2: {} 1473 | 1474 | detect-indent@6.1.0: {} 1475 | 1476 | dir-glob@3.0.1: 1477 | dependencies: 1478 | path-type: 4.0.0 1479 | 1480 | enquirer@2.4.1: 1481 | dependencies: 1482 | ansi-colors: 4.1.3 1483 | strip-ansi: 6.0.1 1484 | 1485 | es-module-lexer@1.7.0: {} 1486 | 1487 | esbuild@0.25.9: 1488 | optionalDependencies: 1489 | '@esbuild/aix-ppc64': 0.25.9 1490 | '@esbuild/android-arm': 0.25.9 1491 | '@esbuild/android-arm64': 0.25.9 1492 | '@esbuild/android-x64': 0.25.9 1493 | '@esbuild/darwin-arm64': 0.25.9 1494 | '@esbuild/darwin-x64': 0.25.9 1495 | '@esbuild/freebsd-arm64': 0.25.9 1496 | '@esbuild/freebsd-x64': 0.25.9 1497 | '@esbuild/linux-arm': 0.25.9 1498 | '@esbuild/linux-arm64': 0.25.9 1499 | '@esbuild/linux-ia32': 0.25.9 1500 | '@esbuild/linux-loong64': 0.25.9 1501 | '@esbuild/linux-mips64el': 0.25.9 1502 | '@esbuild/linux-ppc64': 0.25.9 1503 | '@esbuild/linux-riscv64': 0.25.9 1504 | '@esbuild/linux-s390x': 0.25.9 1505 | '@esbuild/linux-x64': 0.25.9 1506 | '@esbuild/netbsd-arm64': 0.25.9 1507 | '@esbuild/netbsd-x64': 0.25.9 1508 | '@esbuild/openbsd-arm64': 0.25.9 1509 | '@esbuild/openbsd-x64': 0.25.9 1510 | '@esbuild/openharmony-arm64': 0.25.9 1511 | '@esbuild/sunos-x64': 0.25.9 1512 | '@esbuild/win32-arm64': 0.25.9 1513 | '@esbuild/win32-ia32': 0.25.9 1514 | '@esbuild/win32-x64': 0.25.9 1515 | 1516 | esprima@4.0.1: {} 1517 | 1518 | estree-walker@3.0.3: 1519 | dependencies: 1520 | '@types/estree': 1.0.8 1521 | 1522 | eventsource-parser@3.0.6: {} 1523 | 1524 | expect-type@1.2.2: {} 1525 | 1526 | extendable-error@0.1.7: {} 1527 | 1528 | fast-glob@3.3.3: 1529 | dependencies: 1530 | '@nodelib/fs.stat': 2.0.5 1531 | '@nodelib/fs.walk': 1.2.8 1532 | glob-parent: 5.1.2 1533 | merge2: 1.4.1 1534 | micromatch: 4.0.8 1535 | 1536 | fastq@1.19.1: 1537 | dependencies: 1538 | reusify: 1.1.0 1539 | 1540 | fdir@6.5.0(picomatch@4.0.3): 1541 | optionalDependencies: 1542 | picomatch: 4.0.3 1543 | 1544 | fill-range@7.1.1: 1545 | dependencies: 1546 | to-regex-range: 5.0.1 1547 | 1548 | find-up@4.1.0: 1549 | dependencies: 1550 | locate-path: 5.0.0 1551 | path-exists: 4.0.0 1552 | 1553 | fs-extra@7.0.1: 1554 | dependencies: 1555 | graceful-fs: 4.2.11 1556 | jsonfile: 4.0.0 1557 | universalify: 0.1.2 1558 | 1559 | fs-extra@8.1.0: 1560 | dependencies: 1561 | graceful-fs: 4.2.11 1562 | jsonfile: 4.0.0 1563 | universalify: 0.1.2 1564 | 1565 | fsevents@2.3.3: 1566 | optional: true 1567 | 1568 | glob-parent@5.1.2: 1569 | dependencies: 1570 | is-glob: 4.0.3 1571 | 1572 | globby@11.1.0: 1573 | dependencies: 1574 | array-union: 2.1.0 1575 | dir-glob: 3.0.1 1576 | fast-glob: 3.3.3 1577 | ignore: 5.3.2 1578 | merge2: 1.4.1 1579 | slash: 3.0.0 1580 | 1581 | graceful-fs@4.2.11: {} 1582 | 1583 | human-id@4.1.1: {} 1584 | 1585 | iconv-lite@0.6.3: 1586 | dependencies: 1587 | safer-buffer: 2.1.2 1588 | 1589 | ignore@5.3.2: {} 1590 | 1591 | is-extglob@2.1.1: {} 1592 | 1593 | is-glob@4.0.3: 1594 | dependencies: 1595 | is-extglob: 2.1.1 1596 | 1597 | is-number@7.0.0: {} 1598 | 1599 | is-subdir@1.2.0: 1600 | dependencies: 1601 | better-path-resolve: 1.0.0 1602 | 1603 | is-windows@1.0.2: {} 1604 | 1605 | isexe@2.0.0: {} 1606 | 1607 | js-tokens@9.0.1: {} 1608 | 1609 | js-yaml@3.14.1: 1610 | dependencies: 1611 | argparse: 1.0.10 1612 | esprima: 4.0.1 1613 | 1614 | json-schema@0.4.0: {} 1615 | 1616 | jsonfile@4.0.0: 1617 | optionalDependencies: 1618 | graceful-fs: 4.2.11 1619 | 1620 | locate-path@5.0.0: 1621 | dependencies: 1622 | p-locate: 4.1.0 1623 | 1624 | lodash.startcase@4.4.0: {} 1625 | 1626 | loupe@3.2.1: {} 1627 | 1628 | magic-string@0.30.18: 1629 | dependencies: 1630 | '@jridgewell/sourcemap-codec': 1.5.5 1631 | 1632 | merge2@1.4.1: {} 1633 | 1634 | micromatch@4.0.8: 1635 | dependencies: 1636 | braces: 3.0.3 1637 | picomatch: 2.3.1 1638 | 1639 | mri@1.2.0: {} 1640 | 1641 | ms@2.1.3: {} 1642 | 1643 | nanoid@3.3.11: {} 1644 | 1645 | outdent@0.5.0: {} 1646 | 1647 | p-filter@2.1.0: 1648 | dependencies: 1649 | p-map: 2.1.0 1650 | 1651 | p-limit@2.3.0: 1652 | dependencies: 1653 | p-try: 2.2.0 1654 | 1655 | p-locate@4.1.0: 1656 | dependencies: 1657 | p-limit: 2.3.0 1658 | 1659 | p-map@2.1.0: {} 1660 | 1661 | p-try@2.2.0: {} 1662 | 1663 | package-manager-detector@0.2.11: 1664 | dependencies: 1665 | quansync: 0.2.11 1666 | 1667 | path-exists@4.0.0: {} 1668 | 1669 | path-key@3.1.1: {} 1670 | 1671 | path-type@4.0.0: {} 1672 | 1673 | pathe@2.0.3: {} 1674 | 1675 | pathval@2.0.1: {} 1676 | 1677 | picocolors@1.1.1: {} 1678 | 1679 | picomatch@2.3.1: {} 1680 | 1681 | picomatch@4.0.3: {} 1682 | 1683 | pify@4.0.1: {} 1684 | 1685 | postcss@8.5.6: 1686 | dependencies: 1687 | nanoid: 3.3.11 1688 | picocolors: 1.1.1 1689 | source-map-js: 1.2.1 1690 | 1691 | prettier@2.8.8: {} 1692 | 1693 | quansync@0.2.11: {} 1694 | 1695 | queue-microtask@1.2.3: {} 1696 | 1697 | read-yaml-file@1.1.0: 1698 | dependencies: 1699 | graceful-fs: 4.2.11 1700 | js-yaml: 3.14.1 1701 | pify: 4.0.1 1702 | strip-bom: 3.0.0 1703 | 1704 | resolve-from@5.0.0: {} 1705 | 1706 | reusify@1.1.0: {} 1707 | 1708 | rollup@4.50.0: 1709 | dependencies: 1710 | '@types/estree': 1.0.8 1711 | optionalDependencies: 1712 | '@rollup/rollup-android-arm-eabi': 4.50.0 1713 | '@rollup/rollup-android-arm64': 4.50.0 1714 | '@rollup/rollup-darwin-arm64': 4.50.0 1715 | '@rollup/rollup-darwin-x64': 4.50.0 1716 | '@rollup/rollup-freebsd-arm64': 4.50.0 1717 | '@rollup/rollup-freebsd-x64': 4.50.0 1718 | '@rollup/rollup-linux-arm-gnueabihf': 4.50.0 1719 | '@rollup/rollup-linux-arm-musleabihf': 4.50.0 1720 | '@rollup/rollup-linux-arm64-gnu': 4.50.0 1721 | '@rollup/rollup-linux-arm64-musl': 4.50.0 1722 | '@rollup/rollup-linux-loongarch64-gnu': 4.50.0 1723 | '@rollup/rollup-linux-ppc64-gnu': 4.50.0 1724 | '@rollup/rollup-linux-riscv64-gnu': 4.50.0 1725 | '@rollup/rollup-linux-riscv64-musl': 4.50.0 1726 | '@rollup/rollup-linux-s390x-gnu': 4.50.0 1727 | '@rollup/rollup-linux-x64-gnu': 4.50.0 1728 | '@rollup/rollup-linux-x64-musl': 4.50.0 1729 | '@rollup/rollup-openharmony-arm64': 4.50.0 1730 | '@rollup/rollup-win32-arm64-msvc': 4.50.0 1731 | '@rollup/rollup-win32-ia32-msvc': 4.50.0 1732 | '@rollup/rollup-win32-x64-msvc': 4.50.0 1733 | fsevents: 2.3.3 1734 | 1735 | run-parallel@1.2.0: 1736 | dependencies: 1737 | queue-microtask: 1.2.3 1738 | 1739 | safer-buffer@2.1.2: {} 1740 | 1741 | semver@7.7.2: {} 1742 | 1743 | shebang-command@2.0.0: 1744 | dependencies: 1745 | shebang-regex: 3.0.0 1746 | 1747 | shebang-regex@3.0.0: {} 1748 | 1749 | siginfo@2.0.0: {} 1750 | 1751 | signal-exit@4.1.0: {} 1752 | 1753 | slash@3.0.0: {} 1754 | 1755 | source-map-js@1.2.1: {} 1756 | 1757 | spawndamnit@3.0.1: 1758 | dependencies: 1759 | cross-spawn: 7.0.6 1760 | signal-exit: 4.1.0 1761 | 1762 | sprintf-js@1.0.3: {} 1763 | 1764 | stackback@0.0.2: {} 1765 | 1766 | std-env@3.9.0: {} 1767 | 1768 | strip-ansi@6.0.1: 1769 | dependencies: 1770 | ansi-regex: 5.0.1 1771 | 1772 | strip-bom@3.0.0: {} 1773 | 1774 | strip-literal@3.0.0: 1775 | dependencies: 1776 | js-tokens: 9.0.1 1777 | 1778 | term-size@2.2.1: {} 1779 | 1780 | tinybench@2.9.0: {} 1781 | 1782 | tinyexec@0.3.2: {} 1783 | 1784 | tinyglobby@0.2.14: 1785 | dependencies: 1786 | fdir: 6.5.0(picomatch@4.0.3) 1787 | picomatch: 4.0.3 1788 | 1789 | tinypool@1.1.1: {} 1790 | 1791 | tinyrainbow@2.0.0: {} 1792 | 1793 | tinyspy@4.0.3: {} 1794 | 1795 | to-regex-range@5.0.1: 1796 | dependencies: 1797 | is-number: 7.0.0 1798 | 1799 | typescript@5.9.2: {} 1800 | 1801 | undici-types@7.10.0: {} 1802 | 1803 | universalify@0.1.2: {} 1804 | 1805 | vite-node@3.2.4(@types/node@24.3.0): 1806 | dependencies: 1807 | cac: 6.7.14 1808 | debug: 4.4.1 1809 | es-module-lexer: 1.7.0 1810 | pathe: 2.0.3 1811 | vite: 7.1.4(@types/node@24.3.0) 1812 | transitivePeerDependencies: 1813 | - '@types/node' 1814 | - jiti 1815 | - less 1816 | - lightningcss 1817 | - sass 1818 | - sass-embedded 1819 | - stylus 1820 | - sugarss 1821 | - supports-color 1822 | - terser 1823 | - tsx 1824 | - yaml 1825 | 1826 | vite@7.1.4(@types/node@24.3.0): 1827 | dependencies: 1828 | esbuild: 0.25.9 1829 | fdir: 6.5.0(picomatch@4.0.3) 1830 | picomatch: 4.0.3 1831 | postcss: 8.5.6 1832 | rollup: 4.50.0 1833 | tinyglobby: 0.2.14 1834 | optionalDependencies: 1835 | '@types/node': 24.3.0 1836 | fsevents: 2.3.3 1837 | 1838 | vitest@3.2.4(@types/node@24.3.0): 1839 | dependencies: 1840 | '@types/chai': 5.2.2 1841 | '@vitest/expect': 3.2.4 1842 | '@vitest/mocker': 3.2.4(vite@7.1.4(@types/node@24.3.0)) 1843 | '@vitest/pretty-format': 3.2.4 1844 | '@vitest/runner': 3.2.4 1845 | '@vitest/snapshot': 3.2.4 1846 | '@vitest/spy': 3.2.4 1847 | '@vitest/utils': 3.2.4 1848 | chai: 5.3.3 1849 | debug: 4.4.1 1850 | expect-type: 1.2.2 1851 | magic-string: 0.30.18 1852 | pathe: 2.0.3 1853 | picomatch: 4.0.3 1854 | std-env: 3.9.0 1855 | tinybench: 2.9.0 1856 | tinyexec: 0.3.2 1857 | tinyglobby: 0.2.14 1858 | tinypool: 1.1.1 1859 | tinyrainbow: 2.0.0 1860 | vite: 7.1.4(@types/node@24.3.0) 1861 | vite-node: 3.2.4(@types/node@24.3.0) 1862 | why-is-node-running: 2.3.0 1863 | optionalDependencies: 1864 | '@types/node': 24.3.0 1865 | transitivePeerDependencies: 1866 | - jiti 1867 | - less 1868 | - lightningcss 1869 | - msw 1870 | - sass 1871 | - sass-embedded 1872 | - stylus 1873 | - sugarss 1874 | - supports-color 1875 | - terser 1876 | - tsx 1877 | - yaml 1878 | 1879 | which@2.0.2: 1880 | dependencies: 1881 | isexe: 2.0.0 1882 | 1883 | why-is-node-running@2.3.0: 1884 | dependencies: 1885 | siginfo: 2.0.0 1886 | stackback: 0.0.2 1887 | 1888 | zod@4.1.5: {} 1889 | --------------------------------------------------------------------------------