vibezcheck 0.4.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +249 -273
  3. package/bin/vibezcheck.js +4 -4
  4. package/dist/ai-sdk/index.d.mts +28 -59
  5. package/dist/ai-sdk/index.d.ts +28 -59
  6. package/dist/ai-sdk/index.js +307 -69
  7. package/dist/ai-sdk/index.js.map +1 -1
  8. package/dist/ai-sdk/index.mjs +307 -69
  9. package/dist/ai-sdk/index.mjs.map +1 -1
  10. package/dist/ai-sdk/middleware.d.mts +15 -0
  11. package/dist/ai-sdk/middleware.d.ts +15 -0
  12. package/dist/ai-sdk/middleware.js +1433 -0
  13. package/dist/ai-sdk/middleware.js.map +1 -0
  14. package/dist/ai-sdk/middleware.mjs +1396 -0
  15. package/dist/ai-sdk/middleware.mjs.map +1 -0
  16. package/dist/auth/index.js.map +1 -1
  17. package/dist/auth/index.mjs.map +1 -1
  18. package/dist/billing/index.d.mts +90 -1
  19. package/dist/billing/index.d.ts +90 -1
  20. package/dist/billing/index.js +1542 -2
  21. package/dist/billing/index.js.map +1 -1
  22. package/dist/billing/index.mjs +1537 -1
  23. package/dist/billing/index.mjs.map +1 -1
  24. package/dist/cli/index.js +59 -7
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/index.mjs +59 -7
  27. package/dist/cli/index.mjs.map +1 -1
  28. package/dist/{client-ynfWcHX6.d.ts → client-BORmJy8s.d.ts} +1 -1
  29. package/dist/{client-w_hWhQ6g.d.mts → client-CbuXmoXz.d.mts} +1 -1
  30. package/dist/compat/stripe-meter.d.mts +21 -0
  31. package/dist/compat/stripe-meter.d.ts +21 -0
  32. package/dist/compat/stripe-meter.js +1451 -0
  33. package/dist/compat/stripe-meter.js.map +1 -0
  34. package/dist/compat/stripe-meter.mjs +1414 -0
  35. package/dist/compat/stripe-meter.mjs.map +1 -0
  36. package/dist/compat/stripe-provider.d.mts +34 -0
  37. package/dist/compat/stripe-provider.d.ts +34 -0
  38. package/dist/compat/stripe-provider.js +1620 -0
  39. package/dist/compat/stripe-provider.js.map +1 -0
  40. package/dist/compat/stripe-provider.mjs +1587 -0
  41. package/dist/compat/stripe-provider.mjs.map +1 -0
  42. package/dist/compat/token-meter.d.mts +28 -0
  43. package/dist/compat/token-meter.d.ts +28 -0
  44. package/dist/compat/token-meter.js +1320 -0
  45. package/dist/compat/token-meter.js.map +1 -0
  46. package/dist/compat/token-meter.mjs +1283 -0
  47. package/dist/compat/token-meter.mjs.map +1 -0
  48. package/dist/customers/index.d.mts +1 -1
  49. package/dist/customers/index.d.ts +1 -1
  50. package/dist/customers/index.js.map +1 -1
  51. package/dist/customers/index.mjs.map +1 -1
  52. package/dist/index.d.mts +25 -11
  53. package/dist/index.d.ts +25 -11
  54. package/dist/index.js +810 -72
  55. package/dist/index.js.map +1 -1
  56. package/dist/index.mjs +798 -72
  57. package/dist/index.mjs.map +1 -1
  58. package/dist/meter/index.d.mts +2 -2
  59. package/dist/meter/index.d.ts +2 -2
  60. package/dist/meter/index.js +176 -42
  61. package/dist/meter/index.js.map +1 -1
  62. package/dist/meter/index.mjs +176 -42
  63. package/dist/meter/index.mjs.map +1 -1
  64. package/dist/pricing/index.d.mts +15 -4
  65. package/dist/pricing/index.d.ts +15 -4
  66. package/dist/pricing/index.js +165 -29
  67. package/dist/pricing/index.js.map +1 -1
  68. package/dist/pricing/index.mjs +164 -29
  69. package/dist/pricing/index.mjs.map +1 -1
  70. package/dist/react/index.d.mts +46 -2
  71. package/dist/react/index.d.ts +46 -2
  72. package/dist/react/index.js +471 -29
  73. package/dist/react/index.js.map +1 -1
  74. package/dist/react/index.mjs +469 -29
  75. package/dist/react/index.mjs.map +1 -1
  76. package/dist/{types-Mozk4-Mr.d.mts → types-6P71CXAD.d.mts} +16 -6
  77. package/dist/{types-Mozk4-Mr.d.ts → types-6P71CXAD.d.ts} +16 -6
  78. package/dist/with-billing-Bj6Ya_Iy.d.ts +49 -0
  79. package/dist/with-billing-DndWGxL8.d.mts +49 -0
  80. package/package.json +35 -10
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/meter/client.ts","../../src/meter/batcher.ts","../../src/meter/extractors/openai.ts","../../src/meter/extractors/anthropic.ts","../../src/meter/extractors/gemini.ts","../../src/meter/extractors/generic.ts","../../src/meter/extractors/index.ts","../../src/pricing/table.ts","../../src/pricing/calculator.ts","../../src/customers/helpers.ts","../../src/meter/stream.ts","../../src/compat/token-meter.ts"],"sourcesContent":["import Stripe from 'stripe';\r\nimport type {\r\n MeterOptions,\r\n StreamWrapOptions,\r\n RecordUsageOptions,\r\n UsageEvent,\r\n UsageSummary,\r\n CustomerParam,\r\n} from '../types';\r\nimport { MeterBatcher } from './batcher';\r\nimport { detectAndExtractUsage } from './extractors';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { wrapUniversalStream } from './stream';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport class VibezMeter {\r\n private batcher: MeterBatcher;\r\n private stripeClient?: Stripe;\r\n private markupMultiplier?: number;\r\n\r\n constructor(options: MeterOptions = {}) {\r\n this.markupMultiplier = options.markupMultiplier;\r\n\r\n // Initialize Stripe client if apiKey or stripe instance is provided\r\n if (options.stripe) {\r\n this.stripeClient = options.stripe;\r\n } else if (options.apiKey || process.env.STRIPE_SECRET_KEY) {\r\n const key = options.apiKey || process.env.STRIPE_SECRET_KEY!;\r\n this.stripeClient = new Stripe(key, {\r\n appInfo: {\r\n name: 'vibezcheck',\r\n version: '0.5.3',\r\n url: 'https://vibezcheck.xyz',\r\n },\r\n });\r\n }\r\n\r\n this.batcher = new MeterBatcher({\r\n ...options,\r\n stripe: this.stripeClient,\r\n });\r\n }\r\n\r\n /**\r\n * Track token usage from a non-streaming response object (OpenAI, Anthropic, Gemini, etc.)\r\n */\r\n public trackUsage(\r\n response: any,\r\n options: {\r\n customer?: CustomerParam;\r\n customerId?: string;\r\n model?: string;\r\n provider?: string;\r\n metadata?: Record<string, string | number | boolean>;\r\n } = {}\r\n ): UsageEvent | null {\r\n const extracted = detectAndExtractUsage(response, options.model, options.provider);\r\n if (!extracted) {\r\n return null;\r\n }\r\n\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: extracted.provider,\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Wrap any LLM stream (OpenAI, Anthropic, Gemini) with zero added latency\r\n */\r\n public wrapStream<T>(stream: T, options: StreamWrapOptions = {}): T {\r\n return wrapUniversalStream(stream, options, (event) => {\r\n this.batcher.enqueue(event);\r\n });\r\n }\r\n\r\n /**\r\n * Directly record token usage manually\r\n */\r\n public recordUsage(options: RecordUsageOptions & { customer?: CustomerParam }): UsageEvent {\r\n const inputTokens = options.inputTokens ?? 0;\r\n const outputTokens = options.outputTokens ?? 0;\r\n const reasoningTokens = options.reasoningTokens;\r\n const cachedTokens = options.cachedTokens;\r\n\r\n const usage = {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens,\r\n visibleOutputTokens:\r\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\r\n cachedTokens,\r\n };\r\n\r\n const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: options.model,\r\n provider: options.provider || 'custom',\r\n usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Flush pending events to Stripe (vital for Serverless & Edge environments)\r\n */\r\n public async flush(): Promise<void> {\r\n await this.batcher.flush();\r\n }\r\n\r\n /**\r\n * Get in-memory aggregated usage statistics\r\n */\r\n public getUsageSummary(): UsageSummary {\r\n return this.batcher.getSummary();\r\n }\r\n\r\n /**\r\n * Reset in-memory ledger\r\n */\r\n public resetSummary(): void {\r\n this.batcher.resetLedger();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create a VibezMeter instance\r\n */\r\nexport function createMeter(options: MeterOptions = {}): VibezMeter {\r\n return new VibezMeter(options);\r\n}\r\n","import type Stripe from 'stripe';\r\nimport type { UsageEvent, UsageSummary, MeterOptions } from '../types';\r\n\r\nexport class MeterBatcher {\r\n private queue: UsageEvent[] = [];\r\n private timer: NodeJS.Timeout | null = null;\r\n private isFlushing: boolean = false;\r\n private readonly maxBatchSize: number;\r\n private readonly flushIntervalMs: number;\r\n private readonly stripeClient?: Stripe;\r\n private readonly eventName: string;\r\n private readonly onUsageCallback?: (event: UsageEvent) => void | Promise<void>;\r\n private readonly onErrorCallback?: (error: Error, events: UsageEvent[]) => void;\r\n private readonly debug: boolean;\r\n\r\n // In-memory ledger for local stats\r\n private totalRequests = 0;\r\n private totalTokens = 0;\r\n private totalInputTokens = 0;\r\n private totalOutputTokens = 0;\r\n private totalReasoningTokens = 0;\r\n private totalCostUSD = 0;\r\n private byModel: Record<string, { requests: number; tokens: number; costUSD: number }> = {};\r\n\r\n constructor(options: MeterOptions = {}) {\r\n this.stripeClient = options.stripe;\r\n this.eventName = options.eventName || 'token-billing-tokens';\r\n this.maxBatchSize = options.batching?.maxBatchSize ?? 50;\r\n this.flushIntervalMs = options.batching?.flushIntervalMs ?? 50;\r\n this.onUsageCallback = options.onUsage;\r\n this.onErrorCallback = options.onError;\r\n this.debug = options.debug ?? false;\r\n }\r\n\r\n /**\r\n * Enqueue a usage event for batch dispatching\r\n */\r\n public enqueue(event: UsageEvent): void {\r\n // 1. Update in-memory local ledger\r\n this.recordInLedger(event);\r\n\r\n // 2. Fire onUsage hook immediately\r\n if (this.onUsageCallback) {\r\n try {\r\n const res = this.onUsageCallback(event);\r\n if (res instanceof Promise) {\r\n res.catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\r\n });\r\n }\r\n } catch (err) {\r\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\r\n }\r\n }\r\n\r\n // 3. If no Stripe client is configured, we're done (local mode)\r\n if (!this.stripeClient) {\r\n if (this.debug) {\r\n console.log(\r\n `[vibezcheck:local] 📊 ${event.model} | Tokens: ${event.usage.totalTokens} | Cost: $${event.cost.totalUSD.toFixed(6)}`\r\n );\r\n }\r\n return;\r\n }\r\n\r\n // 4. Queue for Stripe dispatch\r\n this.queue.push(event);\r\n\r\n if (this.queue.length >= this.maxBatchSize) {\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Batch flush error:', err);\r\n });\r\n } else if (!this.timer) {\r\n this.timer = setTimeout(() => {\r\n this.timer = null;\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Debounce flush error:', err);\r\n });\r\n }, this.flushIntervalMs);\r\n }\r\n }\r\n\r\n /**\r\n * Immediately flush all queued events to Stripe\r\n */\r\n public async flush(): Promise<void> {\r\n if (this.timer) {\r\n clearTimeout(this.timer);\r\n this.timer = null;\r\n }\r\n\r\n if (this.queue.length === 0 || !this.stripeClient || this.isFlushing) {\r\n return;\r\n }\r\n\r\n this.isFlushing = true;\r\n const eventsToSend = [...this.queue];\r\n this.queue = [];\r\n\r\n try {\r\n await this.sendEventsToStripe(eventsToSend);\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n if (this.debug) {\r\n console.error('[vibezcheck] Failed to send meter events to Stripe:', err);\r\n }\r\n if (this.onErrorCallback) {\r\n this.onErrorCallback(err, eventsToSend);\r\n }\r\n } finally {\r\n this.isFlushing = false;\r\n // If new items were queued while flushing, trigger another flush\r\n if (this.queue.length > 0) {\r\n this.flush().catch(() => {});\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sends events to Stripe Billing Meter Events API\r\n */\r\n private async sendEventsToStripe(events: UsageEvent[]): Promise<void> {\r\n if (!this.stripeClient) return;\r\n\r\n for (const event of events) {\r\n const customerId = event.customerId;\r\n if (!customerId) {\r\n // Skip events without customer attribution for Stripe billing\r\n continue;\r\n }\r\n\r\n const timestamp = event.timestamp || new Date().toISOString();\r\n const model = `${event.provider}/${event.model}`;\r\n\r\n // 1. Send Input Tokens Meter Event\r\n if (event.usage.inputTokens > 0) {\r\n try {\r\n await this.stripeClient.v2.billing.meterEvents.create({\r\n event_name: this.eventName,\r\n timestamp,\r\n payload: {\r\n stripe_customer_id: customerId,\r\n value: event.usage.inputTokens.toString(),\r\n model,\r\n token_type: 'input',\r\n cached_tokens: (event.usage.cachedTokens ?? 0).toString(),\r\n ...(event.metadata ? (event.metadata as any) : {}),\r\n },\r\n });\r\n } catch (e) {\r\n if (this.debug) console.warn('[vibezcheck] Input meter event error:', e);\r\n }\r\n }\r\n\r\n // 2. Send Output Tokens Meter Event\r\n if (event.usage.outputTokens > 0) {\r\n try {\r\n await this.stripeClient.v2.billing.meterEvents.create({\r\n event_name: this.eventName,\r\n timestamp,\r\n payload: {\r\n stripe_customer_id: customerId,\r\n value: event.usage.outputTokens.toString(),\r\n model,\r\n token_type: 'output',\r\n reasoning_tokens: (event.usage.reasoningTokens ?? 0).toString(),\r\n visible_tokens: (event.usage.visibleOutputTokens ?? event.usage.outputTokens).toString(),\r\n ...(event.metadata ? (event.metadata as any) : {}),\r\n },\r\n });\r\n } catch (e) {\r\n if (this.debug) console.warn('[vibezcheck] Output meter event error:', e);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates internal in-memory ledger\r\n */\r\n private recordInLedger(event: UsageEvent): void {\r\n this.totalRequests += 1;\r\n this.totalTokens += event.usage.totalTokens;\r\n this.totalInputTokens += event.usage.inputTokens;\r\n this.totalOutputTokens += event.usage.outputTokens;\r\n this.totalReasoningTokens += event.usage.reasoningTokens ?? 0;\r\n this.totalCostUSD += event.cost.totalUSD;\r\n\r\n const modelKey = event.model;\r\n if (!this.byModel[modelKey]) {\r\n this.byModel[modelKey] = { requests: 0, tokens: 0, costUSD: 0 };\r\n }\r\n this.byModel[modelKey].requests += 1;\r\n this.byModel[modelKey].tokens += event.usage.totalTokens;\r\n this.byModel[modelKey].costUSD += event.cost.totalUSD;\r\n }\r\n\r\n /**\r\n * Get in-memory usage summary\r\n */\r\n public getSummary(): UsageSummary {\r\n return {\r\n totalRequests: this.totalRequests,\r\n totalTokens: this.totalTokens,\r\n totalInputTokens: this.totalInputTokens,\r\n totalOutputTokens: this.totalOutputTokens,\r\n totalReasoningTokens: this.totalReasoningTokens,\r\n totalCostUSD: Number(this.totalCostUSD.toFixed(6)),\r\n byModel: { ...this.byModel },\r\n };\r\n }\r\n\r\n /**\r\n * Reset in-memory ledger\r\n */\r\n public resetLedger(): void {\r\n this.totalRequests = 0;\r\n this.totalTokens = 0;\r\n this.totalInputTokens = 0;\r\n this.totalOutputTokens = 0;\r\n this.totalReasoningTokens = 0;\r\n this.totalCostUSD = 0;\r\n this.byModel = {};\r\n }\r\n}\r\n","import type { TokenUsage } from '../../types';\r\n\r\nexport interface ExtractedUsage {\r\n model: string;\r\n provider: string;\r\n usage: TokenUsage;\r\n}\r\n\r\n/**\r\n * Extracts token usage from OpenAI synchronous responses (ChatCompletion, Responses, Embeddings)\r\n */\r\nexport function extractOpenAIResponseUsage(response: any): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // 1. Standard OpenAI ChatCompletion\r\n if ('choices' in response && 'usage' in response && response.usage) {\r\n const rawUsage = response.usage;\r\n const model = response.model || 'gpt-4o';\r\n\r\n const inputTokens = rawUsage.prompt_tokens ?? 0;\r\n const outputTokens = rawUsage.completion_tokens ?? 0;\r\n const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens ?? 0;\r\n const cachedTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? 0;\r\n\r\n return {\r\n model,\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n // 2. OpenAI Embeddings Response\r\n if ('data' in response && 'usage' in response && response.usage && 'model' in response) {\r\n const rawUsage = response.usage;\r\n const inputTokens = rawUsage.prompt_tokens ?? 0;\r\n\r\n return {\r\n model: response.model || 'text-embedding-3-small',\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens: 0,\r\n totalTokens: inputTokens,\r\n },\r\n };\r\n }\r\n\r\n // 3. OpenAI Responses API (New standard)\r\n if ('status' in response && 'usage' in response && response.usage) {\r\n const rawUsage = response.usage;\r\n const model = response.model || 'gpt-5.6-sol';\r\n\r\n const inputTokens = rawUsage.input_tokens ?? rawUsage.prompt_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? rawUsage.completion_tokens ?? 0;\r\n const reasoningTokens =\r\n rawUsage.output_token_details?.reasoning_tokens ??\r\n rawUsage.completion_tokens_details?.reasoning_tokens ??\r\n 0;\r\n const cachedTokens =\r\n rawUsage.input_token_details?.cached_tokens ??\r\n rawUsage.prompt_tokens_details?.cached_tokens ??\r\n 0;\r\n\r\n return {\r\n model,\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Extracts token usage from an individual OpenAI stream chunk or stream accumulator\r\n */\r\nexport function inspectOpenAIStreamChunk(chunk: any): {\r\n model?: string;\r\n usage?: TokenUsage;\r\n} {\r\n if (!chunk || typeof chunk !== 'object') return {};\r\n\r\n const model = chunk.model;\r\n\r\n // Final chunk with usage object (when stream_options: { include_usage: true }, or Groq / DeepSeek / Mistral stream ending)\r\n const rawUsage = chunk.usage || chunk.token_usage || chunk.x_groq?.usage || chunk.usageMetadata;\r\n if (rawUsage) {\r\n const inputTokens =\r\n rawUsage.prompt_tokens ??\r\n rawUsage.input_tokens ??\r\n rawUsage.promptTokens ??\r\n rawUsage.inputTokens ??\r\n rawUsage.promptTokenCount ??\r\n 0;\r\n const outputTokens =\r\n rawUsage.completion_tokens ??\r\n rawUsage.output_tokens ??\r\n rawUsage.completionTokens ??\r\n rawUsage.outputTokens ??\r\n rawUsage.candidatesTokenCount ??\r\n 0;\r\n const reasoningTokens =\r\n rawUsage.completion_tokens_details?.reasoning_tokens ??\r\n rawUsage.output_token_details?.reasoning_tokens ??\r\n rawUsage.reasoning_tokens ??\r\n rawUsage.reasoningTokens ??\r\n rawUsage.thoughtsTokenCount ??\r\n 0;\r\n const cachedTokens =\r\n rawUsage.prompt_tokens_details?.cached_tokens ??\r\n rawUsage.input_token_details?.cached_tokens ??\r\n rawUsage.prompt_cache_hit_tokens ??\r\n rawUsage.cached_tokens ??\r\n rawUsage.cachedTokens ??\r\n rawUsage.cachedContentTokenCount ??\r\n 0;\r\n\r\n return {\r\n model,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n // Response API stream event (response.completed or response.done)\r\n if (chunk.type === 'response.completed' || chunk.type === 'response.done') {\r\n if (chunk.response?.usage) {\r\n const rawUsage = chunk.response.usage;\r\n const inputTokens = rawUsage.input_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? 0;\r\n const reasoningTokens = rawUsage.output_token_details?.reasoning_tokens ?? 0;\r\n const cachedTokens = rawUsage.input_token_details?.cached_tokens ?? 0;\r\n\r\n return {\r\n model: chunk.response.model || model,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n }\r\n\r\n return { model };\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from Anthropic synchronous responses\r\n */\r\nexport function extractAnthropicResponseUsage(response: any): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Anthropic Message response has type: 'message' or role: 'assistant' with usage\r\n if (response.type === 'message' || ('content' in response && 'usage' in response)) {\r\n const rawUsage = response.usage || {};\r\n const model = response.model || 'claude-3-7-sonnet';\r\n\r\n const inputTokens = rawUsage.input_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? 0;\r\n const cachedTokens = rawUsage.cache_read_input_tokens ?? 0;\r\n const cacheWriteTokens = rawUsage.cache_creation_input_tokens ?? 0;\r\n\r\n // Check content blocks for thinking/reasoning tokens count or thinking blocks\r\n let reasoningTokens: number | undefined = undefined;\r\n if (Array.isArray(response.content)) {\r\n const thinkingBlocks = response.content.filter((b: any) => b.type === 'thinking');\r\n if (thinkingBlocks.length > 0) {\r\n // Approximate or extract explicit thinking tokens if present in metadata\r\n reasoningTokens = (rawUsage as any).thinking_tokens ?? undefined;\r\n }\r\n }\r\n\r\n return {\r\n model,\r\n provider: 'anthropic',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens,\r\n visibleOutputTokens:\r\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n cacheWriteTokens: cacheWriteTokens > 0 ? cacheWriteTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Accumulates stream events across an Anthropic raw message stream\r\n */\r\nexport class AnthropicStreamAccumulator {\r\n private model: string = 'claude-3-7-sonnet';\r\n private inputTokens: number = 0;\r\n private outputTokens: number = 0;\r\n private cachedTokens: number = 0;\r\n private cacheWriteTokens: number = 0;\r\n private reasoningTokens: number = 0;\r\n\r\n processEvent(event: any): void {\r\n if (!event || typeof event !== 'object') return;\r\n\r\n // 1. message_start (contains model and initial input usage)\r\n if (event.type === 'message_start' && event.message) {\r\n if (event.message.model) {\r\n this.model = event.message.model;\r\n }\r\n if (event.message.usage) {\r\n this.inputTokens = event.message.usage.input_tokens ?? 0;\r\n this.cachedTokens = event.message.usage.cache_read_input_tokens ?? 0;\r\n this.cacheWriteTokens = event.message.usage.cache_creation_input_tokens ?? 0;\r\n }\r\n }\r\n\r\n // 2. message_delta (contains final output usage)\r\n if (event.type === 'message_delta' && event.usage) {\r\n this.outputTokens = event.usage.output_tokens ?? 0;\r\n if (event.usage.thinking_tokens) {\r\n this.reasoningTokens = event.usage.thinking_tokens;\r\n }\r\n }\r\n\r\n // 3. content_block_start / content_block_delta for thinking blocks\r\n if (event.type === 'content_block_start' && event.content_block?.type === 'thinking') {\r\n // thinking block detected\r\n }\r\n }\r\n\r\n getUsage(): ExtractedUsage {\r\n return {\r\n model: this.model,\r\n provider: 'anthropic',\r\n usage: {\r\n inputTokens: this.inputTokens,\r\n outputTokens: this.outputTokens,\r\n totalTokens: this.inputTokens + this.outputTokens,\r\n reasoningTokens: this.reasoningTokens > 0 ? this.reasoningTokens : undefined,\r\n visibleOutputTokens:\r\n this.reasoningTokens > 0\r\n ? Math.max(0, this.outputTokens - this.reasoningTokens)\r\n : this.outputTokens,\r\n cachedTokens: this.cachedTokens > 0 ? this.cachedTokens : undefined,\r\n cacheWriteTokens: this.cacheWriteTokens > 0 ? this.cacheWriteTokens : undefined,\r\n },\r\n };\r\n }\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from Google Gemini API response or chunk\r\n */\r\nexport function extractGeminiResponseUsage(\r\n response: any,\r\n fallbackModel: string = 'gemini-3.7-flash'\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Gemini returns usageMetadata on response or GenerateContentResult\r\n const usageMetadata = response.usageMetadata || response.response?.usageMetadata;\r\n\r\n if (usageMetadata) {\r\n const inputTokens = usageMetadata.promptTokenCount ?? 0;\r\n const baseOutputTokens = usageMetadata.candidatesTokenCount ?? 0;\r\n const thoughtsTokenCount =\r\n usageMetadata.thoughtsTokenCount ?? (usageMetadata as any).reasoningTokenCount ?? 0;\r\n const cachedTokens = usageMetadata.cachedContentTokenCount ?? 0;\r\n\r\n const totalOutput = baseOutputTokens + thoughtsTokenCount;\r\n const model = response.model || response.response?.model || fallbackModel;\r\n\r\n return {\r\n model,\r\n provider: 'google',\r\n usage: {\r\n inputTokens,\r\n outputTokens: totalOutput,\r\n totalTokens: inputTokens + totalOutput,\r\n reasoningTokens: thoughtsTokenCount > 0 ? thoughtsTokenCount : undefined,\r\n visibleOutputTokens: baseOutputTokens,\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from generic LLM provider objects (DeepSeek, Groq, Mistral, Ollama, Cohere, Together)\r\n */\r\nexport function extractGenericResponseUsage(\r\n response: any,\r\n fallbackModel: string = 'generic-llm',\r\n fallbackProvider: string = 'generic'\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Check common usage property locations\r\n const usage = response.usage || response.token_usage || response.usageMetadata;\r\n\r\n if (usage) {\r\n const inputTokens =\r\n usage.prompt_tokens ??\r\n usage.input_tokens ??\r\n usage.promptTokenCount ??\r\n usage.prompt_eval_count ??\r\n 0;\r\n const outputTokens =\r\n usage.completion_tokens ??\r\n usage.output_tokens ??\r\n usage.candidatesTokenCount ??\r\n usage.eval_count ??\r\n 0;\r\n const reasoningTokens =\r\n usage.reasoning_tokens ??\r\n usage.thoughtsTokenCount ??\r\n usage.completion_tokens_details?.reasoning_tokens ??\r\n 0;\r\n const cachedTokens =\r\n usage.prompt_tokens_details?.cached_tokens ??\r\n usage.cached_tokens ??\r\n usage.cachedContentTokenCount ??\r\n 0;\r\n\r\n const model = response.model || fallbackModel;\r\n const provider = response.provider || fallbackProvider;\r\n\r\n return {\r\n model,\r\n provider,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n","import type { ExtractedUsage } from './openai';\r\nimport { extractOpenAIResponseUsage } from './openai';\r\nimport { extractAnthropicResponseUsage } from './anthropic';\r\nimport { extractGeminiResponseUsage } from './gemini';\r\nimport { extractGenericResponseUsage } from './generic';\r\n\r\nexport * from './openai';\r\nexport * from './anthropic';\r\nexport * from './gemini';\r\nexport * from './generic';\r\n\r\n/**\r\n * Universal polymorphic response detector\r\n */\r\nexport function detectAndExtractUsage(\r\n response: any,\r\n fallbackModel?: string,\r\n fallbackProvider?: string\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // 1. Try OpenAI\r\n const openaiResult = extractOpenAIResponseUsage(response);\r\n if (openaiResult) return openaiResult;\r\n\r\n // 2. Try Anthropic\r\n const anthropicResult = extractAnthropicResponseUsage(response);\r\n if (anthropicResult) return anthropicResult;\r\n\r\n // 3. Try Gemini\r\n const geminiResult = extractGeminiResponseUsage(response, fallbackModel);\r\n if (geminiResult) return geminiResult;\r\n\r\n // 4. Try Generic\r\n const genericResult = extractGenericResponseUsage(response, fallbackModel, fallbackProvider);\r\n if (genericResult) return genericResult;\r\n\r\n return null;\r\n}\r\n","import type { ModelPricingRates } from '../types';\r\n\r\n/**\r\n * Built-in Registry of Model Pricing (USD per 1 Million Tokens)\r\n * Sourced from official 2026 provider pricing tables.\r\n */\r\nexport const MODEL_PRICING_TABLE: Record<string, ModelPricingRates> = {\r\n // --- OpenAI (Modern & Reasoning) ---\r\n 'gpt-5.6-sol': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\r\n 'gpt-5.6-terra': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.2 },\r\n 'gpt-5.6-luna': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\r\n 'gpt-5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\r\n 'gpt-5-mini': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\r\n 'o1': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\r\n 'o1-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\r\n 'o3': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\r\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\r\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10.0, cachedInputPer1M: 1.25 },\r\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },\r\n 'gpt-4.5': { inputPer1M: 75.0, outputPer1M: 150.0, cachedInputPer1M: 37.5 },\r\n 'gpt-4.5-preview': { inputPer1M: 75.0, outputPer1M: 150.0, cachedInputPer1M: 37.5 },\r\n 'chatgpt-4o-latest': { inputPer1M: 5.0, outputPer1M: 15.0 },\r\n 'gpt-4.1': { inputPer1M: 2.0, outputPer1M: 8.0, cachedInputPer1M: 1.0 },\r\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },\r\n\r\n // --- OpenAI (Legacy & Backward Compatibility) ---\r\n 'gpt-4-turbo': { inputPer1M: 10.0, outputPer1M: 30.0, cachedInputPer1M: 5.0 },\r\n 'gpt-4-turbo-preview': { inputPer1M: 10.0, outputPer1M: 30.0, cachedInputPer1M: 5.0 },\r\n 'gpt-4': { inputPer1M: 30.0, outputPer1M: 60.0 },\r\n 'gpt-4-32k': { inputPer1M: 60.0, outputPer1M: 120.0 },\r\n 'gpt-3.5-turbo': { inputPer1M: 0.5, outputPer1M: 1.5 },\r\n 'gpt-3.5-turbo-16k': { inputPer1M: 3.0, outputPer1M: 4.0 },\r\n 'text-embedding-3-small': { inputPer1M: 0.02, outputPer1M: 0.0 },\r\n 'text-embedding-3-large': { inputPer1M: 0.13, outputPer1M: 0.0 },\r\n 'text-embedding-ada-002': { inputPer1M: 0.10, outputPer1M: 0.0 },\r\n\r\n // --- Anthropic (Modern & Extended Thinking) ---\r\n 'claude-3-7-sonnet': { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },\r\n 'claude-sonnet-5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-5-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4.0, cachedInputPer1M: 0.08 },\r\n 'haiku-4.5': { inputPer1M: 1.0, outputPer1M: 5.0, cachedInputPer1M: 0.1 },\r\n 'claude-opus-5': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 1.5 },\r\n 'claude-3-opus': { inputPer1M: 15.0, outputPer1M: 75.0, cachedInputPer1M: 1.5 },\r\n\r\n // --- Anthropic (Legacy & Backward Compatibility) ---\r\n 'claude-3-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-haiku': { inputPer1M: 0.25, outputPer1M: 1.25, cachedInputPer1M: 0.025 },\r\n 'claude-2.1': { inputPer1M: 8.0, outputPer1M: 24.0 },\r\n 'claude-2.0': { inputPer1M: 8.0, outputPer1M: 24.0 },\r\n 'claude-instant-1.2': { inputPer1M: 1.63, outputPer1M: 5.51 },\r\n\r\n // --- Google Gemini (Modern & Thoughts) ---\r\n 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },\r\n 'gemini-3.1-pro': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.5 },\r\n 'gemini-3.5-flash': { inputPer1M: 1.5, outputPer1M: 9.0, cachedInputPer1M: 0.38 },\r\n 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },\r\n 'gemini-2.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n 'gemini-2.5-flash': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.0375 },\r\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },\r\n 'gemini-2.0-flash-lite': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\r\n 'gemini-2.0-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n\r\n // --- Google Gemini (Legacy & Backward Compatibility) ---\r\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\r\n 'gemini-1.5-flash-8b': { inputPer1M: 0.0375, outputPer1M: 0.15, cachedInputPer1M: 0.009375 },\r\n 'gemini-1.0-pro': { inputPer1M: 0.5, outputPer1M: 1.5 },\r\n\r\n // --- xAI Grok ---\r\n 'grok-4.6': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'grok-3': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'grok-3-mini': { inputPer1M: 0.3, outputPer1M: 1.5 },\r\n 'grok-2': { inputPer1M: 2.0, outputPer1M: 10.0 },\r\n 'grok-2-vision': { inputPer1M: 2.0, outputPer1M: 10.0 },\r\n 'grok-beta': { inputPer1M: 5.0, outputPer1M: 15.0 },\r\n\r\n // --- Mistral ---\r\n 'mistral-large-3': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'mistral-large-latest': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'mistral-large-2411': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'codestral-latest': { inputPer1M: 0.3, outputPer1M: 0.9 },\r\n 'mistral-medium-latest': { inputPer1M: 2.7, outputPer1M: 8.1 },\r\n 'mistral-small-latest': { inputPer1M: 0.2, outputPer1M: 0.6 },\r\n 'ministral-8b-latest': { inputPer1M: 0.1, outputPer1M: 0.1 },\r\n 'ministral-3b-latest': { inputPer1M: 0.04, outputPer1M: 0.04 },\r\n 'open-mistral-7b': { inputPer1M: 0.2, outputPer1M: 0.2 },\r\n 'open-mixtral-8x7b': { inputPer1M: 0.7, outputPer1M: 0.7 },\r\n 'open-mixtral-8x22b': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n\r\n // --- Groq & Meta Llama LPUs ---\r\n 'llama-3.3-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\r\n 'llama-3.1-405b': { inputPer1M: 3.0, outputPer1M: 3.0 },\r\n 'llama-3.1-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\r\n 'llama-3.1-8b-instant': { inputPer1M: 0.05, outputPer1M: 0.08 },\r\n 'llama-3.2-1b-preview': { inputPer1M: 0.04, outputPer1M: 0.04 },\r\n 'llama-3.2-3b-preview': { inputPer1M: 0.06, outputPer1M: 0.06 },\r\n 'llama-3.2-11b-vision': { inputPer1M: 0.18, outputPer1M: 0.18 },\r\n 'llama-3.2-90b-vision': { inputPer1M: 0.90, outputPer1M: 0.90 },\r\n 'deepseek-r1-distill-llama-70b': { inputPer1M: 0.75, outputPer1M: 0.99 },\r\n 'deepseek-r1-distill-qwen-32b': { inputPer1M: 0.49, outputPer1M: 0.49 },\r\n 'qwen-2.5-32b': { inputPer1M: 0.29, outputPer1M: 0.39 },\r\n 'qwen-2.5-72b': { inputPer1M: 0.35, outputPer1M: 0.40 },\r\n 'mixtral-8x7b-32768': { inputPer1M: 0.24, outputPer1M: 0.24 },\r\n 'gemma2-9b-it': { inputPer1M: 0.20, outputPer1M: 0.20 },\r\n\r\n // --- DeepSeek ---\r\n 'deepseek-v4-pro': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\r\n 'deepseek-v4-flash': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\r\n 'deepseek-v3': { inputPer1M: 0.14, outputPer1M: 0.28, cachedInputPer1M: 0.014 },\r\n 'deepseek-chat': { inputPer1M: 0.14, outputPer1M: 0.28, cachedInputPer1M: 0.014 },\r\n 'deepseek-r1': { inputPer1M: 0.55, outputPer1M: 2.19, cachedInputPer1M: 0.14 },\r\n 'deepseek-reasoner': { inputPer1M: 0.55, outputPer1M: 2.19, cachedInputPer1M: 0.14 },\r\n\r\n // --- Cohere ---\r\n 'command-r-plus': { inputPer1M: 2.5, outputPer1M: 10.0 },\r\n 'command-r': { inputPer1M: 0.15, outputPer1M: 0.6 },\r\n 'command': { inputPer1M: 1.0, outputPer1M: 2.0 },\r\n 'command-light': { inputPer1M: 0.3, outputPer1M: 0.6 },\r\n 'embed-english-v3.0': { inputPer1M: 0.10, outputPer1M: 0.0 },\r\n\r\n // --- Perplexity ---\r\n 'sonar': { inputPer1M: 1.0, outputPer1M: 1.0 },\r\n 'sonar-pro': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'sonar-reasoning': { inputPer1M: 1.0, outputPer1M: 5.0 },\r\n 'sonar-reasoning-pro': { inputPer1M: 2.0, outputPer1M: 8.0 },\r\n};\r\n\r\n/**\r\n * Common model alias map to normalize nicknames, shorthands, and legacy IDs\r\n */\r\nexport const MODEL_ALIASES: Record<string, string> = {\r\n // OpenAI Shorthands & Aliases\r\n 'gpt4': 'gpt-4',\r\n 'gpt4o': 'gpt-4o',\r\n 'gpt-4-preview': 'gpt-4-turbo',\r\n 'gpt-4-0125-preview': 'gpt-4-turbo',\r\n 'gpt-4-1106-preview': 'gpt-4-turbo',\r\n 'gpt-3.5': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-0125': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-1106': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-16k-0613': 'gpt-3.5-turbo-16k',\r\n\r\n // Anthropic Shorthands\r\n 'sonnet': 'claude-3-5-sonnet',\r\n 'sonnet-3.7': 'claude-3-7-sonnet',\r\n 'sonnet-3.5': 'claude-3-5-sonnet',\r\n 'haiku': 'claude-3-5-haiku',\r\n 'haiku-3.5': 'claude-3-5-haiku',\r\n 'opus': 'claude-3-opus',\r\n 'claude-2': 'claude-2.0',\r\n 'claude-instant': 'claude-instant-1.2',\r\n\r\n // DeepSeek Shorthands\r\n 'r1': 'deepseek-r1',\r\n 'v3': 'deepseek-v3',\r\n\r\n // Gemini Shorthands\r\n 'flash': 'gemini-2.0-flash',\r\n 'pro': 'gemini-1.5-pro',\r\n\r\n // Meta / Groq Shorthands\r\n 'llama-3.3-70b': 'llama-3.3-70b-versatile',\r\n 'llama-3.1-70b': 'llama-3.1-70b-versatile',\r\n 'llama-3.1-8b': 'llama-3.1-8b-instant',\r\n 'llama-3-70b': 'llama-3.1-70b-versatile',\r\n 'llama-3-8b': 'llama-3.1-8b-instant',\r\n\r\n // Mistral Shorthands\r\n 'codestral': 'codestral-latest',\r\n 'mistral-large': 'mistral-large-latest',\r\n 'mistral-small': 'mistral-small-latest',\r\n};\r\n\r\n/**\r\n * Dynamic in-memory registry allowing runtime custom price registration\r\n */\r\nconst customPricingRegistry: Record<string, ModelPricingRates> = {};\r\n\r\n/**\r\n * Normalize model identifier to match pricing table keys:\r\n * - Strips AWS Bedrock prefixes (e.g. 'anthropic.claude-3-5-sonnet-20241022-v2:0' -> 'claude-3-5-sonnet')\r\n * - Strips provider prefixes (e.g. 'openai/gpt-4o' -> 'gpt-4o', 'deepseek/deepseek-r1' -> 'deepseek-r1')\r\n * - Strips date suffixes (e.g. '-20240307', '-20250219')\r\n * - Resolves shorthands and aliases\r\n */\r\nexport function normalizeModelKey(rawModel: string): string {\r\n if (!rawModel) return 'unknown';\r\n\r\n let model = rawModel.toLowerCase().trim();\r\n\r\n // Strip AWS Bedrock model prefix (e.g. 'us.anthropic.claude-3-5-sonnet...', 'meta.llama3-...')\r\n model = model.replace(/^[a-z0-9_-]+\\.(anthropic|meta|amazon|cohere|mistral|ai21)\\./i, '');\r\n model = model.replace(/^(anthropic|meta|amazon|cohere|mistral|ai21)\\./i, '');\r\n\r\n // Strip AWS Bedrock version suffix (e.g. '-v1:0', '-v2:0', ':0')\r\n model = model.replace(/-v\\d+(:\\d+)?$/, '');\r\n model = model.replace(/:\\d+$/, '');\r\n\r\n // Strip provider prefix if present (e.g. 'openai/gpt-4o' -> 'gpt-4o', 'meta-llama/llama-3.3-70b-instruct' -> 'llama-3.3-70b-instruct')\r\n if (model.includes('/')) {\r\n model = model.split('/').slice(1).join('/');\r\n }\r\n\r\n // Remove trailing version/mode tags (e.g. ':latest', ':free', ':beta')\r\n model = model.replace(/:(latest|free|beta)$/, '');\r\n\r\n // Remove date suffixes like -20240307 or -20250219 or -2024-08-06\r\n model = model.replace(/-\\d{8}$/, '');\r\n model = model.replace(/-\\d{4}-\\d{2}-\\d{2}$/, '');\r\n\r\n // Normalize Bedrock Meta format (e.g. llama3-1-70b -> llama-3.1-70b)\r\n model = model.replace(/llama(\\d+)-(\\d+)-/g, 'llama-$1.$2-');\r\n model = model.replace(/llama(\\d+)\\.(\\d+)-/g, 'llama-$1.$2-');\r\n\r\n // Check aliases before fine-tuning\r\n if (MODEL_ALIASES[model]) {\r\n return MODEL_ALIASES[model];\r\n }\r\n\r\n // Remove common modifier suffixes if not directly matching table\r\n if (!MODEL_PRICING_TABLE[model]) {\r\n const withoutInstruct = model.replace(/-(instruct|chat|preview)$/, '');\r\n if (MODEL_PRICING_TABLE[withoutInstruct]) {\r\n return withoutInstruct;\r\n }\r\n if (MODEL_ALIASES[withoutInstruct]) {\r\n return MODEL_ALIASES[withoutInstruct];\r\n }\r\n }\r\n\r\n return model;\r\n}\r\n\r\n/**\r\n * Retrieve pricing rates for a given model\r\n */\r\nexport function getModelPricing(modelName: string): ModelPricingRates {\r\n const normalized = normalizeModelKey(modelName);\r\n\r\n // Check custom registry first\r\n if (customPricingRegistry[normalized]) {\r\n return customPricingRegistry[normalized];\r\n }\r\n if (customPricingRegistry[modelName]) {\r\n return customPricingRegistry[modelName];\r\n }\r\n\r\n // Check built-in table with normalized key\r\n if (MODEL_PRICING_TABLE[normalized]) {\r\n return MODEL_PRICING_TABLE[normalized];\r\n }\r\n // Check built-in table with direct key\r\n if (MODEL_PRICING_TABLE[modelName]) {\r\n return MODEL_PRICING_TABLE[modelName];\r\n }\r\n\r\n // Check alias table fallback\r\n const alias = MODEL_ALIASES[modelName.toLowerCase().trim()];\r\n if (alias && MODEL_PRICING_TABLE[alias]) {\r\n return MODEL_PRICING_TABLE[alias];\r\n }\r\n\r\n // Fallback defaults for unknown models (conservative estimates: $1.00 in, $3.00 out)\r\n return {\r\n inputPer1M: 1.0,\r\n outputPer1M: 3.0,\r\n cachedInputPer1M: 0.5,\r\n };\r\n}\r\n\r\n/**\r\n * Register or override pricing rates for a custom model\r\n */\r\nexport function registerModelPricing(modelName: string, rates: ModelPricingRates): void {\r\n const normalized = normalizeModelKey(modelName);\r\n customPricingRegistry[normalized] = rates;\r\n customPricingRegistry[modelName] = rates;\r\n}\r\n","import type { InferenceCost, TokenUsage, InlineRateConfig, ModelPricingRates } from '../types';\nimport { getModelPricing } from './table';\n\nexport interface CalculateCostParams {\n model: string;\n inputTokens?: number;\n outputTokens?: number;\n reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n markupMultiplier?: number;\n minimumChargeUSD?: number;\n customRate?: InlineRateConfig;\n}\n\n/**\n * BigInt Nano-Precision Financial Math Engine\n * 1 USD = 1,000,000,000 Nano-USD (10^9)\n * 1 token at $1.00 / 1M = $0.000001 = 1,000 Nano-USD\n * Prevents IEEE 754 floating point precision drift on micro-transactions.\n */\nexport function calculateCost(params: CalculateCostParams): InferenceCost {\n let rates: ModelPricingRates;\n\n if (params.customRate) {\n const outRate = params.customRate.out ?? params.customRate.output ?? 0;\n rates = {\n inputPer1M: params.customRate.in,\n outputPer1M: outRate,\n reasoningPer1M: params.customRate.reasoning ?? outRate,\n cachedInputPer1M: params.customRate.cached ?? params.customRate.in * 0.15,\n currency: 'USD',\n };\n } else {\n rates = getModelPricing(params.model);\n }\n\n const inputTokens = BigInt(Math.max(0, params.inputTokens ?? 0));\n const outputTokens = BigInt(Math.max(0, params.outputTokens ?? 0));\n const reasoningTokens = BigInt(Math.max(0, params.reasoningTokens ?? 0));\n const cachedTokens = BigInt(Math.max(0, params.cachedTokens ?? 0));\n\n // Regular input tokens (minus any cached tokens)\n const regularInputTokens = inputTokens > cachedTokens ? inputTokens - cachedTokens : 0n;\n\n // Convert rate per 1M tokens to integer nano-dollars per single token (rate * 1,000)\n // Using 10^9 nano-precision\n const rateInputNano = BigInt(Math.round(rates.inputPer1M * 1_000));\n const cachedPer1M = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15;\n const rateCachedNano = BigInt(Math.round(cachedPer1M * 1_000));\n const rateOutputNano = BigInt(Math.round(rates.outputPer1M * 1_000));\n const reasoningPer1M = rates.reasoningPer1M ?? rates.outputPer1M;\n const rateReasoningNano = BigInt(Math.round(reasoningPer1M * 1_000));\n\n // Compute component nano costs\n const regularInputCostNano = regularInputTokens * rateInputNano;\n const cachedInputCostNano = cachedTokens * rateCachedNano;\n const inputCostNano = regularInputCostNano + cachedInputCostNano;\n const outputCostNano = outputTokens * rateOutputNano;\n const reasoningCostNano = reasoningTokens * rateReasoningNano;\n\n // Prompt cache savings discount\n const standardCacheCostNano = cachedTokens * rateInputNano;\n const cachedDiscountNano =\n standardCacheCostNano > cachedInputCostNano ? standardCacheCostNano - cachedInputCostNano : 0n;\n\n // Total wholesale cost\n const wholesaleNano = inputCostNano + outputCostNano;\n\n // Retail calculation\n const markup = params.markupMultiplier ?? 1.0;\n let billedNano = wholesaleNano;\n let hasRetail = false;\n\n if (markup !== 1.0 || params.minimumChargeUSD !== undefined) {\n hasRetail = true;\n const markupMultiplierNano = BigInt(Math.round(markup * 1_000));\n billedNano = (wholesaleNano * markupMultiplierNano) / 1_000n;\n\n if (params.minimumChargeUSD !== undefined && params.minimumChargeUSD > 0) {\n const minChargeNano = BigInt(Math.round(params.minimumChargeUSD * 1_000_000_000));\n if (billedNano < minChargeNano) {\n billedNano = minChargeNano;\n }\n }\n }\n\n const inputCostUSD = Number(inputCostNano) / 1_000_000_000;\n const outputCostUSD = Number(outputCostNano) / 1_000_000_000;\n const reasoningCostUSD = Number(reasoningCostNano) / 1_000_000_000;\n const cachedDiscountUSD = Number(cachedDiscountNano) / 1_000_000_000;\n const totalUSD = Number(wholesaleNano) / 1_000_000_000;\n const wholesaleTotalUSD = totalUSD;\n const billedUSD = Number(billedNano) / 1_000_000_000;\n const profitUSD = Math.max(0, billedUSD - wholesaleTotalUSD);\n const retailUSD = hasRetail ? billedUSD : undefined;\n\n return {\n inputCostUSD: Number(inputCostUSD.toFixed(8)),\n outputCostUSD: Number(outputCostUSD.toFixed(8)),\n reasoningCostUSD: reasoningTokens > 0n ? Number(reasoningCostUSD.toFixed(8)) : undefined,\n cachedDiscountUSD: cachedTokens > 0n ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n totalUSD: Number(totalUSD.toFixed(8)),\n wholesaleTotalUSD: Number(wholesaleTotalUSD.toFixed(8)),\n billedUSD: Number(billedUSD.toFixed(8)),\n profitUSD: Number(profitUSD.toFixed(8)),\n retailUSD: retailUSD !== undefined ? Number(retailUSD.toFixed(8)) : undefined,\n currency: rates.currency || 'USD',\n };\n}\n\n/**\n * Calculates cost directly from a TokenUsage object\n */\nexport function calculateUsageCost(\n model: string,\n usage: TokenUsage,\n optionsOrMarkup?: number | { markupMultiplier?: number; minimumChargeUSD?: number; customRate?: InlineRateConfig }\n): InferenceCost {\n const options =\n typeof optionsOrMarkup === 'number'\n ? { markupMultiplier: optionsOrMarkup }\n : optionsOrMarkup || {};\n\n return calculateCost({\n model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n reasoningTokens: usage.reasoningTokens,\n cachedTokens: usage.cachedTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n markupMultiplier: options.markupMultiplier,\n minimumChargeUSD: options.minimumChargeUSD,\n customRate: options.customRate,\n });\n}\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n","import type { UsageEvent, StreamWrapOptions } from '../types';\r\nimport { inspectOpenAIStreamChunk } from './extractors/openai';\r\nimport { AnthropicStreamAccumulator } from './extractors/anthropic';\r\nimport { extractGeminiResponseUsage } from './extractors/gemini';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport type UsageDispatchedCallback = (event: UsageEvent) => void;\r\n\r\n/**\r\n * Wraps an OpenAI async iterable stream to capture usage at stream conclusion\r\n */\r\nexport function wrapOpenAIStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n let detectedModel = options.model || 'gpt-4o';\r\n let finalUsage: any = null;\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const chunk of stream) {\r\n const inspected = inspectOpenAIStreamChunk(chunk);\r\n if (inspected.model) {\r\n detectedModel = inspected.model;\r\n }\r\n if (inspected.usage) {\r\n finalUsage = inspected.usage;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (finalUsage) {\r\n const cost = calculateUsageCost(detectedModel, finalUsage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: detectedModel,\r\n provider: 'openai',\r\n usage: finalUsage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps an Anthropic message stream to accumulate message_start and message_delta usage\r\n */\r\nexport function wrapAnthropicStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n const accumulator = new AnthropicStreamAccumulator();\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const event of stream) {\r\n accumulator.processEvent(event);\r\n yield event;\r\n }\r\n } finally {\r\n const extracted = accumulator.getUsage();\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const usageEvent: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: 'anthropic',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(usageEvent);\r\n if (options.onUsage) {\r\n options.onUsage(usageEvent);\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps a Google Gemini GenerateContentStreamResult\r\n */\r\nexport function wrapGeminiStream(\r\n result: any,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): any {\r\n if (!result || !result.stream) return result;\r\n\r\n const originalStream = result.stream;\r\n const model = options.model || 'gemini-3.7-flash';\r\n let lastChunkWithUsage: any = null;\r\n\r\n const wrappedStream = (async function* () {\r\n try {\r\n for await (const chunk of originalStream) {\r\n if (chunk.usageMetadata) {\r\n lastChunkWithUsage = chunk;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (lastChunkWithUsage) {\r\n const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);\r\n if (extracted) {\r\n const cost = calculateUsageCost(extracted.model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: extracted.model,\r\n provider: 'google',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n }\r\n })();\r\n\r\n return {\r\n ...result,\r\n stream: wrappedStream,\r\n };\r\n}\r\n\r\n/**\r\n * Universal Stream Wrapper\r\n */\r\nexport function wrapUniversalStream<T>(\r\n stream: T,\r\n options: StreamWrapOptions = {},\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n if (!stream || typeof stream !== 'object') return stream;\r\n\r\n // 1. Check Gemini stream\r\n if ('stream' in stream && 'response' in stream) {\r\n return wrapGeminiStream(stream, options, onComplete);\r\n }\r\n\r\n // 2. Check if stream is an AsyncIterable\r\n if (Symbol.asyncIterator in stream) {\r\n // If provider is explicitly anthropic or model is claude\r\n if (options.provider === 'anthropic' || options.model?.toLowerCase().includes('claude')) {\r\n return wrapAnthropicStream(stream as any, options, onComplete);\r\n }\r\n // Default to universal stream wrapper which detects usage chunks polymorphically\r\n return wrapOpenAIStream(stream as any, options, onComplete);\r\n }\r\n\r\n return stream;\r\n}\r\n","/**\n * 100% Drop-In Replacement for @stripe/token-meter\n * Metering for native OpenAI, Anthropic, and Google Gemini SDKs\n */\n\nimport { VibezMeter } from '../meter/client';\nimport { calculateUsageCost } from '../pricing/calculator';\n\nexport interface TokenMeterConfig {\n eventName?: string;\n}\n\nexport type TokenMeterCustomer = string | { customer?: string; customerId?: string };\n\nexport interface TokenMeter {\n trackUsage(response: any, customer: TokenMeterCustomer): void;\n track(response: any, customer: TokenMeterCustomer): void;\n trackUsageStreamOpenAI<T>(stream: T, customer: TokenMeterCustomer): T;\n trackUsageStreamAnthropic<T>(stream: T, customer: TokenMeterCustomer): T;\n trackUsageStreamGemini<T>(stream: T, customer: TokenMeterCustomer, modelName?: string): T;\n trackUsageStreamDeepSeek<T>(stream: T, customer: TokenMeterCustomer, modelName?: string): T;\n trackUsageStreamGroq<T>(stream: T, customer: TokenMeterCustomer, modelName?: string): T;\n trackUsageStreamMistral<T>(stream: T, customer: TokenMeterCustomer, modelName?: string): T;\n trackUsageStream<T>(stream: T, customer: TokenMeterCustomer, options?: { model?: string; provider?: string }): T;\n}\n\nexport function createTokenMeter(\n stripeApiKey?: string,\n config: TokenMeterConfig = {}\n): TokenMeter {\n const apiKey = stripeApiKey || (typeof process !== 'undefined' ? (process.env?.STRIPE_SECRET_KEY || process.env?.STRIPE_API_KEY) : undefined);\n const meter = new VibezMeter({\n apiKey,\n eventName: config.eventName,\n });\n\n const resolveCustomer = (cust: TokenMeterCustomer): string => {\n if (typeof cust === 'string') return cust;\n return cust.customerId || cust.customer || 'unknown-customer';\n };\n\n return {\n trackUsage(response: any, customer: TokenMeterCustomer): void {\n if (!response) return;\n const customerId = resolveCustomer(customer);\n meter.trackUsage(response, { customer: customerId });\n },\n\n track(response: any, customer: TokenMeterCustomer): void {\n if (!response) return;\n const customerId = resolveCustomer(customer);\n meter.trackUsage(response, { customer: customerId });\n },\n\n trackUsageStreamOpenAI<T>(stream: any, customer: TokenMeterCustomer): T {\n if (!stream || typeof stream[Symbol.asyncIterator] !== 'function') {\n return stream;\n }\n\n const stripeCustomerId = resolveCustomer(customer);\n const originalIterator = stream[Symbol.asyncIterator].bind(stream);\n let capturedUsage: any = null;\n let capturedModel = 'gpt-4o';\n\n const wrappedAsyncGenerator = async function* () {\n try {\n for await (const chunk of originalIterator()) {\n if (chunk.model) {\n capturedModel = chunk.model;\n }\n if (chunk.usage || chunk.token_usage) {\n capturedUsage = chunk.usage || chunk.token_usage;\n }\n yield chunk;\n }\n } finally {\n if (capturedUsage) {\n meter.recordUsage({\n model: capturedModel,\n provider: 'openai',\n inputTokens: capturedUsage.prompt_tokens ?? capturedUsage.inputTokens ?? 0,\n outputTokens: capturedUsage.completion_tokens ?? capturedUsage.outputTokens ?? 0,\n reasoningTokens:\n capturedUsage.completion_tokens_details?.reasoning_tokens ??\n capturedUsage.output_token_details?.reasoning_tokens ??\n 0,\n cachedTokens:\n capturedUsage.prompt_tokens_details?.cached_tokens ??\n capturedUsage.input_token_details?.cached_tokens ??\n 0,\n customer: stripeCustomerId,\n });\n }\n }\n };\n\n return wrappedAsyncGenerator() as unknown as T;\n },\n\n trackUsageStreamAnthropic<T>(stream: any, customer: TokenMeterCustomer): T {\n if (!stream || typeof stream[Symbol.asyncIterator] !== 'function') {\n return stream;\n }\n\n const stripeCustomerId = resolveCustomer(customer);\n const originalIterator = stream[Symbol.asyncIterator].bind(stream);\n let capturedUsage: any = null;\n let capturedModel = 'claude-3-5-sonnet';\n\n const wrappedAsyncGenerator = async function* () {\n try {\n for await (const chunk of originalIterator()) {\n if (chunk.type === 'message_start' && chunk.message?.model) {\n capturedModel = chunk.message.model;\n if (chunk.message.usage) {\n capturedUsage = { ...capturedUsage, ...chunk.message.usage };\n }\n } else if (chunk.type === 'message_delta' && chunk.usage) {\n capturedUsage = { ...capturedUsage, ...chunk.usage };\n }\n yield chunk;\n }\n } finally {\n if (capturedUsage) {\n meter.recordUsage({\n model: capturedModel,\n provider: 'anthropic',\n inputTokens: capturedUsage.input_tokens ?? 0,\n outputTokens: capturedUsage.output_tokens ?? 0,\n cachedTokens: capturedUsage.cache_read_input_tokens ?? 0,\n customer: stripeCustomerId,\n });\n }\n }\n };\n\n return wrappedAsyncGenerator() as unknown as T;\n },\n\n trackUsageStreamGemini<T>(streamResult: any, customer: TokenMeterCustomer, modelName: string = 'gemini-2.0-flash'): T {\n const stripeCustomerId = resolveCustomer(customer);\n const originalStream = streamResult?.stream || streamResult;\n if (!originalStream || typeof originalStream[Symbol.asyncIterator] !== 'function') {\n return streamResult;\n }\n\n const wrappedAsyncGenerator = async function* () {\n let lastUsageMetadata: any = null;\n\n try {\n for await (const chunk of originalStream) {\n if (chunk.usageMetadata) {\n lastUsageMetadata = chunk.usageMetadata;\n }\n yield chunk;\n }\n } finally {\n if (lastUsageMetadata) {\n meter.recordUsage({\n model: modelName,\n provider: 'google',\n inputTokens: lastUsageMetadata.promptTokenCount ?? 0,\n outputTokens:\n (lastUsageMetadata.candidatesTokenCount ?? 0) +\n (lastUsageMetadata.thoughtsTokenCount ?? 0),\n reasoningTokens: lastUsageMetadata.thoughtsTokenCount ?? 0,\n customer: stripeCustomerId,\n });\n }\n }\n };\n\n if (streamResult && streamResult.stream) {\n return {\n ...streamResult,\n stream: wrappedAsyncGenerator(),\n } as T;\n }\n\n return wrappedAsyncGenerator() as unknown as T;\n },\n\n trackUsageStreamDeepSeek<T>(stream: any, customer: TokenMeterCustomer, modelName: string = 'deepseek-chat'): T {\n const stripeCustomerId = resolveCustomer(customer);\n if (!stream || typeof stream[Symbol.asyncIterator] !== 'function') {\n return stream;\n }\n\n const originalIterator = stream[Symbol.asyncIterator].bind(stream);\n let capturedUsage: any = null;\n let capturedModel = modelName;\n\n const wrappedAsyncGenerator = async function* () {\n try {\n for await (const chunk of originalIterator()) {\n if (chunk.model) capturedModel = chunk.model;\n if (chunk.usage) capturedUsage = chunk.usage;\n yield chunk;\n }\n } finally {\n if (capturedUsage) {\n meter.recordUsage({\n model: capturedModel,\n provider: 'deepseek',\n inputTokens: capturedUsage.prompt_tokens ?? capturedUsage.inputTokens ?? 0,\n outputTokens: capturedUsage.completion_tokens ?? capturedUsage.outputTokens ?? 0,\n reasoningTokens: capturedUsage.completion_tokens_details?.reasoning_tokens ?? 0,\n cachedTokens: capturedUsage.prompt_cache_hit_tokens ?? capturedUsage.prompt_tokens_details?.cached_tokens ?? 0,\n customer: stripeCustomerId,\n });\n }\n }\n };\n\n return wrappedAsyncGenerator() as unknown as T;\n },\n\n trackUsageStreamGroq<T>(stream: any, customer: TokenMeterCustomer, modelName: string = 'llama-3.3-70b-versatile'): T {\n const stripeCustomerId = resolveCustomer(customer);\n if (!stream || typeof stream[Symbol.asyncIterator] !== 'function') {\n return stream;\n }\n\n const originalIterator = stream[Symbol.asyncIterator].bind(stream);\n let capturedUsage: any = null;\n let capturedModel = modelName;\n\n const wrappedAsyncGenerator = async function* () {\n try {\n for await (const chunk of originalIterator()) {\n if (chunk.model) capturedModel = chunk.model;\n if (chunk.usage || chunk.x_groq?.usage) {\n capturedUsage = chunk.usage || chunk.x_groq?.usage;\n }\n yield chunk;\n }\n } finally {\n if (capturedUsage) {\n meter.recordUsage({\n model: capturedModel,\n provider: 'groq',\n inputTokens: capturedUsage.prompt_tokens ?? 0,\n outputTokens: capturedUsage.completion_tokens ?? 0,\n customer: stripeCustomerId,\n });\n }\n }\n };\n\n return wrappedAsyncGenerator() as unknown as T;\n },\n\n trackUsageStreamMistral<T>(stream: any, customer: TokenMeterCustomer, modelName: string = 'mistral-large-latest'): T {\n const stripeCustomerId = resolveCustomer(customer);\n if (!stream || typeof stream[Symbol.asyncIterator] !== 'function') {\n return stream;\n }\n\n const originalIterator = stream[Symbol.asyncIterator].bind(stream);\n let capturedUsage: any = null;\n let capturedModel = modelName;\n\n const wrappedAsyncGenerator = async function* () {\n try {\n for await (const chunk of originalIterator()) {\n if (chunk.model) capturedModel = chunk.model;\n if (chunk.usage) capturedUsage = chunk.usage;\n yield chunk;\n }\n } finally {\n if (capturedUsage) {\n meter.recordUsage({\n model: capturedModel,\n provider: 'mistral',\n inputTokens: capturedUsage.prompt_tokens ?? 0,\n outputTokens: capturedUsage.completion_tokens ?? 0,\n customer: stripeCustomerId,\n });\n }\n }\n };\n\n return wrappedAsyncGenerator() as unknown as T;\n },\n\n trackUsageStream<T>(stream: T, customer: TokenMeterCustomer, options: { model?: string; provider?: string } = {}): T {\n const stripeCustomerId = resolveCustomer(customer);\n return meter.wrapStream(stream, {\n customer: stripeCustomerId,\n model: options.model,\n provider: options.provider,\n });\n },\n };\n}\n\nexport default createTokenMeter;\n"],"mappings":";AAAA,OAAO,YAAY;;;ACGZ,IAAM,eAAN,MAAmB;AAAA,EAChB,QAAsB,CAAC;AAAA,EACvB,QAA+B;AAAA,EAC/B,aAAsB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGT,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,UAAiF,CAAC;AAAA,EAE1F,YAAY,UAAwB,CAAC,GAAG;AACtC,SAAK,eAAe,QAAQ;AAC5B,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,eAAe,QAAQ,UAAU,gBAAgB;AACtD,SAAK,kBAAkB,QAAQ,UAAU,mBAAmB;AAC5D,SAAK,kBAAkB,QAAQ;AAC/B,SAAK,kBAAkB,QAAQ;AAC/B,SAAK,QAAQ,QAAQ,SAAS;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKO,QAAQ,OAAyB;AAEtC,SAAK,eAAe,KAAK;AAGzB,QAAI,KAAK,iBAAiB;AACxB,UAAI;AACF,cAAM,MAAM,KAAK,gBAAgB,KAAK;AACtC,YAAI,eAAe,SAAS;AAC1B,cAAI,MAAM,CAAC,QAAQ;AACjB,gBAAI,KAAK,MAAO,SAAQ,MAAM,2CAA2C,GAAG;AAAA,UAC9E,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,KAAK,MAAO,SAAQ,MAAM,2CAA2C,GAAG;AAAA,MAC9E;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,cAAc;AACtB,UAAI,KAAK,OAAO;AACd,gBAAQ;AAAA,UACN,gCAAyB,MAAM,KAAK,cAAc,MAAM,MAAM,WAAW,aAAa,MAAM,KAAK,SAAS,QAAQ,CAAC,CAAC;AAAA,QACtH;AAAA,MACF;AACA;AAAA,IACF;AAGA,SAAK,MAAM,KAAK,KAAK;AAErB,QAAI,KAAK,MAAM,UAAU,KAAK,cAAc;AAC1C,WAAK,MAAM,EAAE,MAAM,CAAC,QAAQ;AAC1B,YAAI,KAAK,MAAO,SAAQ,MAAM,mCAAmC,GAAG;AAAA,MACtE,CAAC;AAAA,IACH,WAAW,CAAC,KAAK,OAAO;AACtB,WAAK,QAAQ,WAAW,MAAM;AAC5B,aAAK,QAAQ;AACb,aAAK,MAAM,EAAE,MAAM,CAAC,QAAQ;AAC1B,cAAI,KAAK,MAAO,SAAQ,MAAM,sCAAsC,GAAG;AAAA,QACzE,CAAC;AAAA,MACH,GAAG,KAAK,eAAe;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAuB;AAClC,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AAEA,QAAI,KAAK,MAAM,WAAW,KAAK,CAAC,KAAK,gBAAgB,KAAK,YAAY;AACpE;AAAA,IACF;AAEA,SAAK,aAAa;AAClB,UAAM,eAAe,CAAC,GAAG,KAAK,KAAK;AACnC,SAAK,QAAQ,CAAC;AAEd,QAAI;AACF,YAAM,KAAK,mBAAmB,YAAY;AAAA,IAC5C,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,UAAI,KAAK,OAAO;AACd,gBAAQ,MAAM,uDAAuD,GAAG;AAAA,MAC1E;AACA,UAAI,KAAK,iBAAiB;AACxB,aAAK,gBAAgB,KAAK,YAAY;AAAA,MACxC;AAAA,IACF,UAAE;AACA,WAAK,aAAa;AAElB,UAAI,KAAK,MAAM,SAAS,GAAG;AACzB,aAAK,MAAM,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBAAmB,QAAqC;AACpE,QAAI,CAAC,KAAK,aAAc;AAExB,eAAW,SAAS,QAAQ;AAC1B,YAAM,aAAa,MAAM;AACzB,UAAI,CAAC,YAAY;AAEf;AAAA,MACF;AAEA,YAAM,YAAY,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC5D,YAAM,QAAQ,GAAG,MAAM,QAAQ,IAAI,MAAM,KAAK;AAG9C,UAAI,MAAM,MAAM,cAAc,GAAG;AAC/B,YAAI;AACF,gBAAM,KAAK,aAAa,GAAG,QAAQ,YAAY,OAAO;AAAA,YACpD,YAAY,KAAK;AAAA,YACjB;AAAA,YACA,SAAS;AAAA,cACP,oBAAoB;AAAA,cACpB,OAAO,MAAM,MAAM,YAAY,SAAS;AAAA,cACxC;AAAA,cACA,YAAY;AAAA,cACZ,gBAAgB,MAAM,MAAM,gBAAgB,GAAG,SAAS;AAAA,cACxD,GAAI,MAAM,WAAY,MAAM,WAAmB,CAAC;AAAA,YAClD;AAAA,UACF,CAAC;AAAA,QACH,SAAS,GAAG;AACV,cAAI,KAAK,MAAO,SAAQ,KAAK,yCAAyC,CAAC;AAAA,QACzE;AAAA,MACF;AAGA,UAAI,MAAM,MAAM,eAAe,GAAG;AAChC,YAAI;AACF,gBAAM,KAAK,aAAa,GAAG,QAAQ,YAAY,OAAO;AAAA,YACpD,YAAY,KAAK;AAAA,YACjB;AAAA,YACA,SAAS;AAAA,cACP,oBAAoB;AAAA,cACpB,OAAO,MAAM,MAAM,aAAa,SAAS;AAAA,cACzC;AAAA,cACA,YAAY;AAAA,cACZ,mBAAmB,MAAM,MAAM,mBAAmB,GAAG,SAAS;AAAA,cAC9D,iBAAiB,MAAM,MAAM,uBAAuB,MAAM,MAAM,cAAc,SAAS;AAAA,cACvF,GAAI,MAAM,WAAY,MAAM,WAAmB,CAAC;AAAA,YAClD;AAAA,UACF,CAAC;AAAA,QACH,SAAS,GAAG;AACV,cAAI,KAAK,MAAO,SAAQ,KAAK,0CAA0C,CAAC;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,OAAyB;AAC9C,SAAK,iBAAiB;AACtB,SAAK,eAAe,MAAM,MAAM;AAChC,SAAK,oBAAoB,MAAM,MAAM;AACrC,SAAK,qBAAqB,MAAM,MAAM;AACtC,SAAK,wBAAwB,MAAM,MAAM,mBAAmB;AAC5D,SAAK,gBAAgB,MAAM,KAAK;AAEhC,UAAM,WAAW,MAAM;AACvB,QAAI,CAAC,KAAK,QAAQ,QAAQ,GAAG;AAC3B,WAAK,QAAQ,QAAQ,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,SAAS,EAAE;AAAA,IAChE;AACA,SAAK,QAAQ,QAAQ,EAAE,YAAY;AACnC,SAAK,QAAQ,QAAQ,EAAE,UAAU,MAAM,MAAM;AAC7C,SAAK,QAAQ,QAAQ,EAAE,WAAW,MAAM,KAAK;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKO,aAA2B;AAChC,WAAO;AAAA,MACL,eAAe,KAAK;AAAA,MACpB,aAAa,KAAK;AAAA,MAClB,kBAAkB,KAAK;AAAA,MACvB,mBAAmB,KAAK;AAAA,MACxB,sBAAsB,KAAK;AAAA,MAC3B,cAAc,OAAO,KAAK,aAAa,QAAQ,CAAC,CAAC;AAAA,MACjD,SAAS,EAAE,GAAG,KAAK,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,cAAoB;AACzB,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,mBAAmB;AACxB,SAAK,oBAAoB;AACzB,SAAK,uBAAuB;AAC5B,SAAK,eAAe;AACpB,SAAK,UAAU,CAAC;AAAA,EAClB;AACF;;;ACrNO,SAAS,2BAA2B,UAAsC;AAC/E,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO;AAGtD,MAAI,aAAa,YAAY,WAAW,YAAY,SAAS,OAAO;AAClE,UAAM,WAAW,SAAS;AAC1B,UAAM,QAAQ,SAAS,SAAS;AAEhC,UAAM,cAAc,SAAS,iBAAiB;AAC9C,UAAM,eAAe,SAAS,qBAAqB;AACnD,UAAM,kBAAkB,SAAS,2BAA2B,oBAAoB;AAChF,UAAM,eAAe,SAAS,uBAAuB,iBAAiB;AAEtE,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,aAAa,cAAc;AAAA,QAC3B,iBAAiB,kBAAkB,IAAI,kBAAkB;AAAA,QACzD,qBAAqB,KAAK,IAAI,GAAG,eAAe,eAAe;AAAA,QAC/D,cAAc,eAAe,IAAI,eAAe;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAU,YAAY,WAAW,YAAY,SAAS,SAAS,WAAW,UAAU;AACtF,UAAM,WAAW,SAAS;AAC1B,UAAM,cAAc,SAAS,iBAAiB;AAE9C,WAAO;AAAA,MACL,OAAO,SAAS,SAAS;AAAA,MACzB,UAAU;AAAA,MACV,OAAO;AAAA,QACL;AAAA,QACA,cAAc;AAAA,QACd,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAGA,MAAI,YAAY,YAAY,WAAW,YAAY,SAAS,OAAO;AACjE,UAAM,WAAW,SAAS;AAC1B,UAAM,QAAQ,SAAS,SAAS;AAEhC,UAAM,cAAc,SAAS,gBAAgB,SAAS,iBAAiB;AACvE,UAAM,eAAe,SAAS,iBAAiB,SAAS,qBAAqB;AAC7E,UAAM,kBACJ,SAAS,sBAAsB,oBAC/B,SAAS,2BAA2B,oBACpC;AACF,UAAM,eACJ,SAAS,qBAAqB,iBAC9B,SAAS,uBAAuB,iBAChC;AAEF,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,aAAa,cAAc;AAAA,QAC3B,iBAAiB,kBAAkB,IAAI,kBAAkB;AAAA,QACzD,qBAAqB,KAAK,IAAI,GAAG,eAAe,eAAe;AAAA,QAC/D,cAAc,eAAe,IAAI,eAAe;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,yBAAyB,OAGvC;AACA,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,CAAC;AAEjD,QAAM,QAAQ,MAAM;AAGpB,QAAM,WAAW,MAAM,SAAS,MAAM,eAAe,MAAM,QAAQ,SAAS,MAAM;AAClF,MAAI,UAAU;AACZ,UAAM,cACJ,SAAS,iBACT,SAAS,gBACT,SAAS,gBACT,SAAS,eACT,SAAS,oBACT;AACF,UAAM,eACJ,SAAS,qBACT,SAAS,iBACT,SAAS,oBACT,SAAS,gBACT,SAAS,wBACT;AACF,UAAM,kBACJ,SAAS,2BAA2B,oBACpC,SAAS,sBAAsB,oBAC/B,SAAS,oBACT,SAAS,mBACT,SAAS,sBACT;AACF,UAAM,eACJ,SAAS,uBAAuB,iBAChC,SAAS,qBAAqB,iBAC9B,SAAS,2BACT,SAAS,iBACT,SAAS,gBACT,SAAS,2BACT;AAEF,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,aAAa,cAAc;AAAA,QAC3B,iBAAiB,kBAAkB,IAAI,kBAAkB;AAAA,QACzD,qBAAqB,KAAK,IAAI,GAAG,eAAe,eAAe;AAAA,QAC/D,cAAc,eAAe,IAAI,eAAe;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAGA,MAAI,MAAM,SAAS,wBAAwB,MAAM,SAAS,iBAAiB;AACzE,QAAI,MAAM,UAAU,OAAO;AACzB,YAAMA,YAAW,MAAM,SAAS;AAChC,YAAM,cAAcA,UAAS,gBAAgB;AAC7C,YAAM,eAAeA,UAAS,iBAAiB;AAC/C,YAAM,kBAAkBA,UAAS,sBAAsB,oBAAoB;AAC3E,YAAM,eAAeA,UAAS,qBAAqB,iBAAiB;AAEpE,aAAO;AAAA,QACL,OAAO,MAAM,SAAS,SAAS;AAAA,QAC/B,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,aAAa,cAAc;AAAA,UAC3B,iBAAiB,kBAAkB,IAAI,kBAAkB;AAAA,UACzD,qBAAqB,KAAK,IAAI,GAAG,eAAe,eAAe;AAAA,UAC/D,cAAc,eAAe,IAAI,eAAe;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM;AACjB;;;AClKO,SAAS,8BAA8B,UAAsC;AAClF,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO;AAGtD,MAAI,SAAS,SAAS,aAAc,aAAa,YAAY,WAAW,UAAW;AACjF,UAAM,WAAW,SAAS,SAAS,CAAC;AACpC,UAAM,QAAQ,SAAS,SAAS;AAEhC,UAAM,cAAc,SAAS,gBAAgB;AAC7C,UAAM,eAAe,SAAS,iBAAiB;AAC/C,UAAM,eAAe,SAAS,2BAA2B;AACzD,UAAM,mBAAmB,SAAS,+BAA+B;AAGjE,QAAI,kBAAsC;AAC1C,QAAI,MAAM,QAAQ,SAAS,OAAO,GAAG;AACnC,YAAM,iBAAiB,SAAS,QAAQ,OAAO,CAAC,MAAW,EAAE,SAAS,UAAU;AAChF,UAAI,eAAe,SAAS,GAAG;AAE7B,0BAAmB,SAAiB,mBAAmB;AAAA,MACzD;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,aAAa,cAAc;AAAA,QAC3B;AAAA,QACA,qBACE,oBAAoB,SAAY,KAAK,IAAI,GAAG,eAAe,eAAe,IAAI;AAAA,QAChF,cAAc,eAAe,IAAI,eAAe;AAAA,QAChD,kBAAkB,mBAAmB,IAAI,mBAAmB;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,IAAM,6BAAN,MAAiC;AAAA,EAC9B,QAAgB;AAAA,EAChB,cAAsB;AAAA,EACtB,eAAuB;AAAA,EACvB,eAAuB;AAAA,EACvB,mBAA2B;AAAA,EAC3B,kBAA0B;AAAA,EAElC,aAAa,OAAkB;AAC7B,QAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AAGzC,QAAI,MAAM,SAAS,mBAAmB,MAAM,SAAS;AACnD,UAAI,MAAM,QAAQ,OAAO;AACvB,aAAK,QAAQ,MAAM,QAAQ;AAAA,MAC7B;AACA,UAAI,MAAM,QAAQ,OAAO;AACvB,aAAK,cAAc,MAAM,QAAQ,MAAM,gBAAgB;AACvD,aAAK,eAAe,MAAM,QAAQ,MAAM,2BAA2B;AACnE,aAAK,mBAAmB,MAAM,QAAQ,MAAM,+BAA+B;AAAA,MAC7E;AAAA,IACF;AAGA,QAAI,MAAM,SAAS,mBAAmB,MAAM,OAAO;AACjD,WAAK,eAAe,MAAM,MAAM,iBAAiB;AACjD,UAAI,MAAM,MAAM,iBAAiB;AAC/B,aAAK,kBAAkB,MAAM,MAAM;AAAA,MACrC;AAAA,IACF;AAGA,QAAI,MAAM,SAAS,yBAAyB,MAAM,eAAe,SAAS,YAAY;AAAA,IAEtF;AAAA,EACF;AAAA,EAEA,WAA2B;AACzB,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,OAAO;AAAA,QACL,aAAa,KAAK;AAAA,QAClB,cAAc,KAAK;AAAA,QACnB,aAAa,KAAK,cAAc,KAAK;AAAA,QACrC,iBAAiB,KAAK,kBAAkB,IAAI,KAAK,kBAAkB;AAAA,QACnE,qBACE,KAAK,kBAAkB,IACnB,KAAK,IAAI,GAAG,KAAK,eAAe,KAAK,eAAe,IACpD,KAAK;AAAA,QACX,cAAc,KAAK,eAAe,IAAI,KAAK,eAAe;AAAA,QAC1D,kBAAkB,KAAK,mBAAmB,IAAI,KAAK,mBAAmB;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AACF;;;ACpGO,SAAS,2BACd,UACA,gBAAwB,oBACD;AACvB,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO;AAGtD,QAAM,gBAAgB,SAAS,iBAAiB,SAAS,UAAU;AAEnE,MAAI,eAAe;AACjB,UAAM,cAAc,cAAc,oBAAoB;AACtD,UAAM,mBAAmB,cAAc,wBAAwB;AAC/D,UAAM,qBACJ,cAAc,sBAAuB,cAAsB,uBAAuB;AACpF,UAAM,eAAe,cAAc,2BAA2B;AAE9D,UAAM,cAAc,mBAAmB;AACvC,UAAM,QAAQ,SAAS,SAAS,SAAS,UAAU,SAAS;AAE5D,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,OAAO;AAAA,QACL;AAAA,QACA,cAAc;AAAA,QACd,aAAa,cAAc;AAAA,QAC3B,iBAAiB,qBAAqB,IAAI,qBAAqB;AAAA,QAC/D,qBAAqB;AAAA,QACrB,cAAc,eAAe,IAAI,eAAe;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AClCO,SAAS,4BACd,UACA,gBAAwB,eACxB,mBAA2B,WACJ;AACvB,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO;AAGtD,QAAM,QAAQ,SAAS,SAAS,SAAS,eAAe,SAAS;AAEjE,MAAI,OAAO;AACT,UAAM,cACJ,MAAM,iBACN,MAAM,gBACN,MAAM,oBACN,MAAM,qBACN;AACF,UAAM,eACJ,MAAM,qBACN,MAAM,iBACN,MAAM,wBACN,MAAM,cACN;AACF,UAAM,kBACJ,MAAM,oBACN,MAAM,sBACN,MAAM,2BAA2B,oBACjC;AACF,UAAM,eACJ,MAAM,uBAAuB,iBAC7B,MAAM,iBACN,MAAM,2BACN;AAEF,UAAM,QAAQ,SAAS,SAAS;AAChC,UAAM,WAAW,SAAS,YAAY;AAEtC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,aAAa,cAAc;AAAA,QAC3B,iBAAiB,kBAAkB,IAAI,kBAAkB;AAAA,QACzD,qBAAqB,KAAK,IAAI,GAAG,eAAe,eAAe;AAAA,QAC/D,cAAc,eAAe,IAAI,eAAe;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC5CO,SAAS,sBACd,UACA,eACA,kBACuB;AACvB,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU,QAAO;AAGtD,QAAM,eAAe,2BAA2B,QAAQ;AACxD,MAAI,aAAc,QAAO;AAGzB,QAAM,kBAAkB,8BAA8B,QAAQ;AAC9D,MAAI,gBAAiB,QAAO;AAG5B,QAAM,eAAe,2BAA2B,UAAU,aAAa;AACvE,MAAI,aAAc,QAAO;AAGzB,QAAM,gBAAgB,4BAA4B,UAAU,eAAe,gBAAgB;AAC3F,MAAI,cAAe,QAAO;AAE1B,SAAO;AACT;;;AChCO,IAAM,sBAAyD;AAAA;AAAA,EAEpE,eAAe,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EAC3E,iBAAiB,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EAC7E,gBAAgB,EAAE,YAAY,KAAK,aAAa,KAAK,kBAAkB,KAAK;AAAA,EAC5E,SAAS,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EACrE,cAAc,EAAE,YAAY,KAAK,aAAa,KAAK,kBAAkB,KAAK;AAAA,EAC1E,MAAM,EAAE,YAAY,IAAM,aAAa,IAAM,kBAAkB,IAAI;AAAA,EACnE,WAAW,EAAE,YAAY,KAAK,aAAa,KAAK,kBAAkB,KAAK;AAAA,EACvE,MAAM,EAAE,YAAY,IAAM,aAAa,IAAM,kBAAkB,IAAI;AAAA,EACnE,WAAW,EAAE,YAAY,KAAK,aAAa,KAAK,kBAAkB,KAAK;AAAA,EACvE,UAAU,EAAE,YAAY,KAAK,aAAa,IAAM,kBAAkB,KAAK;AAAA,EACvE,eAAe,EAAE,YAAY,MAAM,aAAa,KAAK,kBAAkB,MAAM;AAAA,EAC7E,WAAW,EAAE,YAAY,IAAM,aAAa,KAAO,kBAAkB,KAAK;AAAA,EAC1E,mBAAmB,EAAE,YAAY,IAAM,aAAa,KAAO,kBAAkB,KAAK;AAAA,EAClF,qBAAqB,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EAC1D,WAAW,EAAE,YAAY,GAAK,aAAa,GAAK,kBAAkB,EAAI;AAAA,EACtE,gBAAgB,EAAE,YAAY,KAAK,aAAa,KAAK,kBAAkB,KAAK;AAAA;AAAA,EAG5E,eAAe,EAAE,YAAY,IAAM,aAAa,IAAM,kBAAkB,EAAI;AAAA,EAC5E,uBAAuB,EAAE,YAAY,IAAM,aAAa,IAAM,kBAAkB,EAAI;AAAA,EACpF,SAAS,EAAE,YAAY,IAAM,aAAa,GAAK;AAAA,EAC/C,aAAa,EAAE,YAAY,IAAM,aAAa,IAAM;AAAA,EACpD,iBAAiB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EACrD,qBAAqB,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EACzD,0BAA0B,EAAE,YAAY,MAAM,aAAa,EAAI;AAAA,EAC/D,0BAA0B,EAAE,YAAY,MAAM,aAAa,EAAI;AAAA,EAC/D,0BAA0B,EAAE,YAAY,KAAM,aAAa,EAAI;AAAA;AAAA,EAG/D,qBAAqB,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,IAAI;AAAA,EAClF,mBAAmB,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EAC/E,qBAAqB,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EACjF,oBAAoB,EAAE,YAAY,KAAK,aAAa,GAAK,kBAAkB,KAAK;AAAA,EAChF,aAAa,EAAE,YAAY,GAAK,aAAa,GAAK,kBAAkB,IAAI;AAAA,EACxE,iBAAiB,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EAC7E,iBAAiB,EAAE,YAAY,IAAM,aAAa,IAAM,kBAAkB,IAAI;AAAA;AAAA,EAG9E,mBAAmB,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EAC/E,kBAAkB,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,MAAM;AAAA,EACjF,cAAc,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EACnD,cAAc,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EACnD,sBAAsB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA;AAAA,EAG5D,oBAAoB,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,KAAK;AAAA,EAClF,kBAAkB,EAAE,YAAY,GAAK,aAAa,IAAM,kBAAkB,IAAI;AAAA,EAC9E,oBAAoB,EAAE,YAAY,KAAK,aAAa,GAAK,kBAAkB,KAAK;AAAA,EAChF,yBAAyB,EAAE,YAAY,MAAM,aAAa,KAAK,kBAAkB,KAAK;AAAA,EACtF,kBAAkB,EAAE,YAAY,MAAM,aAAa,GAAK,kBAAkB,OAAO;AAAA,EACjF,oBAAoB,EAAE,YAAY,MAAM,aAAa,KAAK,kBAAkB,OAAO;AAAA,EACnF,oBAAoB,EAAE,YAAY,KAAK,aAAa,KAAK,kBAAkB,MAAM;AAAA,EACjF,yBAAyB,EAAE,YAAY,OAAO,aAAa,KAAK,kBAAkB,QAAQ;AAAA,EAC1F,kBAAkB,EAAE,YAAY,MAAM,aAAa,GAAK,kBAAkB,OAAO;AAAA;AAAA,EAGjF,kBAAkB,EAAE,YAAY,MAAM,aAAa,GAAK,kBAAkB,OAAO;AAAA,EACjF,oBAAoB,EAAE,YAAY,OAAO,aAAa,KAAK,kBAAkB,QAAQ;AAAA,EACrF,uBAAuB,EAAE,YAAY,QAAQ,aAAa,MAAM,kBAAkB,QAAS;AAAA,EAC3F,kBAAkB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA;AAAA,EAGtD,YAAY,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EACjD,UAAU,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EAC/C,eAAe,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EACnD,UAAU,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EAC/C,iBAAiB,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EACtD,aAAa,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA;AAAA,EAGlD,mBAAmB,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EACvD,wBAAwB,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EAC5D,sBAAsB,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EAC1D,oBAAoB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EACxD,yBAAyB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EAC7D,wBAAwB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EAC5D,uBAAuB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EAC3D,uBAAuB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EAC7D,mBAAmB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EACvD,qBAAqB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EACzD,sBAAsB,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA;AAAA,EAG1D,2BAA2B,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EACjE,kBAAkB,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EACtD,2BAA2B,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EACjE,wBAAwB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EAC9D,wBAAwB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EAC9D,wBAAwB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EAC9D,wBAAwB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EAC9D,wBAAwB,EAAE,YAAY,KAAM,aAAa,IAAK;AAAA,EAC9D,iCAAiC,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EACvE,gCAAgC,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EACtE,gBAAgB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EACtD,gBAAgB,EAAE,YAAY,MAAM,aAAa,IAAK;AAAA,EACtD,sBAAsB,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EAC5D,gBAAgB,EAAE,YAAY,KAAM,aAAa,IAAK;AAAA;AAAA,EAGtD,mBAAmB,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,KAAK;AAAA,EACjF,qBAAqB,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,KAAK;AAAA,EACnF,eAAe,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,MAAM;AAAA,EAC9E,iBAAiB,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,MAAM;AAAA,EAChF,eAAe,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,KAAK;AAAA,EAC7E,qBAAqB,EAAE,YAAY,MAAM,aAAa,MAAM,kBAAkB,KAAK;AAAA;AAAA,EAGnF,kBAAkB,EAAE,YAAY,KAAK,aAAa,GAAK;AAAA,EACvD,aAAa,EAAE,YAAY,MAAM,aAAa,IAAI;AAAA,EAClD,WAAW,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EAC/C,iBAAiB,EAAE,YAAY,KAAK,aAAa,IAAI;AAAA,EACrD,sBAAsB,EAAE,YAAY,KAAM,aAAa,EAAI;AAAA;AAAA,EAG3D,SAAS,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EAC7C,aAAa,EAAE,YAAY,GAAK,aAAa,GAAK;AAAA,EAClD,mBAAmB,EAAE,YAAY,GAAK,aAAa,EAAI;AAAA,EACvD,uBAAuB,EAAE,YAAY,GAAK,aAAa,EAAI;AAC7D;AAKO,IAAM,gBAAwC;AAAA;AAAA,EAEnD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,0BAA0B;AAAA;AAAA,EAG1B,UAAU;AAAA,EACV,cAAc;AAAA,EACd,cAAc;AAAA,EACd,SAAS;AAAA,EACT,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,kBAAkB;AAAA;AAAA,EAGlB,MAAM;AAAA,EACN,MAAM;AAAA;AAAA,EAGN,SAAS;AAAA,EACT,OAAO;AAAA;AAAA,EAGP,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,cAAc;AAAA;AAAA,EAGd,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,iBAAiB;AACnB;AAKA,IAAM,wBAA2D,CAAC;AAS3D,SAAS,kBAAkB,UAA0B;AAC1D,MAAI,CAAC,SAAU,QAAO;AAEtB,MAAI,QAAQ,SAAS,YAAY,EAAE,KAAK;AAGxC,UAAQ,MAAM,QAAQ,gEAAgE,EAAE;AACxF,UAAQ,MAAM,QAAQ,mDAAmD,EAAE;AAG3E,UAAQ,MAAM,QAAQ,iBAAiB,EAAE;AACzC,UAAQ,MAAM,QAAQ,SAAS,EAAE;AAGjC,MAAI,MAAM,SAAS,GAAG,GAAG;AACvB,YAAQ,MAAM,MAAM,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,EAC5C;AAGA,UAAQ,MAAM,QAAQ,wBAAwB,EAAE;AAGhD,UAAQ,MAAM,QAAQ,WAAW,EAAE;AACnC,UAAQ,MAAM,QAAQ,uBAAuB,EAAE;AAG/C,UAAQ,MAAM,QAAQ,sBAAsB,cAAc;AAC1D,UAAQ,MAAM,QAAQ,uBAAuB,cAAc;AAG3D,MAAI,cAAc,KAAK,GAAG;AACxB,WAAO,cAAc,KAAK;AAAA,EAC5B;AAGA,MAAI,CAAC,oBAAoB,KAAK,GAAG;AAC/B,UAAM,kBAAkB,MAAM,QAAQ,6BAA6B,EAAE;AACrE,QAAI,oBAAoB,eAAe,GAAG;AACxC,aAAO;AAAA,IACT;AACA,QAAI,cAAc,eAAe,GAAG;AAClC,aAAO,cAAc,eAAe;AAAA,IACtC;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,gBAAgB,WAAsC;AACpE,QAAM,aAAa,kBAAkB,SAAS;AAG9C,MAAI,sBAAsB,UAAU,GAAG;AACrC,WAAO,sBAAsB,UAAU;AAAA,EACzC;AACA,MAAI,sBAAsB,SAAS,GAAG;AACpC,WAAO,sBAAsB,SAAS;AAAA,EACxC;AAGA,MAAI,oBAAoB,UAAU,GAAG;AACnC,WAAO,oBAAoB,UAAU;AAAA,EACvC;AAEA,MAAI,oBAAoB,SAAS,GAAG;AAClC,WAAO,oBAAoB,SAAS;AAAA,EACtC;AAGA,QAAM,QAAQ,cAAc,UAAU,YAAY,EAAE,KAAK,CAAC;AAC1D,MAAI,SAAS,oBAAoB,KAAK,GAAG;AACvC,WAAO,oBAAoB,KAAK;AAAA,EAClC;AAGA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,kBAAkB;AAAA,EACpB;AACF;;;ACxPO,SAAS,cAAc,QAA4C;AACxE,MAAI;AAEJ,MAAI,OAAO,YAAY;AACrB,UAAM,UAAU,OAAO,WAAW,OAAO,OAAO,WAAW,UAAU;AACrE,YAAQ;AAAA,MACN,YAAY,OAAO,WAAW;AAAA,MAC9B,aAAa;AAAA,MACb,gBAAgB,OAAO,WAAW,aAAa;AAAA,MAC/C,kBAAkB,OAAO,WAAW,UAAU,OAAO,WAAW,KAAK;AAAA,MACrE,UAAU;AAAA,IACZ;AAAA,EACF,OAAO;AACL,YAAQ,gBAAgB,OAAO,KAAK;AAAA,EACtC;AAEA,QAAM,cAAc,OAAO,KAAK,IAAI,GAAG,OAAO,eAAe,CAAC,CAAC;AAC/D,QAAM,eAAe,OAAO,KAAK,IAAI,GAAG,OAAO,gBAAgB,CAAC,CAAC;AACjE,QAAM,kBAAkB,OAAO,KAAK,IAAI,GAAG,OAAO,mBAAmB,CAAC,CAAC;AACvE,QAAM,eAAe,OAAO,KAAK,IAAI,GAAG,OAAO,gBAAgB,CAAC,CAAC;AAGjE,QAAM,qBAAqB,cAAc,eAAe,cAAc,eAAe;AAIrF,QAAM,gBAAgB,OAAO,KAAK,MAAM,MAAM,aAAa,GAAK,CAAC;AACjE,QAAM,cAAc,MAAM,oBAAoB,MAAM,aAAa;AACjE,QAAM,iBAAiB,OAAO,KAAK,MAAM,cAAc,GAAK,CAAC;AAC7D,QAAM,iBAAiB,OAAO,KAAK,MAAM,MAAM,cAAc,GAAK,CAAC;AACnE,QAAM,iBAAiB,MAAM,kBAAkB,MAAM;AACrD,QAAM,oBAAoB,OAAO,KAAK,MAAM,iBAAiB,GAAK,CAAC;AAGnE,QAAM,uBAAuB,qBAAqB;AAClD,QAAM,sBAAsB,eAAe;AAC3C,QAAM,gBAAgB,uBAAuB;AAC7C,QAAM,iBAAiB,eAAe;AACtC,QAAM,oBAAoB,kBAAkB;AAG5C,QAAM,wBAAwB,eAAe;AAC7C,QAAM,qBACJ,wBAAwB,sBAAsB,wBAAwB,sBAAsB;AAG9F,QAAM,gBAAgB,gBAAgB;AAGtC,QAAM,SAAS,OAAO,oBAAoB;AAC1C,MAAI,aAAa;AACjB,MAAI,YAAY;AAEhB,MAAI,WAAW,KAAO,OAAO,qBAAqB,QAAW;AAC3D,gBAAY;AACZ,UAAM,uBAAuB,OAAO,KAAK,MAAM,SAAS,GAAK,CAAC;AAC9D,iBAAc,gBAAgB,uBAAwB;AAEtD,QAAI,OAAO,qBAAqB,UAAa,OAAO,mBAAmB,GAAG;AACxE,YAAM,gBAAgB,OAAO,KAAK,MAAM,OAAO,mBAAmB,GAAa,CAAC;AAChF,UAAI,aAAa,eAAe;AAC9B,qBAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,OAAO,aAAa,IAAI;AAC7C,QAAM,gBAAgB,OAAO,cAAc,IAAI;AAC/C,QAAM,mBAAmB,OAAO,iBAAiB,IAAI;AACrD,QAAM,oBAAoB,OAAO,kBAAkB,IAAI;AACvD,QAAM,WAAW,OAAO,aAAa,IAAI;AACzC,QAAM,oBAAoB;AAC1B,QAAM,YAAY,OAAO,UAAU,IAAI;AACvC,QAAM,YAAY,KAAK,IAAI,GAAG,YAAY,iBAAiB;AAC3D,QAAM,YAAY,YAAY,YAAY;AAE1C,SAAO;AAAA,IACL,cAAc,OAAO,aAAa,QAAQ,CAAC,CAAC;AAAA,IAC5C,eAAe,OAAO,cAAc,QAAQ,CAAC,CAAC;AAAA,IAC9C,kBAAkB,kBAAkB,KAAK,OAAO,iBAAiB,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC/E,mBAAmB,eAAe,KAAK,OAAO,kBAAkB,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC9E,UAAU,OAAO,SAAS,QAAQ,CAAC,CAAC;AAAA,IACpC,mBAAmB,OAAO,kBAAkB,QAAQ,CAAC,CAAC;AAAA,IACtD,WAAW,OAAO,UAAU,QAAQ,CAAC,CAAC;AAAA,IACtC,WAAW,OAAO,UAAU,QAAQ,CAAC,CAAC;AAAA,IACtC,WAAW,cAAc,SAAY,OAAO,UAAU,QAAQ,CAAC,CAAC,IAAI;AAAA,IACpE,UAAU,MAAM,YAAY;AAAA,EAC9B;AACF;AAKO,SAAS,mBACd,OACA,OACA,iBACe;AACf,QAAM,UACJ,OAAO,oBAAoB,WACvB,EAAE,kBAAkB,gBAAgB,IACpC,mBAAmB,CAAC;AAE1B,SAAO,cAAc;AAAA,IACnB;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,cAAc,MAAM;AAAA,IACpB,iBAAiB,MAAM;AAAA,IACvB,cAAc,MAAM;AAAA,IACpB,kBAAkB,MAAM;AAAA,IACxB,kBAAkB,QAAQ;AAAA,IAC1B,kBAAkB,QAAQ;AAAA,IAC1B,YAAY,QAAQ;AAAA,EACtB,CAAC;AACH;;;AC3HO,SAAS,kBAAkB,UAA0B,iBAA8C;AACxG,MAAI,CAAC,YAAY,CAAC,iBAAiB;AACjC,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,aAAa;AAAA,MACb,kBAAkB,CAAC;AAAA,IACrB;AAAA,EACF;AAEA,MAAI,OAAO,aAAa,UAAU;AAChC,UAAM,UAAU,SAAS,SAAS,GAAG;AACrC,UAAMC,eAA4B;AAAA,MAChC,IAAI;AAAA,MACJ,OAAO,UAAU,WAAW;AAAA,IAC9B;AACA,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,eAAe,UAAU,WAAW;AAAA,MACpC,aAAAA;AAAA,MACA,kBAAkB,CAAC;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,cAAc,aAAa,kBAAkB,EAAE,IAAI,gBAAgB,IAAI;AAC7E,QAAM,aAAa,aAAa,MAAM,aAAa,UAAU;AAC7D,QAAM,gBAAgB,aAAa;AAEnC,QAAM,mBAA8D,CAAC;AAErE,MAAI,aAAa;AACf,UAAM,QAAQ,YAAY,SAAS,YAAY;AAC/C,QAAI,MAAO,kBAAiB,SAAS,OAAO,KAAK;AAEjD,UAAM,SAAS,YAAY,UAAU,YAAY;AACjD,QAAI,OAAQ,kBAAiB,UAAU,OAAO,MAAM;AAEpD,QAAI,YAAY,KAAM,kBAAiB,OAAO,OAAO,YAAY,IAAI;AACrE,QAAI,YAAY,KAAM,kBAAiB,OAAO,OAAO,YAAY,IAAI;AACrE,QAAI,YAAY,KAAM,kBAAiB,OAAO,OAAO,YAAY,IAAI;AACrE,QAAI,YAAY,QAAS,kBAAiB,WAAW,OAAO,YAAY,OAAO;AAE/E,QAAI,YAAY,UAAU;AACxB,iBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,YAAY,QAAQ,GAAG;AAC7D,YAAI,QAAQ,QAAQ,QAAQ,QAAW;AACrC,2BAAiB,GAAG,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACzDO,SAAS,iBACd,QACA,SACA,YACG;AACH,MAAI,gBAAgB,QAAQ,SAAS;AACrC,MAAI,aAAkB;AAEtB,QAAM,uBAAuB;AAAA,IAC3B,QAAQ,OAAO,aAAa,IAAI;AAC9B,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAChC,gBAAM,YAAY,yBAAyB,KAAK;AAChD,cAAI,UAAU,OAAO;AACnB,4BAAgB,UAAU;AAAA,UAC5B;AACA,cAAI,UAAU,OAAO;AACnB,yBAAa,UAAU;AAAA,UACzB;AACA,gBAAM;AAAA,QACR;AAAA,MACF,UAAE;AACA,YAAI,YAAY;AACd,gBAAM,OAAO,mBAAmB,eAAe,UAAU;AACzD,gBAAM,aAAa,kBAAkB,QAAQ,UAAU,QAAQ,UAAU;AAEzE,gBAAM,QAAoB;AAAA,YACxB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YAClC,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAO;AAAA,YACP;AAAA,YACA,YAAY,WAAW;AAAA,YACvB,eAAe,WAAW;AAAA,YAC1B,UAAU,WAAW;AAAA,YACrB,UAAU;AAAA,cACR,GAAG,WAAW;AAAA,cACd,GAAG,QAAQ;AAAA,YACb;AAAA,UACF;AAEA,qBAAW,KAAK;AAChB,cAAI,QAAQ,SAAS;AACnB,oBAAQ,QAAQ,KAAK;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,oBACd,QACA,SACA,YACG;AACH,QAAM,cAAc,IAAI,2BAA2B;AAEnD,QAAM,uBAAuB;AAAA,IAC3B,QAAQ,OAAO,aAAa,IAAI;AAC9B,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAChC,sBAAY,aAAa,KAAK;AAC9B,gBAAM;AAAA,QACR;AAAA,MACF,UAAE;AACA,cAAM,YAAY,YAAY,SAAS;AACvC,cAAM,QAAQ,QAAQ,SAAS,UAAU;AACzC,cAAM,OAAO,mBAAmB,OAAO,UAAU,KAAK;AACtD,cAAM,aAAa,kBAAkB,QAAQ,UAAU,QAAQ,UAAU;AAEzE,cAAM,aAAyB;AAAA,UAC7B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UAClC;AAAA,UACA,UAAU;AAAA,UACV,OAAO,UAAU;AAAA,UACjB;AAAA,UACA,YAAY,WAAW;AAAA,UACvB,eAAe,WAAW;AAAA,UAC1B,UAAU,WAAW;AAAA,UACrB,UAAU;AAAA,YACR,GAAG,WAAW;AAAA,YACd,GAAG,QAAQ;AAAA,UACb;AAAA,QACF;AAEA,mBAAW,UAAU;AACrB,YAAI,QAAQ,SAAS;AACnB,kBAAQ,QAAQ,UAAU;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,iBACd,QACA,SACA,YACK;AACL,MAAI,CAAC,UAAU,CAAC,OAAO,OAAQ,QAAO;AAEtC,QAAM,iBAAiB,OAAO;AAC9B,QAAM,QAAQ,QAAQ,SAAS;AAC/B,MAAI,qBAA0B;AAE9B,QAAM,iBAAiB,mBAAmB;AACxC,QAAI;AACF,uBAAiB,SAAS,gBAAgB;AACxC,YAAI,MAAM,eAAe;AACvB,+BAAqB;AAAA,QACvB;AACA,cAAM;AAAA,MACR;AAAA,IACF,UAAE;AACA,UAAI,oBAAoB;AACtB,cAAM,YAAY,2BAA2B,oBAAoB,KAAK;AACtE,YAAI,WAAW;AACb,gBAAM,OAAO,mBAAmB,UAAU,OAAO,UAAU,KAAK;AAChE,gBAAM,aAAa,kBAAkB,QAAQ,UAAU,QAAQ,UAAU;AAEzE,gBAAM,QAAoB;AAAA,YACxB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,YAClC,OAAO,UAAU;AAAA,YACjB,UAAU;AAAA,YACV,OAAO,UAAU;AAAA,YACjB;AAAA,YACA,YAAY,WAAW;AAAA,YACvB,eAAe,WAAW;AAAA,YAC1B,UAAU,WAAW;AAAA,YACrB,UAAU;AAAA,cACR,GAAG,WAAW;AAAA,cACd,GAAG,QAAQ;AAAA,YACb;AAAA,UACF;AAEA,qBAAW,KAAK;AAChB,cAAI,QAAQ,SAAS;AACnB,oBAAQ,QAAQ,KAAK;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG;AAEH,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ;AAAA,EACV;AACF;AAKO,SAAS,oBACd,QACA,UAA6B,CAAC,GAC9B,YACG;AACH,MAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAGlD,MAAI,YAAY,UAAU,cAAc,QAAQ;AAC9C,WAAO,iBAAiB,QAAQ,SAAS,UAAU;AAAA,EACrD;AAGA,MAAI,OAAO,iBAAiB,QAAQ;AAElC,QAAI,QAAQ,aAAa,eAAe,QAAQ,OAAO,YAAY,EAAE,SAAS,QAAQ,GAAG;AACvF,aAAO,oBAAoB,QAAe,SAAS,UAAU;AAAA,IAC/D;AAEA,WAAO,iBAAiB,QAAe,SAAS,UAAU;AAAA,EAC5D;AAEA,SAAO;AACT;;;AVxLO,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,UAAwB,CAAC,GAAG;AACtC,SAAK,mBAAmB,QAAQ;AAGhC,QAAI,QAAQ,QAAQ;AAClB,WAAK,eAAe,QAAQ;AAAA,IAC9B,WAAW,QAAQ,UAAU,QAAQ,IAAI,mBAAmB;AAC1D,YAAM,MAAM,QAAQ,UAAU,QAAQ,IAAI;AAC1C,WAAK,eAAe,IAAI,OAAO,KAAK;AAAA,QAClC,SAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,UACT,KAAK;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH;AAEA,SAAK,UAAU,IAAI,aAAa;AAAA,MAC9B,GAAG;AAAA,MACH,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKO,WACL,UACA,UAMI,CAAC,GACc;AACnB,UAAM,YAAY,sBAAsB,UAAU,QAAQ,OAAO,QAAQ,QAAQ;AACjF,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,QAAQ,SAAS,UAAU;AACzC,UAAM,OAAO,mBAAmB,OAAO,UAAU,OAAO,KAAK,gBAAgB;AAC7E,UAAM,aAAa,kBAAkB,QAAQ,UAAU,QAAQ,UAAU;AAEzE,UAAM,aAAa;AAAA,MACjB,GAAG,WAAW;AAAA,MACd,GAAG,QAAQ;AAAA,IACb;AAEA,UAAM,QAAoB;AAAA,MACxB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,MACA,UAAU,UAAU;AAAA,MACpB,OAAO,UAAU;AAAA,MACjB;AAAA,MACA,YAAY,WAAW;AAAA,MACvB,eAAe,WAAW;AAAA,MAC1B,UAAU,WAAW;AAAA,MACrB,UAAU;AAAA,IACZ;AAEA,SAAK,QAAQ,QAAQ,KAAK;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,WAAc,QAAW,UAA6B,CAAC,GAAM;AAClE,WAAO,oBAAoB,QAAQ,SAAS,CAAC,UAAU;AACrD,WAAK,QAAQ,QAAQ,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKO,YAAY,SAAwE;AACzF,UAAM,cAAc,QAAQ,eAAe;AAC3C,UAAM,eAAe,QAAQ,gBAAgB;AAC7C,UAAM,kBAAkB,QAAQ;AAChC,UAAM,eAAe,QAAQ;AAE7B,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA,aAAa,cAAc;AAAA,MAC3B;AAAA,MACA,qBACE,oBAAoB,SAAY,KAAK,IAAI,GAAG,eAAe,eAAe,IAAI;AAAA,MAChF;AAAA,IACF;AAEA,UAAM,OAAO,mBAAmB,QAAQ,OAAO,OAAO,KAAK,gBAAgB;AAC3E,UAAM,aAAa,kBAAkB,QAAQ,UAAU,QAAQ,UAAU;AAEzE,UAAM,aAAa;AAAA,MACjB,GAAG,WAAW;AAAA,MACd,GAAG,QAAQ;AAAA,IACb;AAEA,UAAM,QAAoB;AAAA,MACxB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,OAAO,QAAQ;AAAA,MACf,UAAU,QAAQ,YAAY;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,YAAY,WAAW;AAAA,MACvB,eAAe,WAAW;AAAA,MAC1B,UAAU,WAAW;AAAA,MACrB,UAAU;AAAA,IACZ;AAEA,SAAK,QAAQ,QAAQ,KAAK;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAuB;AAClC,UAAM,KAAK,QAAQ,MAAM;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKO,kBAAgC;AACrC,WAAO,KAAK,QAAQ,WAAW;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKO,eAAqB;AAC1B,SAAK,QAAQ,YAAY;AAAA,EAC3B;AACF;;;AWpIO,SAAS,iBACd,cACA,SAA2B,CAAC,GAChB;AACZ,QAAM,SAAS,iBAAiB,OAAO,YAAY,cAAe,QAAQ,KAAK,qBAAqB,QAAQ,KAAK,iBAAkB;AACnI,QAAM,QAAQ,IAAI,WAAW;AAAA,IAC3B;AAAA,IACA,WAAW,OAAO;AAAA,EACpB,CAAC;AAED,QAAM,kBAAkB,CAAC,SAAqC;AAC5D,QAAI,OAAO,SAAS,SAAU,QAAO;AACrC,WAAO,KAAK,cAAc,KAAK,YAAY;AAAA,EAC7C;AAEA,SAAO;AAAA,IACL,WAAW,UAAe,UAAoC;AAC5D,UAAI,CAAC,SAAU;AACf,YAAM,aAAa,gBAAgB,QAAQ;AAC3C,YAAM,WAAW,UAAU,EAAE,UAAU,WAAW,CAAC;AAAA,IACrD;AAAA,IAEA,MAAM,UAAe,UAAoC;AACvD,UAAI,CAAC,SAAU;AACf,YAAM,aAAa,gBAAgB,QAAQ;AAC3C,YAAM,WAAW,UAAU,EAAE,UAAU,WAAW,CAAC;AAAA,IACrD;AAAA,IAEA,uBAA0B,QAAa,UAAiC;AACtE,UAAI,CAAC,UAAU,OAAO,OAAO,OAAO,aAAa,MAAM,YAAY;AACjE,eAAO;AAAA,MACT;AAEA,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,YAAM,mBAAmB,OAAO,OAAO,aAAa,EAAE,KAAK,MAAM;AACjE,UAAI,gBAAqB;AACzB,UAAI,gBAAgB;AAEpB,YAAM,wBAAwB,mBAAmB;AAC/C,YAAI;AACF,2BAAiB,SAAS,iBAAiB,GAAG;AAC5C,gBAAI,MAAM,OAAO;AACf,8BAAgB,MAAM;AAAA,YACxB;AACA,gBAAI,MAAM,SAAS,MAAM,aAAa;AACpC,8BAAgB,MAAM,SAAS,MAAM;AAAA,YACvC;AACA,kBAAM;AAAA,UACR;AAAA,QACF,UAAE;AACA,cAAI,eAAe;AACjB,kBAAM,YAAY;AAAA,cAChB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa,cAAc,iBAAiB,cAAc,eAAe;AAAA,cACzE,cAAc,cAAc,qBAAqB,cAAc,gBAAgB;AAAA,cAC/E,iBACE,cAAc,2BAA2B,oBACzC,cAAc,sBAAsB,oBACpC;AAAA,cACF,cACE,cAAc,uBAAuB,iBACrC,cAAc,qBAAqB,iBACnC;AAAA,cACF,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO,sBAAsB;AAAA,IAC/B;AAAA,IAEA,0BAA6B,QAAa,UAAiC;AACzE,UAAI,CAAC,UAAU,OAAO,OAAO,OAAO,aAAa,MAAM,YAAY;AACjE,eAAO;AAAA,MACT;AAEA,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,YAAM,mBAAmB,OAAO,OAAO,aAAa,EAAE,KAAK,MAAM;AACjE,UAAI,gBAAqB;AACzB,UAAI,gBAAgB;AAEpB,YAAM,wBAAwB,mBAAmB;AAC/C,YAAI;AACF,2BAAiB,SAAS,iBAAiB,GAAG;AAC5C,gBAAI,MAAM,SAAS,mBAAmB,MAAM,SAAS,OAAO;AAC1D,8BAAgB,MAAM,QAAQ;AAC9B,kBAAI,MAAM,QAAQ,OAAO;AACvB,gCAAgB,EAAE,GAAG,eAAe,GAAG,MAAM,QAAQ,MAAM;AAAA,cAC7D;AAAA,YACF,WAAW,MAAM,SAAS,mBAAmB,MAAM,OAAO;AACxD,8BAAgB,EAAE,GAAG,eAAe,GAAG,MAAM,MAAM;AAAA,YACrD;AACA,kBAAM;AAAA,UACR;AAAA,QACF,UAAE;AACA,cAAI,eAAe;AACjB,kBAAM,YAAY;AAAA,cAChB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa,cAAc,gBAAgB;AAAA,cAC3C,cAAc,cAAc,iBAAiB;AAAA,cAC7C,cAAc,cAAc,2BAA2B;AAAA,cACvD,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO,sBAAsB;AAAA,IAC/B;AAAA,IAEA,uBAA0B,cAAmB,UAA8B,YAAoB,oBAAuB;AACpH,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,YAAM,iBAAiB,cAAc,UAAU;AAC/C,UAAI,CAAC,kBAAkB,OAAO,eAAe,OAAO,aAAa,MAAM,YAAY;AACjF,eAAO;AAAA,MACT;AAEA,YAAM,wBAAwB,mBAAmB;AAC/C,YAAI,oBAAyB;AAE7B,YAAI;AACF,2BAAiB,SAAS,gBAAgB;AACxC,gBAAI,MAAM,eAAe;AACvB,kCAAoB,MAAM;AAAA,YAC5B;AACA,kBAAM;AAAA,UACR;AAAA,QACF,UAAE;AACA,cAAI,mBAAmB;AACrB,kBAAM,YAAY;AAAA,cAChB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa,kBAAkB,oBAAoB;AAAA,cACnD,eACG,kBAAkB,wBAAwB,MAC1C,kBAAkB,sBAAsB;AAAA,cAC3C,iBAAiB,kBAAkB,sBAAsB;AAAA,cACzD,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,UAAI,gBAAgB,aAAa,QAAQ;AACvC,eAAO;AAAA,UACL,GAAG;AAAA,UACH,QAAQ,sBAAsB;AAAA,QAChC;AAAA,MACF;AAEA,aAAO,sBAAsB;AAAA,IAC/B;AAAA,IAEA,yBAA4B,QAAa,UAA8B,YAAoB,iBAAoB;AAC7G,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,UAAI,CAAC,UAAU,OAAO,OAAO,OAAO,aAAa,MAAM,YAAY;AACjE,eAAO;AAAA,MACT;AAEA,YAAM,mBAAmB,OAAO,OAAO,aAAa,EAAE,KAAK,MAAM;AACjE,UAAI,gBAAqB;AACzB,UAAI,gBAAgB;AAEpB,YAAM,wBAAwB,mBAAmB;AAC/C,YAAI;AACF,2BAAiB,SAAS,iBAAiB,GAAG;AAC5C,gBAAI,MAAM,MAAO,iBAAgB,MAAM;AACvC,gBAAI,MAAM,MAAO,iBAAgB,MAAM;AACvC,kBAAM;AAAA,UACR;AAAA,QACF,UAAE;AACA,cAAI,eAAe;AACjB,kBAAM,YAAY;AAAA,cAChB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa,cAAc,iBAAiB,cAAc,eAAe;AAAA,cACzE,cAAc,cAAc,qBAAqB,cAAc,gBAAgB;AAAA,cAC/E,iBAAiB,cAAc,2BAA2B,oBAAoB;AAAA,cAC9E,cAAc,cAAc,2BAA2B,cAAc,uBAAuB,iBAAiB;AAAA,cAC7G,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO,sBAAsB;AAAA,IAC/B;AAAA,IAEA,qBAAwB,QAAa,UAA8B,YAAoB,2BAA8B;AACnH,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,UAAI,CAAC,UAAU,OAAO,OAAO,OAAO,aAAa,MAAM,YAAY;AACjE,eAAO;AAAA,MACT;AAEA,YAAM,mBAAmB,OAAO,OAAO,aAAa,EAAE,KAAK,MAAM;AACjE,UAAI,gBAAqB;AACzB,UAAI,gBAAgB;AAEpB,YAAM,wBAAwB,mBAAmB;AAC/C,YAAI;AACF,2BAAiB,SAAS,iBAAiB,GAAG;AAC5C,gBAAI,MAAM,MAAO,iBAAgB,MAAM;AACvC,gBAAI,MAAM,SAAS,MAAM,QAAQ,OAAO;AACtC,8BAAgB,MAAM,SAAS,MAAM,QAAQ;AAAA,YAC/C;AACA,kBAAM;AAAA,UACR;AAAA,QACF,UAAE;AACA,cAAI,eAAe;AACjB,kBAAM,YAAY;AAAA,cAChB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa,cAAc,iBAAiB;AAAA,cAC5C,cAAc,cAAc,qBAAqB;AAAA,cACjD,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO,sBAAsB;AAAA,IAC/B;AAAA,IAEA,wBAA2B,QAAa,UAA8B,YAAoB,wBAA2B;AACnH,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,UAAI,CAAC,UAAU,OAAO,OAAO,OAAO,aAAa,MAAM,YAAY;AACjE,eAAO;AAAA,MACT;AAEA,YAAM,mBAAmB,OAAO,OAAO,aAAa,EAAE,KAAK,MAAM;AACjE,UAAI,gBAAqB;AACzB,UAAI,gBAAgB;AAEpB,YAAM,wBAAwB,mBAAmB;AAC/C,YAAI;AACF,2BAAiB,SAAS,iBAAiB,GAAG;AAC5C,gBAAI,MAAM,MAAO,iBAAgB,MAAM;AACvC,gBAAI,MAAM,MAAO,iBAAgB,MAAM;AACvC,kBAAM;AAAA,UACR;AAAA,QACF,UAAE;AACA,cAAI,eAAe;AACjB,kBAAM,YAAY;AAAA,cAChB,OAAO;AAAA,cACP,UAAU;AAAA,cACV,aAAa,cAAc,iBAAiB;AAAA,cAC5C,cAAc,cAAc,qBAAqB;AAAA,cACjD,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO,sBAAsB;AAAA,IAC/B;AAAA,IAEA,iBAAoB,QAAW,UAA8B,UAAiD,CAAC,GAAM;AACnH,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,aAAO,MAAM,WAAW,QAAQ;AAAA,QAC9B,UAAU;AAAA,QACV,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAO,sBAAQ;","names":["rawUsage","customerObj"]}
@@ -1,5 +1,5 @@
1
1
  import Stripe from 'stripe';
2
- import { d as CustomerInfo, C as CustomerParam } from '../types-Mozk4-Mr.mjs';
2
+ import { d as CustomerInfo, C as CustomerParam } from '../types-6P71CXAD.mjs';
3
3
 
4
4
  interface GetOrCreateCustomerParams {
5
5
  userId?: string;
@@ -1,5 +1,5 @@
1
1
  import Stripe from 'stripe';
2
- import { d as CustomerInfo, C as CustomerParam } from '../types-Mozk4-Mr.js';
2
+ import { d as CustomerInfo, C as CustomerParam } from '../types-6P71CXAD.js';
3
3
 
4
4
  interface GetOrCreateCustomerParams {
5
5
  userId?: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/customers/index.ts","../../src/customers/manager.ts","../../src/customers/cache.ts","../../src/customers/helpers.ts"],"sourcesContent":["export * from './manager';\r\nexport * from './cache';\r\nexport * from './helpers';\r\n","import Stripe from 'stripe';\r\nimport { CustomerCache } from './cache';\r\n\r\nexport interface GetOrCreateCustomerParams {\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n phone?: string;\r\n orgId?: string;\r\n organizationId?: string;\r\n orgName?: string;\r\n teamId?: string;\r\n workspaceId?: string;\r\n role?: string;\r\n plan?: string;\r\n tier?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface CustomerManagerOptions {\r\n apiKey?: string;\r\n stripe?: Stripe;\r\n cacheTtlMs?: number;\r\n}\r\n\r\nexport class CustomerManager {\r\n private stripe: Stripe;\r\n private cache: CustomerCache;\r\n\r\n constructor(options: CustomerManagerOptions = {}) {\r\n if (options.stripe) {\r\n this.stripe = options.stripe;\r\n } else {\r\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\r\n if (!apiKey) {\r\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\r\n }\r\n this.stripe = new Stripe(apiKey);\r\n }\r\n\r\n this.cache = new CustomerCache(options.cacheTtlMs);\r\n }\r\n\r\n /**\r\n * Retrieves existing Stripe Customer or automatically provisions a new one with full metadata\r\n */\r\n public async getOrCreate(\r\n params: GetOrCreateCustomerParams\r\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\r\n const cacheKey = params.userId || params.email;\r\n if (cacheKey) {\r\n const cachedId = this.cache.get(cacheKey);\r\n if (cachedId) {\r\n return {\r\n id: cachedId,\r\n isNew: false,\r\n customer: { id: cachedId } as Stripe.Customer,\r\n };\r\n }\r\n }\r\n\r\n // 1. Search by userId in Stripe metadata\r\n if (params.userId) {\r\n try {\r\n const searchResult = await this.stripe.customers.search({\r\n query: `metadata['vibez_user_id']:'${params.userId}'`,\r\n limit: 1,\r\n });\r\n\r\n if (searchResult.data.length > 0) {\r\n const customer = searchResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.email) this.cache.set(params.email, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n } catch {\r\n // Fallback to email search if search query is unsupported or errors\r\n }\r\n }\r\n\r\n // 2. Search by email if provided\r\n if (params.email) {\r\n const listResult = await this.stripe.customers.list({\r\n email: params.email,\r\n limit: 1,\r\n });\r\n\r\n if (listResult.data.length > 0) {\r\n const customer = listResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.userId) this.cache.set(params.userId, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n }\r\n\r\n // 3. Prepare rich metadata for Stripe Customer\r\n const orgId = params.orgId || params.organizationId;\r\n const teamId = params.teamId || params.workspaceId;\r\n\r\n const stripeMetadata: Record<string, string> = {\r\n vibez_user_id: params.userId || '',\r\n created_by: 'vibezcheck',\r\n };\r\n\r\n if (orgId) stripeMetadata.org_id = String(orgId);\r\n if (params.orgName) stripeMetadata.org_name = String(params.orgName);\r\n if (teamId) stripeMetadata.team_id = String(teamId);\r\n if (params.plan) stripeMetadata.plan = String(params.plan);\r\n if (params.tier) stripeMetadata.tier = String(params.tier);\r\n if (params.role) stripeMetadata.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n stripeMetadata[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n // 4. Create new Customer in Stripe\r\n const newCustomer = await this.stripe.customers.create({\r\n email: params.email,\r\n name: params.name,\r\n phone: params.phone,\r\n metadata: stripeMetadata,\r\n });\r\n\r\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\r\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\r\n if (params.email) this.cache.set(params.email, newCustomer.id);\r\n\r\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\r\n }\r\n\r\n /**\r\n * Updates an existing Stripe Customer's information and metadata\r\n */\r\n public async updateCustomer(\r\n customerId: string,\r\n params: Partial<GetOrCreateCustomerParams>\r\n ): Promise<Stripe.Customer> {\r\n const updatePayload: Stripe.CustomerUpdateParams = {};\r\n\r\n if (params.email) updatePayload.email = params.email;\r\n if (params.name) updatePayload.name = params.name;\r\n if (params.phone) updatePayload.phone = params.phone;\r\n\r\n const metadataToUpdate: Record<string, string> = {};\r\n if (params.userId) metadataToUpdate.vibez_user_id = params.userId;\r\n const orgId = params.orgId || params.organizationId;\r\n if (orgId) metadataToUpdate.org_id = String(orgId);\r\n if (params.orgName) metadataToUpdate.org_name = String(params.orgName);\r\n const teamId = params.teamId || params.workspaceId;\r\n if (teamId) metadataToUpdate.team_id = String(teamId);\r\n if (params.plan) metadataToUpdate.plan = String(params.plan);\r\n if (params.tier) metadataToUpdate.tier = String(params.tier);\r\n if (params.role) metadataToUpdate.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n metadataToUpdate[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n if (Object.keys(metadataToUpdate).length > 0) {\r\n updatePayload.metadata = metadataToUpdate;\r\n }\r\n\r\n return await this.stripe.customers.update(customerId, updatePayload);\r\n }\r\n\r\n /**\r\n * Clears in-memory resolution cache\r\n */\r\n public clearCache(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n\r\n/**\r\n * Factory to create CustomerManager\r\n */\r\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\r\n return new CustomerManager(options);\r\n}\r\n","interface CacheEntry {\n customerId: string;\n expiresAt: number;\n}\n\n/**\n * In-memory Customer Resolution Cache with TTL\n */\nexport class CustomerCache {\n private cache = new Map<string, CacheEntry>();\n private readonly defaultTtlMs: number;\n\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\n // Default TTL: 1 hour\n this.defaultTtlMs = defaultTtlMs;\n }\n\n public get(key: string): string | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.customerId;\n }\n\n public set(key: string, customerId: string, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\n this.cache.set(key, { customerId, expiresAt });\n }\n\n public delete(key: string): void {\n this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n"],"mappings":"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","names":["Stripe","customerObj"]}
1
+ {"version":3,"sources":["../../src/customers/index.ts","../../src/customers/manager.ts","../../src/customers/cache.ts","../../src/customers/helpers.ts"],"sourcesContent":["export * from './manager';\r\nexport * from './cache';\r\nexport * from './helpers';\r\n","import Stripe from 'stripe';\r\nimport { CustomerCache } from './cache';\r\n\r\nexport interface GetOrCreateCustomerParams {\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n phone?: string;\r\n orgId?: string;\r\n organizationId?: string;\r\n orgName?: string;\r\n teamId?: string;\r\n workspaceId?: string;\r\n role?: string;\r\n plan?: string;\r\n tier?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface CustomerManagerOptions {\r\n apiKey?: string;\r\n stripe?: Stripe;\r\n cacheTtlMs?: number;\r\n}\r\n\r\nexport class CustomerManager {\r\n private stripe: Stripe;\r\n private cache: CustomerCache;\r\n\r\n constructor(options: CustomerManagerOptions = {}) {\r\n if (options.stripe) {\r\n this.stripe = options.stripe;\r\n } else {\r\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\r\n if (!apiKey) {\r\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\r\n }\r\n this.stripe = new Stripe(apiKey);\r\n }\r\n\r\n this.cache = new CustomerCache(options.cacheTtlMs);\r\n }\r\n\r\n /**\r\n * Retrieves existing Stripe Customer or automatically provisions a new one with full metadata\r\n */\r\n public async getOrCreate(\r\n params: GetOrCreateCustomerParams\r\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\r\n const cacheKey = params.userId || params.email;\r\n if (cacheKey) {\r\n const cachedId = this.cache.get(cacheKey);\r\n if (cachedId) {\r\n return {\r\n id: cachedId,\r\n isNew: false,\r\n customer: { id: cachedId } as Stripe.Customer,\r\n };\r\n }\r\n }\r\n\r\n // 1. Search by userId in Stripe metadata\r\n if (params.userId) {\r\n try {\r\n const searchResult = await this.stripe.customers.search({\r\n query: `metadata['vibez_user_id']:'${params.userId}'`,\r\n limit: 1,\r\n });\r\n\r\n if (searchResult.data.length > 0) {\r\n const customer = searchResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.email) this.cache.set(params.email, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n } catch {\r\n // Fallback to email search if search query is unsupported or errors\r\n }\r\n }\r\n\r\n // 2. Search by email if provided\r\n if (params.email) {\r\n const listResult = await this.stripe.customers.list({\r\n email: params.email,\r\n limit: 1,\r\n });\r\n\r\n if (listResult.data.length > 0) {\r\n const customer = listResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.userId) this.cache.set(params.userId, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n }\r\n\r\n // 3. Prepare rich metadata for Stripe Customer\r\n const orgId = params.orgId || params.organizationId;\r\n const teamId = params.teamId || params.workspaceId;\r\n\r\n const stripeMetadata: Record<string, string> = {\r\n vibez_user_id: params.userId || '',\r\n created_by: 'vibezcheck',\r\n };\r\n\r\n if (orgId) stripeMetadata.org_id = String(orgId);\r\n if (params.orgName) stripeMetadata.org_name = String(params.orgName);\r\n if (teamId) stripeMetadata.team_id = String(teamId);\r\n if (params.plan) stripeMetadata.plan = String(params.plan);\r\n if (params.tier) stripeMetadata.tier = String(params.tier);\r\n if (params.role) stripeMetadata.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n stripeMetadata[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n // 4. Create new Customer in Stripe\r\n const newCustomer = await this.stripe.customers.create({\r\n email: params.email,\r\n name: params.name,\r\n phone: params.phone,\r\n metadata: stripeMetadata,\r\n });\r\n\r\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\r\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\r\n if (params.email) this.cache.set(params.email, newCustomer.id);\r\n\r\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\r\n }\r\n\r\n /**\r\n * Updates an existing Stripe Customer's information and metadata\r\n */\r\n public async updateCustomer(\r\n customerId: string,\r\n params: Partial<GetOrCreateCustomerParams>\r\n ): Promise<Stripe.Customer> {\r\n const updatePayload: Stripe.CustomerUpdateParams = {};\r\n\r\n if (params.email) updatePayload.email = params.email;\r\n if (params.name) updatePayload.name = params.name;\r\n if (params.phone) updatePayload.phone = params.phone;\r\n\r\n const metadataToUpdate: Record<string, string> = {};\r\n if (params.userId) metadataToUpdate.vibez_user_id = params.userId;\r\n const orgId = params.orgId || params.organizationId;\r\n if (orgId) metadataToUpdate.org_id = String(orgId);\r\n if (params.orgName) metadataToUpdate.org_name = String(params.orgName);\r\n const teamId = params.teamId || params.workspaceId;\r\n if (teamId) metadataToUpdate.team_id = String(teamId);\r\n if (params.plan) metadataToUpdate.plan = String(params.plan);\r\n if (params.tier) metadataToUpdate.tier = String(params.tier);\r\n if (params.role) metadataToUpdate.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n metadataToUpdate[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n if (Object.keys(metadataToUpdate).length > 0) {\r\n updatePayload.metadata = metadataToUpdate;\r\n }\r\n\r\n return await this.stripe.customers.update(customerId, updatePayload);\r\n }\r\n\r\n /**\r\n * Clears in-memory resolution cache\r\n */\r\n public clearCache(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n\r\n/**\r\n * Factory to create CustomerManager\r\n */\r\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\r\n return new CustomerManager(options);\r\n}\r\n","interface CacheEntry {\r\n customerId: string;\r\n expiresAt: number;\r\n}\r\n\r\n/**\r\n * In-memory Customer Resolution Cache with TTL\r\n */\r\nexport class CustomerCache {\r\n private cache = new Map<string, CacheEntry>();\r\n private readonly defaultTtlMs: number;\r\n\r\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\r\n // Default TTL: 1 hour\r\n this.defaultTtlMs = defaultTtlMs;\r\n }\r\n\r\n public get(key: string): string | null {\r\n const entry = this.cache.get(key);\r\n if (!entry) return null;\r\n\r\n if (Date.now() > entry.expiresAt) {\r\n this.cache.delete(key);\r\n return null;\r\n }\r\n\r\n return entry.customerId;\r\n }\r\n\r\n public set(key: string, customerId: string, ttlMs?: number): void {\r\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\r\n this.cache.set(key, { customerId, expiresAt });\r\n }\r\n\r\n public delete(key: string): void {\r\n this.cache.delete(key);\r\n }\r\n\r\n public clear(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n"],"mappings":"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","names":["Stripe","customerObj"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/customers/manager.ts","../../src/customers/cache.ts","../../src/customers/helpers.ts"],"sourcesContent":["import Stripe from 'stripe';\r\nimport { CustomerCache } from './cache';\r\n\r\nexport interface GetOrCreateCustomerParams {\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n phone?: string;\r\n orgId?: string;\r\n organizationId?: string;\r\n orgName?: string;\r\n teamId?: string;\r\n workspaceId?: string;\r\n role?: string;\r\n plan?: string;\r\n tier?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface CustomerManagerOptions {\r\n apiKey?: string;\r\n stripe?: Stripe;\r\n cacheTtlMs?: number;\r\n}\r\n\r\nexport class CustomerManager {\r\n private stripe: Stripe;\r\n private cache: CustomerCache;\r\n\r\n constructor(options: CustomerManagerOptions = {}) {\r\n if (options.stripe) {\r\n this.stripe = options.stripe;\r\n } else {\r\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\r\n if (!apiKey) {\r\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\r\n }\r\n this.stripe = new Stripe(apiKey);\r\n }\r\n\r\n this.cache = new CustomerCache(options.cacheTtlMs);\r\n }\r\n\r\n /**\r\n * Retrieves existing Stripe Customer or automatically provisions a new one with full metadata\r\n */\r\n public async getOrCreate(\r\n params: GetOrCreateCustomerParams\r\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\r\n const cacheKey = params.userId || params.email;\r\n if (cacheKey) {\r\n const cachedId = this.cache.get(cacheKey);\r\n if (cachedId) {\r\n return {\r\n id: cachedId,\r\n isNew: false,\r\n customer: { id: cachedId } as Stripe.Customer,\r\n };\r\n }\r\n }\r\n\r\n // 1. Search by userId in Stripe metadata\r\n if (params.userId) {\r\n try {\r\n const searchResult = await this.stripe.customers.search({\r\n query: `metadata['vibez_user_id']:'${params.userId}'`,\r\n limit: 1,\r\n });\r\n\r\n if (searchResult.data.length > 0) {\r\n const customer = searchResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.email) this.cache.set(params.email, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n } catch {\r\n // Fallback to email search if search query is unsupported or errors\r\n }\r\n }\r\n\r\n // 2. Search by email if provided\r\n if (params.email) {\r\n const listResult = await this.stripe.customers.list({\r\n email: params.email,\r\n limit: 1,\r\n });\r\n\r\n if (listResult.data.length > 0) {\r\n const customer = listResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.userId) this.cache.set(params.userId, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n }\r\n\r\n // 3. Prepare rich metadata for Stripe Customer\r\n const orgId = params.orgId || params.organizationId;\r\n const teamId = params.teamId || params.workspaceId;\r\n\r\n const stripeMetadata: Record<string, string> = {\r\n vibez_user_id: params.userId || '',\r\n created_by: 'vibezcheck',\r\n };\r\n\r\n if (orgId) stripeMetadata.org_id = String(orgId);\r\n if (params.orgName) stripeMetadata.org_name = String(params.orgName);\r\n if (teamId) stripeMetadata.team_id = String(teamId);\r\n if (params.plan) stripeMetadata.plan = String(params.plan);\r\n if (params.tier) stripeMetadata.tier = String(params.tier);\r\n if (params.role) stripeMetadata.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n stripeMetadata[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n // 4. Create new Customer in Stripe\r\n const newCustomer = await this.stripe.customers.create({\r\n email: params.email,\r\n name: params.name,\r\n phone: params.phone,\r\n metadata: stripeMetadata,\r\n });\r\n\r\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\r\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\r\n if (params.email) this.cache.set(params.email, newCustomer.id);\r\n\r\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\r\n }\r\n\r\n /**\r\n * Updates an existing Stripe Customer's information and metadata\r\n */\r\n public async updateCustomer(\r\n customerId: string,\r\n params: Partial<GetOrCreateCustomerParams>\r\n ): Promise<Stripe.Customer> {\r\n const updatePayload: Stripe.CustomerUpdateParams = {};\r\n\r\n if (params.email) updatePayload.email = params.email;\r\n if (params.name) updatePayload.name = params.name;\r\n if (params.phone) updatePayload.phone = params.phone;\r\n\r\n const metadataToUpdate: Record<string, string> = {};\r\n if (params.userId) metadataToUpdate.vibez_user_id = params.userId;\r\n const orgId = params.orgId || params.organizationId;\r\n if (orgId) metadataToUpdate.org_id = String(orgId);\r\n if (params.orgName) metadataToUpdate.org_name = String(params.orgName);\r\n const teamId = params.teamId || params.workspaceId;\r\n if (teamId) metadataToUpdate.team_id = String(teamId);\r\n if (params.plan) metadataToUpdate.plan = String(params.plan);\r\n if (params.tier) metadataToUpdate.tier = String(params.tier);\r\n if (params.role) metadataToUpdate.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n metadataToUpdate[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n if (Object.keys(metadataToUpdate).length > 0) {\r\n updatePayload.metadata = metadataToUpdate;\r\n }\r\n\r\n return await this.stripe.customers.update(customerId, updatePayload);\r\n }\r\n\r\n /**\r\n * Clears in-memory resolution cache\r\n */\r\n public clearCache(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n\r\n/**\r\n * Factory to create CustomerManager\r\n */\r\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\r\n return new CustomerManager(options);\r\n}\r\n","interface CacheEntry {\n customerId: string;\n expiresAt: number;\n}\n\n/**\n * In-memory Customer Resolution Cache with TTL\n */\nexport class CustomerCache {\n private cache = new Map<string, CacheEntry>();\n private readonly defaultTtlMs: number;\n\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\n // Default TTL: 1 hour\n this.defaultTtlMs = defaultTtlMs;\n }\n\n public get(key: string): string | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.customerId;\n }\n\n public set(key: string, customerId: string, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\n this.cache.set(key, { customerId, expiresAt });\n }\n\n public delete(key: string): void {\n this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n"],"mappings":"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","names":["customerObj"]}
1
+ {"version":3,"sources":["../../src/customers/manager.ts","../../src/customers/cache.ts","../../src/customers/helpers.ts"],"sourcesContent":["import Stripe from 'stripe';\r\nimport { CustomerCache } from './cache';\r\n\r\nexport interface GetOrCreateCustomerParams {\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n phone?: string;\r\n orgId?: string;\r\n organizationId?: string;\r\n orgName?: string;\r\n teamId?: string;\r\n workspaceId?: string;\r\n role?: string;\r\n plan?: string;\r\n tier?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface CustomerManagerOptions {\r\n apiKey?: string;\r\n stripe?: Stripe;\r\n cacheTtlMs?: number;\r\n}\r\n\r\nexport class CustomerManager {\r\n private stripe: Stripe;\r\n private cache: CustomerCache;\r\n\r\n constructor(options: CustomerManagerOptions = {}) {\r\n if (options.stripe) {\r\n this.stripe = options.stripe;\r\n } else {\r\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\r\n if (!apiKey) {\r\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\r\n }\r\n this.stripe = new Stripe(apiKey);\r\n }\r\n\r\n this.cache = new CustomerCache(options.cacheTtlMs);\r\n }\r\n\r\n /**\r\n * Retrieves existing Stripe Customer or automatically provisions a new one with full metadata\r\n */\r\n public async getOrCreate(\r\n params: GetOrCreateCustomerParams\r\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\r\n const cacheKey = params.userId || params.email;\r\n if (cacheKey) {\r\n const cachedId = this.cache.get(cacheKey);\r\n if (cachedId) {\r\n return {\r\n id: cachedId,\r\n isNew: false,\r\n customer: { id: cachedId } as Stripe.Customer,\r\n };\r\n }\r\n }\r\n\r\n // 1. Search by userId in Stripe metadata\r\n if (params.userId) {\r\n try {\r\n const searchResult = await this.stripe.customers.search({\r\n query: `metadata['vibez_user_id']:'${params.userId}'`,\r\n limit: 1,\r\n });\r\n\r\n if (searchResult.data.length > 0) {\r\n const customer = searchResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.email) this.cache.set(params.email, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n } catch {\r\n // Fallback to email search if search query is unsupported or errors\r\n }\r\n }\r\n\r\n // 2. Search by email if provided\r\n if (params.email) {\r\n const listResult = await this.stripe.customers.list({\r\n email: params.email,\r\n limit: 1,\r\n });\r\n\r\n if (listResult.data.length > 0) {\r\n const customer = listResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.userId) this.cache.set(params.userId, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n }\r\n\r\n // 3. Prepare rich metadata for Stripe Customer\r\n const orgId = params.orgId || params.organizationId;\r\n const teamId = params.teamId || params.workspaceId;\r\n\r\n const stripeMetadata: Record<string, string> = {\r\n vibez_user_id: params.userId || '',\r\n created_by: 'vibezcheck',\r\n };\r\n\r\n if (orgId) stripeMetadata.org_id = String(orgId);\r\n if (params.orgName) stripeMetadata.org_name = String(params.orgName);\r\n if (teamId) stripeMetadata.team_id = String(teamId);\r\n if (params.plan) stripeMetadata.plan = String(params.plan);\r\n if (params.tier) stripeMetadata.tier = String(params.tier);\r\n if (params.role) stripeMetadata.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n stripeMetadata[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n // 4. Create new Customer in Stripe\r\n const newCustomer = await this.stripe.customers.create({\r\n email: params.email,\r\n name: params.name,\r\n phone: params.phone,\r\n metadata: stripeMetadata,\r\n });\r\n\r\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\r\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\r\n if (params.email) this.cache.set(params.email, newCustomer.id);\r\n\r\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\r\n }\r\n\r\n /**\r\n * Updates an existing Stripe Customer's information and metadata\r\n */\r\n public async updateCustomer(\r\n customerId: string,\r\n params: Partial<GetOrCreateCustomerParams>\r\n ): Promise<Stripe.Customer> {\r\n const updatePayload: Stripe.CustomerUpdateParams = {};\r\n\r\n if (params.email) updatePayload.email = params.email;\r\n if (params.name) updatePayload.name = params.name;\r\n if (params.phone) updatePayload.phone = params.phone;\r\n\r\n const metadataToUpdate: Record<string, string> = {};\r\n if (params.userId) metadataToUpdate.vibez_user_id = params.userId;\r\n const orgId = params.orgId || params.organizationId;\r\n if (orgId) metadataToUpdate.org_id = String(orgId);\r\n if (params.orgName) metadataToUpdate.org_name = String(params.orgName);\r\n const teamId = params.teamId || params.workspaceId;\r\n if (teamId) metadataToUpdate.team_id = String(teamId);\r\n if (params.plan) metadataToUpdate.plan = String(params.plan);\r\n if (params.tier) metadataToUpdate.tier = String(params.tier);\r\n if (params.role) metadataToUpdate.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n metadataToUpdate[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n if (Object.keys(metadataToUpdate).length > 0) {\r\n updatePayload.metadata = metadataToUpdate;\r\n }\r\n\r\n return await this.stripe.customers.update(customerId, updatePayload);\r\n }\r\n\r\n /**\r\n * Clears in-memory resolution cache\r\n */\r\n public clearCache(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n\r\n/**\r\n * Factory to create CustomerManager\r\n */\r\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\r\n return new CustomerManager(options);\r\n}\r\n","interface CacheEntry {\r\n customerId: string;\r\n expiresAt: number;\r\n}\r\n\r\n/**\r\n * In-memory Customer Resolution Cache with TTL\r\n */\r\nexport class CustomerCache {\r\n private cache = new Map<string, CacheEntry>();\r\n private readonly defaultTtlMs: number;\r\n\r\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\r\n // Default TTL: 1 hour\r\n this.defaultTtlMs = defaultTtlMs;\r\n }\r\n\r\n public get(key: string): string | null {\r\n const entry = this.cache.get(key);\r\n if (!entry) return null;\r\n\r\n if (Date.now() > entry.expiresAt) {\r\n this.cache.delete(key);\r\n return null;\r\n }\r\n\r\n return entry.customerId;\r\n }\r\n\r\n public set(key: string, customerId: string, ttlMs?: number): void {\r\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\r\n this.cache.set(key, { customerId, expiresAt });\r\n }\r\n\r\n public delete(key: string): void {\r\n this.cache.delete(key);\r\n }\r\n\r\n public clear(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n"],"mappings":"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","names":["customerObj"]}
package/dist/index.d.mts CHANGED
@@ -1,17 +1,23 @@
1
+ import { BillingHelper, createAgentSession, AgentSession, wrapTool, instrumentToolKit } from './billing/index.mjs';
2
+ export { AgentSessionOptions, CreateCheckoutSessionParams, CreatePortalSessionParams, CreateTopUpSessionParams, ToolOptions, ToolTrackingOptions, createBillingHelper } from './billing/index.mjs';
1
3
  export { AnthropicStreamAccumulator, ExtractedUsage, MeterBatcher, UsageDispatchedCallback, detectAndExtractUsage, extractAnthropicResponseUsage, extractGeminiResponseUsage, extractGenericResponseUsage, extractOpenAIResponseUsage, inspectOpenAIStreamChunk, trackTokens, wrapAnthropicStream, wrapGeminiStream, wrapOpenAIStream, wrapStream, wrapUniversalStream } from './meter/index.mjs';
2
- import { VibezCheckModelOptions, withBilling, createVibezSession } from './ai-sdk/index.mjs';
3
- export { VibezSession, VibezSessionOptions, WithBillingOptions, createVibezModel, meteredModel } from './ai-sdk/index.mjs';
4
- import { calculateCost, getModelPricing, registerModelPricing } from './pricing/index.mjs';
5
- export { CalculateCostParams, MODEL_PRICING_TABLE, calculateUsageCost, normalizeModelKey } from './pricing/index.mjs';
6
- import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-Mozk4-Mr.mjs';
7
- export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, d as CustomerInfo, D as DatabaseAdapter, I as InferenceCost, e as InlineRateConfig, K as KnownModel, f as ModelPricingRates, P as PaymentProvider, g as PricingConfig, R as RecordUsageOptions, h as SupportedAnthropicModel, i as SupportedDeepSeekModel, j as SupportedGoogleModel, k as SupportedModel, l as SupportedOpenAIModel, T as TokenUsage, m as ToolMeterOptions, V as VibezCircuitBreakerError } from './types-Mozk4-Mr.mjs';
8
- import { V as VibezMeter, c as createMeter } from './client-w_hWhQ6g.mjs';
4
+ import { w as withBilling } from './with-billing-DndWGxL8.mjs';
5
+ export { W as WithBillingOptions, m as meteredModel } from './with-billing-DndWGxL8.mjs';
6
+ import { VibezCheckModelOptions } from './ai-sdk/index.mjs';
7
+ export { VibezSession, VibezSessionOptions, createVibezModel, createVibezSession } from './ai-sdk/index.mjs';
8
+ import { calculateCost, calculateUsageCost, getModelPricing, registerModelPricing } from './pricing/index.mjs';
9
+ export { CalculateCostParams, MODEL_ALIASES, MODEL_PRICING_TABLE, normalizeModelKey } from './pricing/index.mjs';
10
+ import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-6P71CXAD.mjs';
11
+ export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, d as CustomerInfo, D as DatabaseAdapter, I as InferenceCost, e as InlineRateConfig, K as KnownModel, f as ModelPricingRates, P as PaymentProvider, g as PricingConfig, R as RecordUsageOptions, h as SupportedAnthropicModel, i as SupportedCohereModel, j as SupportedDeepSeekModel, k as SupportedGoogleModel, l as SupportedGroqModel, m as SupportedMistralModel, n as SupportedModel, o as SupportedOpenAIModel, p as SupportedXAIModel, T as TokenUsage, q as ToolMeterOptions, V as VibezCircuitBreakerError } from './types-6P71CXAD.mjs';
12
+ import { V as VibezMeter, c as createMeter } from './client-CbuXmoXz.mjs';
13
+ import vibezcheckMiddleware from './ai-sdk/middleware.mjs';
9
14
  import { CustomerManager } from './customers/index.mjs';
10
15
  export { CustomerCache, CustomerManagerOptions, GetOrCreateCustomerParams, NormalizedCustomer, createCustomerManager, normalizeCustomer } from './customers/index.mjs';
11
16
  import { ApiKeyAuth } from './auth/index.mjs';
12
17
  export { ApiKeyRecord, CreateApiKeyParams, VerifyAuthResult, createApiKeyAuth, extractAuthToken } from './auth/index.mjs';
13
- import { BillingHelper } from './billing/index.mjs';
14
- export { CreateCheckoutSessionParams, CreatePortalSessionParams, CreateTopUpSessionParams, createBillingHelper } from './billing/index.mjs';
18
+ export { TokenMeter, TokenMeterConfig, TokenMeterCustomer, createTokenMeter } from './compat/token-meter.mjs';
19
+ export { createStripe, createStripeV3, stripe, stripeV3 } from './compat/stripe-provider.mjs';
20
+ export { default as stripeMeteredModel } from './compat/stripe-meter.mjs';
15
21
  import 'stripe';
16
22
 
17
23
  /**
@@ -96,12 +102,20 @@ declare function vibezcheck(modelOrId: any, options?: VibezCheckModelOptions): a
96
102
  declare function vibezcheck(config?: VibezCheckConfig): VibezCheckClient;
97
103
  declare namespace vibezcheck {
98
104
  var calculateCost: typeof calculateCost;
105
+ var calculateUsageCost: typeof calculateUsageCost;
99
106
  var getModelPricing: typeof getModelPricing;
100
107
  var registerModelPricing: typeof registerModelPricing;
101
108
  var create: typeof createVibezCheck;
102
109
  var withBilling: typeof withBilling;
103
110
  var createMeter: typeof createMeter;
104
- var session: typeof createVibezSession;
111
+ var session: typeof createAgentSession;
112
+ var Session: typeof AgentSession;
113
+ var wrapTool: typeof wrapTool;
114
+ var instrumentToolKit: typeof instrumentToolKit;
115
+ var middleware: typeof vibezcheckMiddleware;
116
+ var Billing: typeof BillingHelper;
117
+ var Auth: typeof ApiKeyAuth;
118
+ var Customers: typeof CustomerManager;
105
119
  }
106
120
  /**
107
121
  * Singleton client instance
@@ -113,4 +127,4 @@ declare const vibez: VibezCheckClient;
113
127
  declare const vibescheck: typeof vibezcheck;
114
128
  declare const vibes: VibezCheckClient;
115
129
 
116
- export { ApiKeyAuth, BillingHelper, CustomerManager, CustomerParam, MeterOptions, StreamWrapOptions, UsageEvent, UsageSummary, VibezCheckClient, type VibezCheckConfig, VibezCheckModelOptions, VibezMeter, calculateCost, createMeter, createVibezCheck, createVibezSession, getModelPricing, registerModelPricing, vibes, vibescheck, vibez, vibezcheck, withBilling };
130
+ export { AgentSession, ApiKeyAuth, BillingHelper, CustomerManager, CustomerParam, MeterOptions, StreamWrapOptions, UsageEvent, UsageSummary, VibezCheckClient, type VibezCheckConfig, VibezCheckModelOptions, VibezMeter, calculateCost, calculateUsageCost, createAgentSession, createMeter, createVibezCheck, getModelPricing, instrumentToolKit, registerModelPricing, vibes, vibescheck, vibez, vibezcheck, vibezcheckMiddleware, withBilling, wrapTool };
package/dist/index.d.ts CHANGED
@@ -1,17 +1,23 @@
1
+ import { BillingHelper, createAgentSession, AgentSession, wrapTool, instrumentToolKit } from './billing/index.js';
2
+ export { AgentSessionOptions, CreateCheckoutSessionParams, CreatePortalSessionParams, CreateTopUpSessionParams, ToolOptions, ToolTrackingOptions, createBillingHelper } from './billing/index.js';
1
3
  export { AnthropicStreamAccumulator, ExtractedUsage, MeterBatcher, UsageDispatchedCallback, detectAndExtractUsage, extractAnthropicResponseUsage, extractGeminiResponseUsage, extractGenericResponseUsage, extractOpenAIResponseUsage, inspectOpenAIStreamChunk, trackTokens, wrapAnthropicStream, wrapGeminiStream, wrapOpenAIStream, wrapStream, wrapUniversalStream } from './meter/index.js';
2
- import { VibezCheckModelOptions, withBilling, createVibezSession } from './ai-sdk/index.js';
3
- export { VibezSession, VibezSessionOptions, WithBillingOptions, createVibezModel, meteredModel } from './ai-sdk/index.js';
4
- import { calculateCost, getModelPricing, registerModelPricing } from './pricing/index.js';
5
- export { CalculateCostParams, MODEL_PRICING_TABLE, calculateUsageCost, normalizeModelKey } from './pricing/index.js';
6
- import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-Mozk4-Mr.js';
7
- export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, d as CustomerInfo, D as DatabaseAdapter, I as InferenceCost, e as InlineRateConfig, K as KnownModel, f as ModelPricingRates, P as PaymentProvider, g as PricingConfig, R as RecordUsageOptions, h as SupportedAnthropicModel, i as SupportedDeepSeekModel, j as SupportedGoogleModel, k as SupportedModel, l as SupportedOpenAIModel, T as TokenUsage, m as ToolMeterOptions, V as VibezCircuitBreakerError } from './types-Mozk4-Mr.js';
8
- import { V as VibezMeter, c as createMeter } from './client-ynfWcHX6.js';
4
+ import { w as withBilling } from './with-billing-Bj6Ya_Iy.js';
5
+ export { W as WithBillingOptions, m as meteredModel } from './with-billing-Bj6Ya_Iy.js';
6
+ import { VibezCheckModelOptions } from './ai-sdk/index.js';
7
+ export { VibezSession, VibezSessionOptions, createVibezModel, createVibezSession } from './ai-sdk/index.js';
8
+ import { calculateCost, calculateUsageCost, getModelPricing, registerModelPricing } from './pricing/index.js';
9
+ export { CalculateCostParams, MODEL_ALIASES, MODEL_PRICING_TABLE, normalizeModelKey } from './pricing/index.js';
10
+ import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-6P71CXAD.js';
11
+ export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, d as CustomerInfo, D as DatabaseAdapter, I as InferenceCost, e as InlineRateConfig, K as KnownModel, f as ModelPricingRates, P as PaymentProvider, g as PricingConfig, R as RecordUsageOptions, h as SupportedAnthropicModel, i as SupportedCohereModel, j as SupportedDeepSeekModel, k as SupportedGoogleModel, l as SupportedGroqModel, m as SupportedMistralModel, n as SupportedModel, o as SupportedOpenAIModel, p as SupportedXAIModel, T as TokenUsage, q as ToolMeterOptions, V as VibezCircuitBreakerError } from './types-6P71CXAD.js';
12
+ import { V as VibezMeter, c as createMeter } from './client-BORmJy8s.js';
13
+ import vibezcheckMiddleware from './ai-sdk/middleware.js';
9
14
  import { CustomerManager } from './customers/index.js';
10
15
  export { CustomerCache, CustomerManagerOptions, GetOrCreateCustomerParams, NormalizedCustomer, createCustomerManager, normalizeCustomer } from './customers/index.js';
11
16
  import { ApiKeyAuth } from './auth/index.js';
12
17
  export { ApiKeyRecord, CreateApiKeyParams, VerifyAuthResult, createApiKeyAuth, extractAuthToken } from './auth/index.js';
13
- import { BillingHelper } from './billing/index.js';
14
- export { CreateCheckoutSessionParams, CreatePortalSessionParams, CreateTopUpSessionParams, createBillingHelper } from './billing/index.js';
18
+ export { TokenMeter, TokenMeterConfig, TokenMeterCustomer, createTokenMeter } from './compat/token-meter.js';
19
+ export { createStripe, createStripeV3, stripe, stripeV3 } from './compat/stripe-provider.js';
20
+ export { default as stripeMeteredModel } from './compat/stripe-meter.js';
15
21
  import 'stripe';
16
22
 
17
23
  /**
@@ -96,12 +102,20 @@ declare function vibezcheck(modelOrId: any, options?: VibezCheckModelOptions): a
96
102
  declare function vibezcheck(config?: VibezCheckConfig): VibezCheckClient;
97
103
  declare namespace vibezcheck {
98
104
  var calculateCost: typeof calculateCost;
105
+ var calculateUsageCost: typeof calculateUsageCost;
99
106
  var getModelPricing: typeof getModelPricing;
100
107
  var registerModelPricing: typeof registerModelPricing;
101
108
  var create: typeof createVibezCheck;
102
109
  var withBilling: typeof withBilling;
103
110
  var createMeter: typeof createMeter;
104
- var session: typeof createVibezSession;
111
+ var session: typeof createAgentSession;
112
+ var Session: typeof AgentSession;
113
+ var wrapTool: typeof wrapTool;
114
+ var instrumentToolKit: typeof instrumentToolKit;
115
+ var middleware: typeof vibezcheckMiddleware;
116
+ var Billing: typeof BillingHelper;
117
+ var Auth: typeof ApiKeyAuth;
118
+ var Customers: typeof CustomerManager;
105
119
  }
106
120
  /**
107
121
  * Singleton client instance
@@ -113,4 +127,4 @@ declare const vibez: VibezCheckClient;
113
127
  declare const vibescheck: typeof vibezcheck;
114
128
  declare const vibes: VibezCheckClient;
115
129
 
116
- export { ApiKeyAuth, BillingHelper, CustomerManager, CustomerParam, MeterOptions, StreamWrapOptions, UsageEvent, UsageSummary, VibezCheckClient, type VibezCheckConfig, VibezCheckModelOptions, VibezMeter, calculateCost, createMeter, createVibezCheck, createVibezSession, getModelPricing, registerModelPricing, vibes, vibescheck, vibez, vibezcheck, withBilling };
130
+ export { AgentSession, ApiKeyAuth, BillingHelper, CustomerManager, CustomerParam, MeterOptions, StreamWrapOptions, UsageEvent, UsageSummary, VibezCheckClient, type VibezCheckConfig, VibezCheckModelOptions, VibezMeter, calculateCost, calculateUsageCost, createAgentSession, createMeter, createVibezCheck, getModelPricing, instrumentToolKit, registerModelPricing, vibes, vibescheck, vibez, vibezcheck, vibezcheckMiddleware, withBilling, wrapTool };