vesant-sdk 1.7.2 → 1.8.0-dev.2b9e28d

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 (61) hide show
  1. package/dist/{client-D23KhWeh.d.mts → client-5q4whhGu.d.mts} +1 -1
  2. package/dist/{client-fy3trF2K.d.ts → client-BaUekQT8.d.ts} +32 -10
  3. package/dist/{client-B3DCAHlg.d.ts → client-DUHC-68_.d.ts} +1 -1
  4. package/dist/{client-BwXMQA2a.d.mts → client-XDEhh9VN.d.mts} +32 -10
  5. package/dist/compliance/index.d.mts +2 -2
  6. package/dist/compliance/index.d.ts +2 -2
  7. package/dist/compliance/index.js +40 -2
  8. package/dist/compliance/index.js.map +1 -1
  9. package/dist/compliance/index.mjs +40 -2
  10. package/dist/compliance/index.mjs.map +1 -1
  11. package/dist/decisions/index.js +1 -1
  12. package/dist/decisions/index.js.map +1 -1
  13. package/dist/decisions/index.mjs +1 -1
  14. package/dist/decisions/index.mjs.map +1 -1
  15. package/dist/geolocation/index.d.mts +2 -2
  16. package/dist/geolocation/index.d.ts +2 -2
  17. package/dist/geolocation/index.js +40 -2
  18. package/dist/geolocation/index.js.map +1 -1
  19. package/dist/geolocation/index.mjs +40 -2
  20. package/dist/geolocation/index.mjs.map +1 -1
  21. package/dist/{index-DSDgS09k.d.ts → index-BosFSGan.d.ts} +57 -2
  22. package/dist/{index-C3zUKydT.d.mts → index-C49a7fg2.d.mts} +57 -2
  23. package/dist/index.d.mts +4 -4
  24. package/dist/index.d.ts +4 -4
  25. package/dist/index.js +46 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +46 -3
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/kyc/core.js +1 -1
  30. package/dist/kyc/core.js.map +1 -1
  31. package/dist/kyc/core.mjs +1 -1
  32. package/dist/kyc/core.mjs.map +1 -1
  33. package/dist/kyc/index.js +1 -1
  34. package/dist/kyc/index.js.map +1 -1
  35. package/dist/kyc/index.mjs +1 -1
  36. package/dist/kyc/index.mjs.map +1 -1
  37. package/dist/react.d.mts +9 -2
  38. package/dist/react.d.ts +9 -2
  39. package/dist/react.js +15 -10
  40. package/dist/react.js.map +1 -1
  41. package/dist/react.mjs +15 -10
  42. package/dist/react.mjs.map +1 -1
  43. package/dist/risk-profile/index.js +1 -1
  44. package/dist/risk-profile/index.js.map +1 -1
  45. package/dist/risk-profile/index.mjs +1 -1
  46. package/dist/risk-profile/index.mjs.map +1 -1
  47. package/dist/scores/index.js +1 -1
  48. package/dist/scores/index.js.map +1 -1
  49. package/dist/scores/index.mjs +1 -1
  50. package/dist/scores/index.mjs.map +1 -1
  51. package/dist/tax/index.js +1 -1
  52. package/dist/tax/index.js.map +1 -1
  53. package/dist/tax/index.mjs +1 -1
  54. package/dist/tax/index.mjs.map +1 -1
  55. package/dist/webhooks/index.d.mts +1 -1
  56. package/dist/webhooks/index.d.ts +1 -1
  57. package/dist/webhooks/index.js +6 -0
  58. package/dist/webhooks/index.js.map +1 -1
  59. package/dist/webhooks/index.mjs +6 -1
  60. package/dist/webhooks/index.mjs.map +1 -1
  61. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/errors.ts","../../src/core/webhook-utils.ts","../../src/core/dedup.ts","../../src/webhooks/handler.ts","../../src/webhooks/middleware.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Error hierarchy for Vesant SDK\n *\n * Provides structured error handling with specific error types\n * for different failure scenarios.\n */\n\nexport class VesantError extends Error {\n public requestId?: string;\n\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'VesantError';\n Object.setPrototypeOf(this, VesantError.prototype);\n }\n}\n\n/** @deprecated Use VesantError instead */\nexport const CGSError = VesantError;\n/** @deprecated Use VesantError instead */\nexport type CGSError = VesantError;\n\nexport class NetworkError extends VesantError {\n constructor(message: string, public originalError?: unknown) {\n super(message, 'NETWORK_ERROR');\n this.name = 'NetworkError';\n Object.setPrototypeOf(this, NetworkError.prototype);\n }\n}\n\nexport class ValidationError extends VesantError {\n constructor(message: string, fields?: string[]) {\n super(message, 'VALIDATION_ERROR', 400, { fields });\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class ServiceUnavailableError extends VesantError {\n constructor(message: string = 'Service unavailable') {\n super(message, 'SERVICE_UNAVAILABLE', 503);\n this.name = 'ServiceUnavailableError';\n Object.setPrototypeOf(this, ServiceUnavailableError.prototype);\n }\n}\n\nexport class ComplianceBlockedError extends VesantError {\n constructor(reasons: string[]) {\n super('Access blocked due to compliance rules', 'COMPLIANCE_BLOCKED', 403, { reasons });\n this.name = 'ComplianceBlockedError';\n Object.setPrototypeOf(this, ComplianceBlockedError.prototype);\n }\n}\n\nexport class AuthenticationError extends VesantError {\n constructor(message: string = 'Authentication failed') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\nexport class RateLimitError extends VesantError {\n constructor(public retryAfter?: number) {\n super('Rate limit exceeded', 'RATE_LIMIT_EXCEEDED', 429, { retryAfter });\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\nexport class TimeoutError extends VesantError {\n constructor(public timeout: number) {\n super(`Request timeout after ${timeout}ms`, 'TIMEOUT', 408, { timeout });\n this.name = 'TimeoutError';\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\nexport class ComplianceError extends VesantError {\n constructor(\n message: string,\n public originalError?: unknown,\n code: string = 'COMPLIANCE_ERROR'\n ) {\n super(message, code);\n this.name = 'ComplianceError';\n Object.setPrototypeOf(this, ComplianceError.prototype);\n }\n}\n\nexport class CircuitBreakerOpenError extends VesantError {\n constructor() {\n super('Circuit breaker is open — requests are temporarily blocked', 'CIRCUIT_BREAKER_OPEN', 503);\n this.name = 'CircuitBreakerOpenError';\n Object.setPrototypeOf(this, CircuitBreakerOpenError.prototype);\n }\n}\n","/**\n * Webhook signature verification utilities.\n *\n * Supports both Web Crypto API (browsers, Deno, Cloudflare Workers)\n * and Node.js crypto module with automatic runtime detection.\n * Uses constant-time comparison to prevent timing attacks.\n */\n\nimport { VesantError } from './errors';\n\nexport interface VerifyWebhookSignatureOptions {\n /** Max allowed clock skew in ms for the signed-timestamp scheme (default: 300000). */\n tolerance?: number;\n /** Clock source for the tolerance check (default: Date.now). */\n now?: () => number;\n /** Accept the legacy body-only `sha256=<hex>` format (default: true, for migration). */\n allowLegacy?: boolean;\n}\n\n/**\n * Verify an HMAC-SHA256 webhook signature.\n *\n * Supports two schemes:\n * - Signed-timestamp (preferred): `t=<unix>,v1=<hex>` where the HMAC is computed\n * over `${t}.${payload}`. The timestamp is inside the signed material, so a\n * replayed body is rejected once `|now - t|` exceeds the tolerance — the check\n * is done BEFORE the HMAC compare and authenticates the timestamp.\n * - Legacy (body-only): `sha256=<hex>` (or raw hex) over the payload alone. Kept\n * for the migration window; disable via `allowLegacy: false`.\n *\n * @returns true if the signature is valid\n */\nexport async function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string,\n opts: VerifyWebhookSignatureOptions = {}\n): Promise<boolean> {\n const signed = parseSignedTimestamp(signature);\n if (signed) {\n const tolerance = opts.tolerance ?? 300000;\n const now = opts.now?.() ?? Date.now();\n // Authenticate the timestamp first — reject replays before any HMAC compare.\n if (tolerance > 0 && Math.abs(now - signed.t * 1000) > tolerance) {\n return false;\n }\n const expected = await computeHmacSha256(`${signed.t}.${payload}`, secret);\n return constantTimeEqual(signed.v1, expected);\n }\n\n if (opts.allowLegacy === false) {\n return false;\n }\n\n const hexDigest = await computeHmacSha256(payload, secret);\n // Backend sends \"sha256=<hex>\" format — support both prefixed and raw signatures\n const expectedPrefixed = `sha256=${hexDigest}`;\n\n if (signature.startsWith('sha256=')) {\n return constantTimeEqual(signature, expectedPrefixed);\n }\n\n return constantTimeEqual(signature, hexDigest);\n}\n\n/**\n * Parse the `t=<unix>,v1=<hex>` signed-timestamp scheme; returns null if the\n * signature is not in that form (e.g. legacy `sha256=<hex>`).\n */\nfunction parseSignedTimestamp(signature: string): { t: number; v1: string } | null {\n if (!signature.includes('t=') || !signature.includes('v1=')) {\n return null;\n }\n let t: number | undefined;\n let v1: string | undefined;\n for (const part of signature.split(',')) {\n const eq = part.indexOf('=');\n if (eq === -1) continue;\n const key = part.slice(0, eq).trim();\n const value = part.slice(eq + 1).trim();\n if (key === 't') t = Number(value);\n else if (key === 'v1') v1 = value;\n }\n if (t === undefined || Number.isNaN(t) || !v1) {\n return null;\n }\n return { t, v1 };\n}\n\n/**\n * Compute HMAC-SHA256 hex digest.\n * Automatically selects Web Crypto API or Node.js crypto.\n */\nasync function computeHmacSha256(message: string, secret: string): Promise<string> {\n // Try Web Crypto API first (browsers, Deno, Cloudflare Workers, Node 18+)\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n const encoder = new TextEncoder();\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n );\n const sig = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(message));\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n // Fallback to Node.js crypto module\n try {\n const { createHmac } = await import('crypto');\n return createHmac('sha256', secret).update(message).digest('hex');\n } catch {\n throw new VesantError(\n 'No crypto implementation available. Requires Web Crypto API or Node.js crypto module.',\n 'CRYPTO_UNAVAILABLE'\n );\n }\n}\n\n/**\n * Constant-time string comparison to prevent timing attacks.\n */\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n","/**\n * Pluggable dedup store for webhook replay protection.\n *\n * The default InMemoryDedupStore is process-local — correct for a single\n * long-lived process, but useless across replicas / serverless invocations where\n * the backend's at-least-once retries land on different instances. Supply a\n * shared implementation (e.g. Redis with SETNX + TTL) via WebhookHandlerConfig\n * to dedup reliably in those deployments.\n */\n\nexport interface WebhookDedupStore {\n /** Has this event id already been processed? */\n seen(id: string): Promise<boolean>;\n /** Record this event id as processed, retained for at least ttlMs. */\n mark(id: string, ttlMs: number): Promise<void>;\n}\n\nexport interface InMemoryDedupStoreOptions {\n /** Purge expired entries once the map grows past this size (default: 1000). */\n maxEntries?: number;\n /** Injectable clock (default: Date.now). */\n now?: () => number;\n}\n\nexport class InMemoryDedupStore implements WebhookDedupStore {\n private readonly expiryById = new Map<string, number>();\n private readonly maxEntries: number;\n private readonly now: () => number;\n\n constructor(opts: InMemoryDedupStoreOptions = {}) {\n this.maxEntries = opts.maxEntries ?? 1000;\n this.now = opts.now ?? (() => Date.now());\n }\n\n async seen(id: string): Promise<boolean> {\n return this.expiryById.has(id);\n }\n\n async mark(id: string, ttlMs: number): Promise<void> {\n const now = this.now();\n this.expiryById.set(id, now + ttlMs);\n\n // Bounded memory: purge expired entries once the map grows too large.\n if (this.expiryById.size > this.maxEntries) {\n for (const [key, expiresAt] of this.expiryById) {\n if (now > expiresAt) {\n this.expiryById.delete(key);\n }\n }\n }\n }\n}\n","/**\n * Webhook event handler with signature verification and typed dispatch.\n */\n\nimport { verifyWebhookSignature } from '../core/webhook-utils';\nimport { ValidationError } from '../core/errors';\nimport { InMemoryDedupStore, type WebhookDedupStore } from '../core';\nimport type {\n WebhookEvent,\n WebhookEventType,\n WebhookEventHandler,\n WebhookAnyHandler,\n WebhookHandlerConfig,\n} from './types';\n\n/** Resolve the event id: the top-level `id`, or `notification.id` for the notification envelope. */\nfunction resolveEventId(event: WebhookEvent): string | undefined {\n if (event.id) {\n return event.id;\n }\n if (event.event_type === 'notification.created') {\n return event.notification?.id;\n }\n return undefined;\n}\n\nexport class WebhookHandler {\n private handlers = new Map<WebhookEventType, WebhookEventHandler[]>();\n private anyHandlers: WebhookAnyHandler[] = [];\n private readonly secret: string;\n private readonly tolerance: number;\n private readonly replayProtection: boolean;\n private readonly allowLegacySignature: boolean;\n private readonly dedupStore: WebhookDedupStore;\n\n constructor(config: WebhookHandlerConfig) {\n this.secret = config.secret;\n this.tolerance = config.tolerance ?? 300000; // 5 minutes\n this.replayProtection = config.replayProtection ?? true;\n this.allowLegacySignature = config.allowLegacySignature ?? true;\n this.dedupStore = config.dedupStore ?? new InMemoryDedupStore();\n }\n\n /**\n * Register a handler for a specific event type.\n */\n on<T extends WebhookEventType>(\n eventType: T,\n handler: WebhookEventHandler<T>\n ): this {\n const existing = this.handlers.get(eventType) || [];\n existing.push(handler as unknown as WebhookEventHandler);\n this.handlers.set(eventType, existing);\n return this;\n }\n\n /**\n * Register a catch-all handler for all event types.\n */\n onAny(handler: WebhookAnyHandler): this {\n this.anyHandlers.push(handler);\n return this;\n }\n\n /**\n * Verify signature and parse the webhook body.\n */\n async verifyAndParse(body: string, signature: string): Promise<WebhookEvent> {\n const isValid = await verifyWebhookSignature(body, signature, this.secret, {\n tolerance: this.tolerance,\n allowLegacy: this.allowLegacySignature,\n });\n if (!isValid) {\n throw new ValidationError('Invalid webhook signature', ['signature']);\n }\n\n return this.parseAndValidate(body);\n }\n\n /**\n * Verify signature, parse, and dispatch to registered handlers.\n */\n async handle(body: string, signature: string): Promise<void> {\n const event = await this.verifyAndParse(body, signature);\n await this.dispatch(event);\n }\n\n /**\n * Parse an event without signature verification (for testing).\n */\n async parseEvent(body: string): Promise<WebhookEvent> {\n return this.parseAndValidate(body);\n }\n\n private async parseAndValidate(body: string): Promise<WebhookEvent> {\n const event = JSON.parse(body) as WebhookEvent;\n const eventId = resolveEventId(event);\n\n if (!event.event_type || !eventId || !event.timestamp) {\n throw new ValidationError(\n 'Invalid webhook event: missing required fields (event_type, id, timestamp)',\n ['event_type', 'id', 'timestamp']\n );\n }\n\n // Timestamp tolerance check (defense in depth; the signed-timestamp scheme\n // also authenticates the timestamp in verifyWebhookSignature).\n if (this.tolerance > 0) {\n const eventTime = new Date(event.timestamp).getTime();\n if (Math.abs(Date.now() - eventTime) > this.tolerance) {\n throw new ValidationError(\n `Webhook event timestamp is outside tolerance window (${this.tolerance}ms)`,\n ['timestamp']\n );\n }\n }\n\n // Replay protection via the (pluggable) dedup store.\n if (this.replayProtection) {\n if (await this.dedupStore.seen(eventId)) {\n throw new ValidationError(\n `Duplicate webhook event: ${eventId} has already been processed`,\n ['id']\n );\n }\n await this.dedupStore.mark(eventId, this.tolerance);\n }\n\n return event;\n }\n\n private async dispatch(event: WebhookEvent): Promise<void> {\n const typeHandlers = this.handlers.get(event.event_type) || [];\n const allHandlers = [...typeHandlers, ...this.anyHandlers];\n\n for (const handler of allHandlers) {\n await (handler as WebhookAnyHandler)(event);\n }\n }\n}\n","/**\n * Framework middleware helpers for webhook handling.\n *\n * Provides pre-built integrations for Express/Connect and Next.js App Router.\n */\n\nimport { WebhookHandler } from './handler';\nimport type { WebhookHandlerConfig, WebhookEventType, WebhookEventHandler, WebhookAnyHandler } from './types';\n\nexport interface WebhookMiddlewareOptions extends WebhookHandlerConfig {\n /** Event handlers to register */\n handlers?: Partial<Record<WebhookEventType, WebhookEventHandler>>;\n /** Catch-all handler */\n onAny?: WebhookAnyHandler;\n}\n\n/**\n * Create an Express/Connect-compatible middleware for webhook handling.\n *\n * Expects the raw body to be available as `req.body` (string).\n * Use `express.raw({ type: 'application/json' })` or similar middleware upstream.\n */\nexport function createWebhookMiddleware(options: WebhookMiddlewareOptions) {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (\n req: { body: string | Buffer; headers: Record<string, string | string[] | undefined> },\n res: { status(code: number): { json(body: unknown): void }; json?(body: unknown): void },\n next?: (err?: unknown) => void\n ) => {\n try {\n const body = typeof req.body === 'string' ? req.body : req.body.toString('utf-8');\n const signature = req.headers[signatureHeader];\n\n if (!signature || typeof signature !== 'string') {\n res.status(401).json({ error: 'Missing webhook signature' });\n return;\n }\n\n await handler.handle(body, signature);\n res.status(200).json({ received: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n\n if (message.includes('signature')) {\n res.status(401).json({ error: message });\n } else if (message.includes('tolerance') || message.includes('timestamp')) {\n res.status(400).json({ error: message });\n } else if (message.includes('Duplicate')) {\n res.status(409).json({ error: message });\n } else if (next) {\n next(error);\n } else {\n res.status(500).json({ error: message });\n }\n }\n };\n}\n\n/**\n * Create a Next.js App Router-compatible webhook handler.\n *\n * Returns an async function `(request: Request) => Promise<Response>`.\n */\nexport function createNextWebhookHandler(\n options: WebhookMiddlewareOptions\n): (request: Request) => Promise<Response> {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (request: Request): Promise<Response> => {\n try {\n const body = await request.text();\n const signature = request.headers.get(signatureHeader);\n\n if (!signature) {\n return new Response(JSON.stringify({ error: 'Missing webhook signature' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n await handler.handle(body, signature);\n\n return new Response(JSON.stringify({ received: true }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n const status = message.includes('signature')\n ? 401\n : message.includes('tolerance') || message.includes('timestamp')\n ? 400\n : message.includes('Duplicate')\n ? 409\n : 500;\n\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n };\n}\n\nfunction buildHandler(options: WebhookMiddlewareOptions): WebhookHandler {\n const handler = new WebhookHandler(options);\n\n if (options.handlers) {\n for (const [eventType, eventHandler] of Object.entries(options.handlers)) {\n if (eventHandler) {\n handler.on(eventType as WebhookEventType, eventHandler);\n }\n }\n }\n\n if (options.onAny) {\n handler.onAny(options.onAny);\n }\n\n return handler;\n}\n"]}
1
+ {"version":3,"sources":["../../src/core/errors.ts","../../src/core/webhook-utils.ts","../../src/core/dedup.ts","../../src/webhooks/handler.ts","../../src/webhooks/middleware.ts","../../src/webhooks/types.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Error hierarchy for Vesant SDK\n *\n * Provides structured error handling with specific error types\n * for different failure scenarios.\n */\n\nexport class VesantError extends Error {\n public requestId?: string;\n\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'VesantError';\n Object.setPrototypeOf(this, VesantError.prototype);\n }\n}\n\n/** @deprecated Use VesantError instead */\nexport const CGSError = VesantError;\n/** @deprecated Use VesantError instead */\nexport type CGSError = VesantError;\n\nexport class NetworkError extends VesantError {\n constructor(message: string, public originalError?: unknown) {\n super(message, 'NETWORK_ERROR');\n this.name = 'NetworkError';\n Object.setPrototypeOf(this, NetworkError.prototype);\n }\n}\n\nexport class ValidationError extends VesantError {\n constructor(message: string, fields?: string[]) {\n super(message, 'VALIDATION_ERROR', 400, { fields });\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class ServiceUnavailableError extends VesantError {\n constructor(message: string = 'Service unavailable') {\n super(message, 'SERVICE_UNAVAILABLE', 503);\n this.name = 'ServiceUnavailableError';\n Object.setPrototypeOf(this, ServiceUnavailableError.prototype);\n }\n}\n\nexport class ComplianceBlockedError extends VesantError {\n constructor(reasons: string[]) {\n super('Access blocked due to compliance rules', 'COMPLIANCE_BLOCKED', 403, { reasons });\n this.name = 'ComplianceBlockedError';\n Object.setPrototypeOf(this, ComplianceBlockedError.prototype);\n }\n}\n\nexport class AuthenticationError extends VesantError {\n constructor(message: string = 'Authentication failed') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\nexport class RateLimitError extends VesantError {\n constructor(public retryAfter?: number) {\n super('Rate limit exceeded', 'RATE_LIMIT_EXCEEDED', 429, { retryAfter });\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\nexport class TimeoutError extends VesantError {\n constructor(public timeout: number) {\n super(`Request timeout after ${timeout}ms`, 'TIMEOUT', 408, { timeout });\n this.name = 'TimeoutError';\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n\nexport class ComplianceError extends VesantError {\n constructor(\n message: string,\n public originalError?: unknown,\n code: string = 'COMPLIANCE_ERROR'\n ) {\n super(message, code);\n this.name = 'ComplianceError';\n Object.setPrototypeOf(this, ComplianceError.prototype);\n }\n}\n\nexport class CircuitBreakerOpenError extends VesantError {\n constructor() {\n super('Circuit breaker is open — requests are temporarily blocked', 'CIRCUIT_BREAKER_OPEN', 503);\n this.name = 'CircuitBreakerOpenError';\n Object.setPrototypeOf(this, CircuitBreakerOpenError.prototype);\n }\n}\n","/**\n * Webhook signature verification utilities.\n *\n * Supports both Web Crypto API (browsers, Deno, Cloudflare Workers)\n * and Node.js crypto module with automatic runtime detection.\n * Uses constant-time comparison to prevent timing attacks.\n */\n\nimport { VesantError } from './errors';\n\nexport interface VerifyWebhookSignatureOptions {\n /** Max allowed clock skew in ms for the signed-timestamp scheme (default: 300000). */\n tolerance?: number;\n /** Clock source for the tolerance check (default: Date.now). */\n now?: () => number;\n /** Accept the legacy body-only `sha256=<hex>` format (default: true, for migration). */\n allowLegacy?: boolean;\n}\n\n/**\n * Verify an HMAC-SHA256 webhook signature.\n *\n * Supports two schemes:\n * - Signed-timestamp (preferred): `t=<unix>,v1=<hex>` where the HMAC is computed\n * over `${t}.${payload}`. The timestamp is inside the signed material, so a\n * replayed body is rejected once `|now - t|` exceeds the tolerance — the check\n * is done BEFORE the HMAC compare and authenticates the timestamp.\n * - Legacy (body-only): `sha256=<hex>` (or raw hex) over the payload alone. Kept\n * for the migration window; disable via `allowLegacy: false`.\n *\n * @returns true if the signature is valid\n */\nexport async function verifyWebhookSignature(\n payload: string,\n signature: string,\n secret: string,\n opts: VerifyWebhookSignatureOptions = {}\n): Promise<boolean> {\n const signed = parseSignedTimestamp(signature);\n if (signed) {\n const tolerance = opts.tolerance ?? 300000;\n const now = opts.now?.() ?? Date.now();\n // Authenticate the timestamp first — reject replays before any HMAC compare.\n if (tolerance > 0 && Math.abs(now - signed.t * 1000) > tolerance) {\n return false;\n }\n const expected = await computeHmacSha256(`${signed.t}.${payload}`, secret);\n return constantTimeEqual(signed.v1, expected);\n }\n\n if (opts.allowLegacy === false) {\n return false;\n }\n\n const hexDigest = await computeHmacSha256(payload, secret);\n // Backend sends \"sha256=<hex>\" format — support both prefixed and raw signatures\n const expectedPrefixed = `sha256=${hexDigest}`;\n\n if (signature.startsWith('sha256=')) {\n return constantTimeEqual(signature, expectedPrefixed);\n }\n\n return constantTimeEqual(signature, hexDigest);\n}\n\n/**\n * Parse the `t=<unix>,v1=<hex>` signed-timestamp scheme; returns null if the\n * signature is not in that form (e.g. legacy `sha256=<hex>`).\n */\nfunction parseSignedTimestamp(signature: string): { t: number; v1: string } | null {\n if (!signature.includes('t=') || !signature.includes('v1=')) {\n return null;\n }\n let t: number | undefined;\n let v1: string | undefined;\n for (const part of signature.split(',')) {\n const eq = part.indexOf('=');\n if (eq === -1) continue;\n const key = part.slice(0, eq).trim();\n const value = part.slice(eq + 1).trim();\n if (key === 't') t = Number(value);\n else if (key === 'v1') v1 = value;\n }\n if (t === undefined || Number.isNaN(t) || !v1) {\n return null;\n }\n return { t, v1 };\n}\n\n/**\n * Compute HMAC-SHA256 hex digest.\n * Automatically selects Web Crypto API or Node.js crypto.\n */\nasync function computeHmacSha256(message: string, secret: string): Promise<string> {\n // Try Web Crypto API first (browsers, Deno, Cloudflare Workers, Node 18+)\n if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.subtle) {\n const encoder = new TextEncoder();\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n );\n const sig = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(message));\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n // Fallback to Node.js crypto module\n try {\n const { createHmac } = await import('crypto');\n return createHmac('sha256', secret).update(message).digest('hex');\n } catch {\n throw new VesantError(\n 'No crypto implementation available. Requires Web Crypto API or Node.js crypto module.',\n 'CRYPTO_UNAVAILABLE'\n );\n }\n}\n\n/**\n * Constant-time string comparison to prevent timing attacks.\n */\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n","/**\n * Pluggable dedup store for webhook replay protection.\n *\n * The default InMemoryDedupStore is process-local — correct for a single\n * long-lived process, but useless across replicas / serverless invocations where\n * the backend's at-least-once retries land on different instances. Supply a\n * shared implementation (e.g. Redis with SETNX + TTL) via WebhookHandlerConfig\n * to dedup reliably in those deployments.\n */\n\nexport interface WebhookDedupStore {\n /** Has this event id already been processed? */\n seen(id: string): Promise<boolean>;\n /** Record this event id as processed, retained for at least ttlMs. */\n mark(id: string, ttlMs: number): Promise<void>;\n}\n\nexport interface InMemoryDedupStoreOptions {\n /** Purge expired entries once the map grows past this size (default: 1000). */\n maxEntries?: number;\n /** Injectable clock (default: Date.now). */\n now?: () => number;\n}\n\nexport class InMemoryDedupStore implements WebhookDedupStore {\n private readonly expiryById = new Map<string, number>();\n private readonly maxEntries: number;\n private readonly now: () => number;\n\n constructor(opts: InMemoryDedupStoreOptions = {}) {\n this.maxEntries = opts.maxEntries ?? 1000;\n this.now = opts.now ?? (() => Date.now());\n }\n\n async seen(id: string): Promise<boolean> {\n return this.expiryById.has(id);\n }\n\n async mark(id: string, ttlMs: number): Promise<void> {\n const now = this.now();\n this.expiryById.set(id, now + ttlMs);\n\n // Bounded memory: purge expired entries once the map grows too large.\n if (this.expiryById.size > this.maxEntries) {\n for (const [key, expiresAt] of this.expiryById) {\n if (now > expiresAt) {\n this.expiryById.delete(key);\n }\n }\n }\n }\n}\n","/**\n * Webhook event handler with signature verification and typed dispatch.\n */\n\nimport { verifyWebhookSignature } from '../core/webhook-utils';\nimport { ValidationError } from '../core/errors';\nimport { InMemoryDedupStore, type WebhookDedupStore } from '../core';\nimport type {\n WebhookEvent,\n WebhookEventType,\n WebhookEventHandler,\n WebhookAnyHandler,\n WebhookHandlerConfig,\n} from './types';\n\n/** Resolve the event id: the top-level `id`, or `notification.id` for the notification envelope. */\nfunction resolveEventId(event: WebhookEvent): string | undefined {\n if (event.id) {\n return event.id;\n }\n if (event.event_type === 'notification.created') {\n return event.notification?.id;\n }\n return undefined;\n}\n\nexport class WebhookHandler {\n private handlers = new Map<WebhookEventType, WebhookEventHandler[]>();\n private anyHandlers: WebhookAnyHandler[] = [];\n private readonly secret: string;\n private readonly tolerance: number;\n private readonly replayProtection: boolean;\n private readonly allowLegacySignature: boolean;\n private readonly dedupStore: WebhookDedupStore;\n\n constructor(config: WebhookHandlerConfig) {\n this.secret = config.secret;\n this.tolerance = config.tolerance ?? 300000; // 5 minutes\n this.replayProtection = config.replayProtection ?? true;\n this.allowLegacySignature = config.allowLegacySignature ?? true;\n this.dedupStore = config.dedupStore ?? new InMemoryDedupStore();\n }\n\n /**\n * Register a handler for a specific event type.\n */\n on<T extends WebhookEventType>(\n eventType: T,\n handler: WebhookEventHandler<T>\n ): this {\n const existing = this.handlers.get(eventType) || [];\n existing.push(handler as unknown as WebhookEventHandler);\n this.handlers.set(eventType, existing);\n return this;\n }\n\n /**\n * Register a catch-all handler for all event types.\n */\n onAny(handler: WebhookAnyHandler): this {\n this.anyHandlers.push(handler);\n return this;\n }\n\n /**\n * Verify signature and parse the webhook body.\n */\n async verifyAndParse(body: string, signature: string): Promise<WebhookEvent> {\n const isValid = await verifyWebhookSignature(body, signature, this.secret, {\n tolerance: this.tolerance,\n allowLegacy: this.allowLegacySignature,\n });\n if (!isValid) {\n throw new ValidationError('Invalid webhook signature', ['signature']);\n }\n\n return this.parseAndValidate(body);\n }\n\n /**\n * Verify signature, parse, and dispatch to registered handlers.\n */\n async handle(body: string, signature: string): Promise<void> {\n const event = await this.verifyAndParse(body, signature);\n await this.dispatch(event);\n }\n\n /**\n * Parse an event without signature verification (for testing).\n */\n async parseEvent(body: string): Promise<WebhookEvent> {\n return this.parseAndValidate(body);\n }\n\n private async parseAndValidate(body: string): Promise<WebhookEvent> {\n const event = JSON.parse(body) as WebhookEvent;\n const eventId = resolveEventId(event);\n\n if (!event.event_type || !eventId || !event.timestamp) {\n throw new ValidationError(\n 'Invalid webhook event: missing required fields (event_type, id, timestamp)',\n ['event_type', 'id', 'timestamp']\n );\n }\n\n // Timestamp tolerance check (defense in depth; the signed-timestamp scheme\n // also authenticates the timestamp in verifyWebhookSignature).\n if (this.tolerance > 0) {\n const eventTime = new Date(event.timestamp).getTime();\n if (Math.abs(Date.now() - eventTime) > this.tolerance) {\n throw new ValidationError(\n `Webhook event timestamp is outside tolerance window (${this.tolerance}ms)`,\n ['timestamp']\n );\n }\n }\n\n // Replay protection via the (pluggable) dedup store.\n if (this.replayProtection) {\n if (await this.dedupStore.seen(eventId)) {\n throw new ValidationError(\n `Duplicate webhook event: ${eventId} has already been processed`,\n ['id']\n );\n }\n await this.dedupStore.mark(eventId, this.tolerance);\n }\n\n return event;\n }\n\n private async dispatch(event: WebhookEvent): Promise<void> {\n const typeHandlers = this.handlers.get(event.event_type) || [];\n const allHandlers = [...typeHandlers, ...this.anyHandlers];\n\n for (const handler of allHandlers) {\n await (handler as WebhookAnyHandler)(event);\n }\n }\n}\n","/**\n * Framework middleware helpers for webhook handling.\n *\n * Provides pre-built integrations for Express/Connect and Next.js App Router.\n */\n\nimport { WebhookHandler } from './handler';\nimport type { WebhookHandlerConfig, WebhookEventType, WebhookEventHandler, WebhookAnyHandler } from './types';\n\nexport interface WebhookMiddlewareOptions extends WebhookHandlerConfig {\n /** Event handlers to register */\n handlers?: Partial<Record<WebhookEventType, WebhookEventHandler>>;\n /** Catch-all handler */\n onAny?: WebhookAnyHandler;\n}\n\n/**\n * Create an Express/Connect-compatible middleware for webhook handling.\n *\n * Expects the raw body to be available as `req.body` (string).\n * Use `express.raw({ type: 'application/json' })` or similar middleware upstream.\n */\nexport function createWebhookMiddleware(options: WebhookMiddlewareOptions) {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (\n req: { body: string | Buffer; headers: Record<string, string | string[] | undefined> },\n res: { status(code: number): { json(body: unknown): void }; json?(body: unknown): void },\n next?: (err?: unknown) => void\n ) => {\n try {\n const body = typeof req.body === 'string' ? req.body : req.body.toString('utf-8');\n const signature = req.headers[signatureHeader];\n\n if (!signature || typeof signature !== 'string') {\n res.status(401).json({ error: 'Missing webhook signature' });\n return;\n }\n\n await handler.handle(body, signature);\n res.status(200).json({ received: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n\n if (message.includes('signature')) {\n res.status(401).json({ error: message });\n } else if (message.includes('tolerance') || message.includes('timestamp')) {\n res.status(400).json({ error: message });\n } else if (message.includes('Duplicate')) {\n res.status(409).json({ error: message });\n } else if (next) {\n next(error);\n } else {\n res.status(500).json({ error: message });\n }\n }\n };\n}\n\n/**\n * Create a Next.js App Router-compatible webhook handler.\n *\n * Returns an async function `(request: Request) => Promise<Response>`.\n */\nexport function createNextWebhookHandler(\n options: WebhookMiddlewareOptions\n): (request: Request) => Promise<Response> {\n const handler = buildHandler(options);\n const signatureHeader = options.signatureHeader || 'x-webhook-signature';\n\n return async (request: Request): Promise<Response> => {\n try {\n const body = await request.text();\n const signature = request.headers.get(signatureHeader);\n\n if (!signature) {\n return new Response(JSON.stringify({ error: 'Missing webhook signature' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n\n await handler.handle(body, signature);\n\n return new Response(JSON.stringify({ received: true }), {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Webhook processing failed';\n const status = message.includes('signature')\n ? 401\n : message.includes('tolerance') || message.includes('timestamp')\n ? 400\n : message.includes('Duplicate')\n ? 409\n : 500;\n\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n }\n };\n}\n\nfunction buildHandler(options: WebhookMiddlewareOptions): WebhookHandler {\n const handler = new WebhookHandler(options);\n\n if (options.handlers) {\n for (const [eventType, eventHandler] of Object.entries(options.handlers)) {\n if (eventHandler) {\n handler.on(eventType as WebhookEventType, eventHandler);\n }\n }\n }\n\n if (options.onAny) {\n handler.onAny(options.onAny);\n }\n\n return handler;\n}\n","/**\n * Webhook event types and payload definitions.\n */\n\nimport type { Timestamp, UUID, RiskLevel } from '../core/types';\nimport type { WebhookDedupStore } from '../core';\n\n// --- Event Types ---\n\nexport type WebhookEventType =\n | 'notification.created'\n | 'risk.score.changed'\n | 'risk.category.changed'\n | 'profile.created'\n | 'profile.updated'\n | 'geolocation.verified'\n | 'geolocation.blocked'\n | 'kyc.status.changed'\n | 'kyc.approved'\n | 'kyc.declined'\n | 'decision.recorded'\n | 'label.applied'\n | 'location_request.completed'\n | 'compliance.check.failed'\n | 'tax.reminder.sent';\n\n// --- Base Event ---\n\nexport interface BaseWebhookEvent<\n T extends WebhookEventType = WebhookEventType,\n P = unknown,\n> {\n /**\n * Top-level event id (typed events). The notification envelope carries none —\n * the handler resolves the id from `notification.id`.\n */\n id?: UUID;\n event_type: T;\n tenant_id: string;\n environment: 'production' | 'sandbox';\n /** Absent on the notification envelope; present on typed events. */\n customer_id?: string;\n payload: P;\n timestamp: Timestamp;\n metadata?: Record<string, unknown>;\n}\n\n// --- Typed Payloads ---\n\nexport interface RiskScoreChangedPayload {\n previous_score: number;\n new_score: number;\n risk_level: RiskLevel;\n factors: string[];\n}\n\nexport interface RiskCategoryChangedPayload {\n previous_category: string;\n new_category: string;\n risk_level: RiskLevel;\n}\n\nexport interface ProfileCreatedPayload {\n customer_id: string;\n entity_type: string;\n source: string;\n}\n\nexport interface ProfileUpdatedPayload {\n customer_id: string;\n updated_fields: string[];\n}\n\nexport interface GeolocationVerifiedPayload {\n latitude: number;\n longitude: number;\n country: string;\n region?: string;\n is_compliant: boolean;\n}\n\nexport interface GeolocationBlockedPayload {\n latitude: number;\n longitude: number;\n country: string;\n region?: string;\n reasons: string[];\n}\n\nexport interface KycStatusChangedPayload {\n previous_status: string;\n new_status: string;\n provider?: string;\n}\n\nexport interface DecisionRecordedPayload {\n decision_id: string;\n decision_type: string;\n category: string;\n source: string;\n risk_score?: number;\n}\n\nexport interface LabelAppliedPayload {\n label_type: string;\n reasons?: string[];\n}\n\nexport interface LocationRequestCompletedPayload {\n request_id: string;\n status: string;\n latitude?: number;\n longitude?: number;\n}\n\nexport interface ComplianceCheckFailedPayload {\n check_type: string;\n reasons: string[];\n severity: string;\n}\n\nexport interface TaxReminderSentPayload {\n /** W-form the reminder is for (e.g. \"W-9\", \"W-8BEN\", \"W-8BEN-E\") */\n form_type: string;\n /** Sequential count of reminders sent in the current solicitation cycle */\n reminder_count: number;\n /** Configured maximum reminders per cycle (reminder_max_count) */\n max_count: number;\n}\n\n// --- Notification Envelope (the real notification-service producer payload) ---\n\nexport interface WebhookNotification {\n id: string;\n user_id?: string;\n title?: string;\n message?: string;\n}\n\n/**\n * The `notification.created` envelope emitted by notification-service. Unlike the\n * typed events it has no top-level `id`/`customer_id` and no `payload`; the data\n * is nested under `notification`.\n */\nexport interface NotificationWebhookEvent {\n id?: UUID;\n event_type: 'notification.created';\n tenant_id: string;\n environment: 'production' | 'sandbox';\n customer_id?: string;\n notification: WebhookNotification;\n timestamp: Timestamp;\n metadata?: Record<string, unknown>;\n}\n\n// --- Discriminated Union ---\n\nexport type WebhookEvent =\n | NotificationWebhookEvent\n | BaseWebhookEvent<'risk.score.changed', RiskScoreChangedPayload>\n | BaseWebhookEvent<'risk.category.changed', RiskCategoryChangedPayload>\n | BaseWebhookEvent<'profile.created', ProfileCreatedPayload>\n | BaseWebhookEvent<'profile.updated', ProfileUpdatedPayload>\n | BaseWebhookEvent<'geolocation.verified', GeolocationVerifiedPayload>\n | BaseWebhookEvent<'geolocation.blocked', GeolocationBlockedPayload>\n | BaseWebhookEvent<'kyc.status.changed', KycStatusChangedPayload>\n | BaseWebhookEvent<'kyc.approved', KycStatusChangedPayload>\n | BaseWebhookEvent<'kyc.declined', KycStatusChangedPayload>\n | BaseWebhookEvent<'decision.recorded', DecisionRecordedPayload>\n | BaseWebhookEvent<'label.applied', LabelAppliedPayload>\n | BaseWebhookEvent<'location_request.completed', LocationRequestCompletedPayload>\n | BaseWebhookEvent<'compliance.check.failed', ComplianceCheckFailedPayload>\n | BaseWebhookEvent<'tax.reminder.sent', TaxReminderSentPayload>;\n\n// --- Handler Config ---\n\nexport interface WebhookHandlerConfig {\n /** Webhook signing secret for signature verification */\n secret: string;\n /** Header name containing the signature (default: 'x-webhook-signature') */\n signatureHeader?: string;\n /** Maximum age of webhook event in ms (default: 300000 = 5 minutes) */\n tolerance?: number;\n /** Enable replay protection to reject duplicate event IDs (default: true) */\n replayProtection?: boolean;\n /** Pluggable dedup store for replay protection (default: in-memory, process-local). */\n dedupStore?: WebhookDedupStore;\n /** Accept the legacy body-only `sha256=<hex>` signature during migration (default: true). */\n allowLegacySignature?: boolean;\n}\n\n// --- Handler Types ---\n\nexport type WebhookEventHandler<T extends WebhookEventType = WebhookEventType> = (\n event: Extract<WebhookEvent, { event_type: T }>\n) => void | Promise<void>;\n\nexport type WebhookAnyHandler = (event: WebhookEvent) => void | Promise<void>;\n\n// --- AML Block Callback ---\n\n/** Watchlist category an AML screening matched. */\nexport type AmlCallbackCategory =\n | 'sanction'\n | 'pep'\n | 'adverse_media'\n | 'fraud'\n | 'terrorism'\n | 'narcotics'\n | 'financial_crime'\n | 'warning'\n | 'fitness_probity'\n | 'previous_client'\n | 'unknown'\n | (string & Record<string, never>);\n\nexport interface AmlBlockCallbackData {\n /** Your customer identifier — the one the screening ran against. */\n customer_id: string;\n /** Screened full name. Omitted when the screening had no full name. */\n customer_name?: string;\n /**\n * Derived from the number of matches against your tenant's risk thresholds —\n * not from the category. A sanction match is not automatically `high`.\n */\n risk_level: RiskLevel;\n /** The category that matched. `previous_client` is a match on your internal watchlist only. */\n category: AmlCallbackCategory;\n /** Total matches, including internal watchlist matches. */\n hits_count: number;\n /** Name of the AML alert rule that decided the block. */\n applied_rule?: string;\n /** ISO 8601 UTC time the screening ran. */\n screened_at?: Timestamp;\n}\n\n/**\n * Body POSTed to the webhook URL in your AML screening settings when a\n * screening matches a watchlist and the governing alert rule carries the\n * `block` reaction. Signed with `X-Webhook-Signature: sha256=<hex>`\n * (HMAC-SHA256 of the raw body).\n *\n * Sent only for blocks — nothing is delivered for a clear screening or for a\n * rule that only alerts. Screenings that run without a request from you (after\n * an accepted KYC, or after a name or date-of-birth change) are reported only\n * through this webhook.\n */\nexport interface AmlBlockCallbackEvent {\n /** Always `\"aml\"` — dispatch on this. */\n event: 'aml';\n /** The screening reference you supplied, or a generated identifier for automatic screenings. */\n reference: string;\n /** The screening record ID — unique per screening, so dedup on it. */\n resource_id: string;\n /** Always `\"blocked\"`. */\n status: 'blocked';\n /** Always `true`. */\n block: true;\n /**\n * Human-readable reason for display and audit. Wording is not stable — branch\n * on `data.category` and `data.risk_level` instead.\n */\n block_reason: string;\n data: AmlBlockCallbackData;\n}\n\n/**\n * Type guard for the AML block webhook. Narrows an already signature-verified,\n * parsed payload to {@link AmlBlockCallbackEvent}.\n */\nexport function isAmlBlockCallbackEvent(value: unknown): value is AmlBlockCallbackEvent {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { event?: unknown }).event === 'aml' &&\n (value as { block?: unknown }).block === true\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vesant-sdk",
3
- "version": "1.7.2",
3
+ "version": "1.8.0-dev.2b9e28d",
4
4
  "workspaces": [
5
5
  "packages/*"
6
6
  ],