@basis-theory/web-elements 3.0.0-beta.3 → 3.0.0-beta.5

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 (101) hide show
  1. package/dist/.vite/manifest.json +30 -8
  2. package/dist/basis-theory-sdk.es.js +1 -1
  3. package/dist/basis-theory-sdk.umd.js +1 -1
  4. package/dist/basis-theory-sdk.umd.js.map +1 -1
  5. package/dist/{create-card-DipDWgph.js → create-card-CB_YcP_4.js} +58 -20
  6. package/dist/create-card-CB_YcP_4.js.map +1 -0
  7. package/dist/create-card-display-kBupMJwe.js +280 -0
  8. package/dist/create-card-display-kBupMJwe.js.map +1 -0
  9. package/dist/create-copy-button-2XtKTEo3.js +236 -0
  10. package/dist/create-copy-button-2XtKTEo3.js.map +1 -0
  11. package/dist/{index-BBfuUaLw.js → index-Dyy7tm5Z.js} +709 -140
  12. package/dist/index-Dyy7tm5Z.js.map +1 -0
  13. package/dist/index.d.ts +1119 -0
  14. package/dist/loader/basis-theory.min.js +1 -1
  15. package/dist/sri.json +9 -9
  16. package/dist/stats.html +1 -1
  17. package/package.json +12 -12
  18. package/dist/api-client/src/api-client.d.ts +0 -11
  19. package/dist/api-client/src/api-client.d.ts.map +0 -1
  20. package/dist/api-client/src/http-client.d.ts +0 -24
  21. package/dist/api-client/src/http-client.d.ts.map +0 -1
  22. package/dist/api-client/src/index.d.ts +0 -9
  23. package/dist/api-client/src/index.d.ts.map +0 -1
  24. package/dist/api-client/src/services/sessions.d.ts +0 -19
  25. package/dist/api-client/src/services/sessions.d.ts.map +0 -1
  26. package/dist/api-client/src/services/token-intents.d.ts +0 -17
  27. package/dist/api-client/src/services/token-intents.d.ts.map +0 -1
  28. package/dist/api-client/src/services/tokens.d.ts +0 -19
  29. package/dist/api-client/src/services/tokens.d.ts.map +0 -1
  30. package/dist/api-client/src/types.d.ts +0 -313
  31. package/dist/api-client/src/types.d.ts.map +0 -1
  32. package/dist/create-card-DipDWgph.js.map +0 -1
  33. package/dist/index-BBfuUaLw.js.map +0 -1
  34. package/dist/postmessage/src/client.d.ts +0 -7
  35. package/dist/postmessage/src/client.d.ts.map +0 -1
  36. package/dist/postmessage/src/event-map.d.ts +0 -135
  37. package/dist/postmessage/src/event-map.d.ts.map +0 -1
  38. package/dist/postmessage/src/index.d.ts +0 -9
  39. package/dist/postmessage/src/index.d.ts.map +0 -1
  40. package/dist/postmessage/src/server.d.ts +0 -11
  41. package/dist/postmessage/src/server.d.ts.map +0 -1
  42. package/dist/postmessage/src/types.d.ts +0 -71
  43. package/dist/postmessage/src/types.d.ts.map +0 -1
  44. package/dist/shared/src/api-url-resolver.d.ts +0 -22
  45. package/dist/shared/src/api-url-resolver.d.ts.map +0 -1
  46. package/dist/shared/src/debug-logger.d.ts +0 -16
  47. package/dist/shared/src/debug-logger.d.ts.map +0 -1
  48. package/dist/shared/src/deep-sanitization.d.ts +0 -24
  49. package/dist/shared/src/deep-sanitization.d.ts.map +0 -1
  50. package/dist/shared/src/errors.d.ts +0 -93
  51. package/dist/shared/src/errors.d.ts.map +0 -1
  52. package/dist/shared/src/generate-id.d.ts +0 -13
  53. package/dist/shared/src/generate-id.d.ts.map +0 -1
  54. package/dist/shared/src/index.d.ts +0 -13
  55. package/dist/shared/src/index.d.ts.map +0 -1
  56. package/dist/shared/src/logger-context.d.ts +0 -25
  57. package/dist/shared/src/logger-context.d.ts.map +0 -1
  58. package/dist/web-elements/src/BasisTheory.d.ts +0 -47
  59. package/dist/web-elements/src/BasisTheory.d.ts.map +0 -1
  60. package/dist/web-elements/src/basis-theory.d.ts +0 -62
  61. package/dist/web-elements/src/basis-theory.d.ts.map +0 -1
  62. package/dist/web-elements/src/elements/create-card-number.d.ts +0 -14
  63. package/dist/web-elements/src/elements/create-card-number.d.ts.map +0 -1
  64. package/dist/web-elements/src/elements/create-card.d.ts +0 -37
  65. package/dist/web-elements/src/elements/create-card.d.ts.map +0 -1
  66. package/dist/web-elements/src/elements/create-cvv.d.ts +0 -10
  67. package/dist/web-elements/src/elements/create-cvv.d.ts.map +0 -1
  68. package/dist/web-elements/src/elements/create-expiry.d.ts +0 -10
  69. package/dist/web-elements/src/elements/create-expiry.d.ts.map +0 -1
  70. package/dist/web-elements/src/elements/create-text.d.ts +0 -13
  71. package/dist/web-elements/src/elements/create-text.d.ts.map +0 -1
  72. package/dist/web-elements/src/index.d.ts +0 -27
  73. package/dist/web-elements/src/index.d.ts.map +0 -1
  74. package/dist/web-elements/src/mounter/create-mounter.d.ts +0 -11
  75. package/dist/web-elements/src/mounter/create-mounter.d.ts.map +0 -1
  76. package/dist/web-elements/src/theme/default-theme.d.ts +0 -22
  77. package/dist/web-elements/src/theme/default-theme.d.ts.map +0 -1
  78. package/dist/web-elements/src/theme/inject-theme-dark.d.ts +0 -13
  79. package/dist/web-elements/src/theme/inject-theme-dark.d.ts.map +0 -1
  80. package/dist/web-elements/src/theme/inject-theme.d.ts +0 -20
  81. package/dist/web-elements/src/theme/inject-theme.d.ts.map +0 -1
  82. package/dist/web-elements/src/types/events.d.ts +0 -137
  83. package/dist/web-elements/src/types/events.d.ts.map +0 -1
  84. package/dist/web-elements/src/types/theme.d.ts +0 -91
  85. package/dist/web-elements/src/types/theme.d.ts.map +0 -1
  86. package/dist/web-elements/src/types.d.ts +0 -537
  87. package/dist/web-elements/src/types.d.ts.map +0 -1
  88. package/dist/web-elements/src/utils/create-event-dispatcher.d.ts +0 -47
  89. package/dist/web-elements/src/utils/create-event-dispatcher.d.ts.map +0 -1
  90. package/dist/web-elements/src/utils/create-iframe.d.ts +0 -10
  91. package/dist/web-elements/src/utils/create-iframe.d.ts.map +0 -1
  92. package/dist/web-elements/src/utils/resolve-element-references.d.ts +0 -20
  93. package/dist/web-elements/src/utils/resolve-element-references.d.ts.map +0 -1
  94. package/dist/web-elements/src/utils/validate-element-options.d.ts +0 -11
  95. package/dist/web-elements/src/utils/validate-element-options.d.ts.map +0 -1
  96. package/dist/web-elements/src/utils/validate-sdk-config.d.ts +0 -15
  97. package/dist/web-elements/src/utils/validate-sdk-config.d.ts.map +0 -1
  98. package/dist/web-elements/src/utils/warn-unknown-keys.d.ts +0 -15
  99. package/dist/web-elements/src/utils/warn-unknown-keys.d.ts.map +0 -1
  100. package/dist/web-elements/src/version.d.ts +0 -25
  101. package/dist/web-elements/src/version.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Dyy7tm5Z.js","sources":["../../shared/dist/deep-sanitization.js","../../shared/dist/debug-logger.js","../../shared/dist/generate-id.js","../../shared/dist/logger-context.js","../../shared/dist/errors.js","../../shared/dist/proxy-validation.js","../../postmessage/dist/client.js","../src/mounter/create-mounter.ts","../src/utils/create-iframe.ts","../src/utils/create-event-dispatcher.ts","../src/elements/create-card-number.ts","../src/elements/create-cvv.ts","../src/elements/create-expiry.ts","../src/elements/create-text.ts","../src/utils/resolve-element-references.ts","../src/theme/default-theme.ts","../src/utils/warn-unknown-keys.ts","../src/utils/validate-sdk-config.ts","../src/utils/validate-element-options.ts","../src/BasisTheory.ts","../src/version.ts","../src/index.ts"],"sourcesContent":["/**\n * FR-005: Deep Logger Sanitization\n * PCI-DSS Requirement 3.2 - Never Store Sensitive Authentication Data\n *\n * Recursively sanitizes objects to prevent PAN/CVV leakage in logs.\n */\n/**\n * Sensitive field patterns for PAN-like data (mask to first6 + last4)\n */\nconst PAN_PATTERNS = [\n /cardnumber/i,\n /^pan$/i,\n /accountnumber/i,\n /^number$/i, // Common in card objects\n];\n/**\n * Sensitive field patterns for security codes (redact completely)\n */\nconst REDACT_PATTERNS = [\n /cvv/i,\n /cvc/i,\n /cvv2/i,\n /securitycode/i,\n /pin/i,\n /password/i,\n /secret/i,\n /token/i,\n /ssn/i,\n /track/i,\n /session_key/i,\n /^apikey$/i,\n];\n/**\n * Check if a field name matches PAN patterns\n */\nexport const isPANField = (key) => {\n return PAN_PATTERNS.some((pattern) => pattern.test(key));\n};\n/**\n * Check if a field name matches redact patterns\n */\nexport const isRedactField = (key) => {\n return REDACT_PATTERNS.some((pattern) => pattern.test(key));\n};\n/**\n * Mask PAN to show first 6 + last 4 digits\n * Example: \"4111111111111111\" -> \"411111******1111\"\n * Always uses at least 6 asterisks for consistent masking across card types\n */\nconst maskPAN = (value) => {\n // Remove non-digits\n const digits = value.replace(/\\D/g, '');\n // Need at least 10 digits to mask (6 + 4)\n if (digits.length < 10) {\n return '***'; // Too short, redact completely\n }\n const first6 = digits.substring(0, 6);\n const last4 = digits.substring(digits.length - 4);\n // Always use at least 6 asterisks to avoid leaking card length\n const maskedLength = Math.max(digits.length - 10, 6);\n const masked = '*'.repeat(maskedLength);\n return `${first6}${masked}${last4}`;\n};\n/**\n * Check if a string value looks like a PAN by value (13-19 digit string)\n */\nconst looksLikePAN = (value) => {\n const digits = value.replace(/[\\s-]/g, '');\n return /^\\d{13,19}$/.test(digits);\n};\n/**\n * Sanitize a single value based on field name\n */\nconst sanitizeValue = (key, value) => {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return value;\n }\n // Handle special types\n if (typeof value === 'function') {\n return '[Function]';\n }\n if (typeof value === 'symbol') {\n return '[Symbol]';\n }\n if (value instanceof RegExp) {\n return '[RegExp]';\n }\n if (value instanceof Date) {\n return value; // Preserve Date objects\n }\n // Check if field is sensitive\n if (isPANField(key)) {\n // PAN field - mask it\n if (typeof value === 'string') {\n return maskPAN(value);\n }\n // Non-string PAN field - redact for safety\n return '***';\n }\n if (isRedactField(key)) {\n // Security code field - redact completely\n return '***';\n }\n // Auto-detect PAN-like strings by value content (covers field names not in PAN_PATTERNS)\n if (typeof value === 'string' && looksLikePAN(value)) {\n return maskPAN(value);\n }\n // Not sensitive - return as-is (will be recursed if object/array)\n return value;\n};\n/**\n * Deep sanitize an unknown value\n *\n * @param data - Data to sanitize\n * @param depth - Current recursion depth (max 5)\n * @param visited - WeakSet to track visited objects (circular reference detection)\n * @returns Sanitized data\n */\nexport const sanitizeDeep = (data, depth = 0, ancestors = new WeakSet()) => {\n // Max depth check (AC4)\n if (depth >= 5) {\n return '[Max Depth]';\n }\n // Handle null/undefined\n if (data === null || data === undefined) {\n return data;\n }\n // Handle string primitives — auto-detect PAN-like values (AC5 array items)\n if (typeof data === 'string') {\n return looksLikePAN(data) ? maskPAN(data) : data;\n }\n // Handle other primitives (numbers, booleans)\n if (typeof data !== 'object') {\n return data;\n }\n // Handle special object types\n if (data instanceof RegExp) {\n return '[RegExp]';\n }\n if (data instanceof Date) {\n return data;\n }\n // Circular reference check using ancestor tracking (AC3)\n // Uses backtracking so sibling objects sharing a reference are fully processed\n if (ancestors.has(data)) {\n return '[Circular]';\n }\n ancestors.add(data);\n let result;\n // Handle arrays (AC5)\n if (Array.isArray(data)) {\n result = data.map((item) => sanitizeDeep(item, depth + 1, ancestors));\n }\n else {\n // Handle objects (AC1, AC2)\n const sanitized = {};\n for (const [key, value] of Object.entries(data)) {\n // Sanitize the value based on key name\n const sanitizedValue = sanitizeValue(key, value);\n // If value is an object/array, recurse into it\n if (sanitizedValue !== null && typeof sanitizedValue === 'object') {\n sanitized[key] = sanitizeDeep(sanitizedValue, depth + 1, ancestors);\n }\n else {\n sanitized[key] = sanitizedValue;\n }\n }\n result = sanitized;\n }\n // Backtrack: remove from ancestors so sibling references are processed correctly\n ancestors.delete(data);\n return result;\n};\n","/**\n * Universal Debug Logger\n * PCI-compliant logging that never exposes sensitive data\n *\n * FR-005: Deep Logger Sanitization\n * - Recursively sanitizes nested objects/arrays\n * - Masks PANs to first 6 + last 4\n * - Redacts CVV/PIN/passwords completely\n * - Handles circular references\n */\nimport { isPANField, isRedactField, sanitizeDeep } from './deep-sanitization';\n/**\n * Sanitize metadata for debug logging (FR-005, PCI-DSS Req 10)\n *\n * Top-level sensitive fields (PAN/CVV/PIN/etc.) are REMOVED and replaced with\n * a `{key}_length` entry recording only the byte-length of the original value.\n * This satisfies PCI-DSS Req 10 — even masked PANs (first-6/last-4) contain\n * partial cardholder data and must not appear in logs.\n *\n * Non-sensitive fields are recursively deep-sanitized so nested PANs are still\n * masked at lower levels (e.g. `card.number`).\n */\nconst sanitizeMetadata = (metadata) => {\n const result = {};\n for (const [key, value] of Object.entries(metadata)) {\n if (isPANField(key) || isRedactField(key)) {\n // Replace sensitive field with its length only — no cardholder data in logs\n const len = typeof value === 'string'\n ? value.length\n : typeof value === 'number'\n ? String(value).length\n : 0;\n result[`${key}_length`] = len;\n }\n else {\n // Recursively deep-sanitize non-sensitive fields (masks nested PANs/CVVs)\n result[key] = sanitizeDeep(value);\n }\n }\n return result;\n};\n/**\n * Format timestamp for logs (HH:MM:SS.mmm)\n */\nconst formatTimestamp = () => {\n const now = new Date();\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n const milliseconds = String(now.getMilliseconds()).padStart(3, '0');\n return `${hours}:${minutes}:${seconds}.${milliseconds}`;\n};\n/**\n * Create a debug logger for a specific package\n */\nexport const createDebugLogger = (packageName, enabled) => {\n if (!enabled) {\n return () => { }; // No-op when disabled\n }\n return (action, metadata) => {\n const timestamp = formatTimestamp();\n const sanitized = metadata ? sanitizeMetadata(metadata) : {};\n console.log(`🔍 [${timestamp}] [${packageName}] ${action}`, sanitized);\n };\n};\n","/**\n * Generate a unique identifier for elements\n *\n * Uses crypto.randomUUID() if available (Node 14.17+, all modern browsers)\n * Falls back to Math.random() for older environments (rare)\n *\n * Format: Standard UUID v4 (e.g., \"550e8400-e29b-41d4-a716-446655440000\")\n *\n * Note: This utility is rarely needed as the coordinator generates element IDs\n * via CMD_REGISTER_ELEMENT using crypto.randomUUID() directly.\n */\nexport const generateId = () => {\n // Modern approach: Use Web Crypto API (standard in all environments)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for ancient environments (extremely rare in 2024+)\n // This produces a UUID-like format but is not cryptographically secure\n // Generate enough random characters to fill UUID format (8-4-4-4-12 = 32 chars)\n const random = () => Math.random().toString(36).substring(2);\n const randomPart = (random() + random() + random() + random()).substring(0, 32);\n // Format as UUID-like string for consistency (8-4-4-4-12)\n return `${randomPart.substring(0, 8)}-${randomPart.substring(8, 12)}-${randomPart.substring(12, 16)}-${randomPart.substring(16, 20)}-${randomPart.substring(20, 32)}`;\n};\n","/**\n * Shared Logger Context\n *\n * Provides a global logger instance that can be controlled by the coordinator.\n * Elements import this and use the shared logger without passing it around.\n */\nimport { createDebugLogger } from './debug-logger';\n/**\n * Global logger instance (controlled by coordinator)\n */\nlet globalLogger = () => { }; // Default: disabled\n/**\n * Configure the global logger (called by coordinator on init)\n *\n * @param packageName - Package name for log prefix\n * @param enabled - Whether debug logging is enabled\n */\nexport const configureLogger = (packageName, enabled) => {\n globalLogger = createDebugLogger(packageName, enabled);\n};\n/**\n * Get the current logger instance\n *\n * Elements use this to get the shared logger\n */\nexport const getLogger = () => globalLogger;\n/**\n * Convenience: Log directly without getting logger first\n */\nexport const log = (action, metadata) => {\n globalLogger(action, metadata);\n};\n","/**\n * BasisTheory Structured Error Types\n *\n * Functional error factories for consistent error handling across SDK, Elements, and API Client.\n */\n/**\n * Base BasisTheoryError factory\n * Creates error objects with consistent structure\n */\nexport const createBasisTheoryError = (code, message, details) => {\n const error = new Error(message);\n error.name = 'BasisTheoryError';\n error.code = code;\n error.details = details;\n // Maintain proper stack trace\n if (Error.captureStackTrace) {\n Error.captureStackTrace(error, createBasisTheoryError);\n }\n // Serialize error to JSON\n error.toJSON = () => ({\n name: error.name,\n code: error.code,\n message: error.message,\n ...(error.details && { details: error.details }),\n });\n return error;\n};\n/**\n * BasisTheoryError - Generic base error\n */\nexport const BasisTheoryError = (code, message, details) => {\n const error = createBasisTheoryError(code, message, details);\n error.name = 'BasisTheoryError';\n return error;\n};\nexport const ValidationError = (message, field, details) => {\n const error = createBasisTheoryError('VALIDATION_ERROR', message, field ? { field, ...details } : details);\n error.name = 'ValidationError';\n error.field = field;\n return error;\n};\n/**\n * CoordinatorError - Errors from coordinator iframe operations\n *\n * @example\n * throw CoordinatorError('Tokenization failed', {\n * operation: 'tokenize',\n * elementId: 'card-123'\n * });\n */\nexport const CoordinatorError = (message, details) => {\n const error = createBasisTheoryError('COORDINATOR_ERROR', message, details);\n error.name = 'CoordinatorError';\n return error;\n};\nexport const ElementError = (message, elementId, details) => {\n const error = createBasisTheoryError('ELEMENT_ERROR', message, elementId ? { elementId, ...details } : details);\n error.name = 'ElementError';\n error.elementId = elementId;\n return error;\n};\nexport const NetworkError = (message, statusCode, details) => {\n const error = createBasisTheoryError('NETWORK_ERROR', message, statusCode ? { statusCode, ...details } : details);\n error.name = 'NetworkError';\n error.statusCode = statusCode;\n return error;\n};\n/**\n * ConfigurationError - SDK/Element configuration errors\n *\n * @example\n * throw ConfigurationError('Invalid API key', {\n * provided: 'key_test_invalid',\n * expected: 'key_test_* or key_live_*'\n * });\n */\nexport const ConfigurationError = (message, details) => {\n const error = createBasisTheoryError('CONFIGURATION_ERROR', message, details);\n error.name = 'ConfigurationError';\n return error;\n};\n/**\n * EncryptionError - Client-side encryption errors\n *\n * @example\n * throw EncryptionError('JWE encryption failed', 'ENCRYPTION_FAILED', {\n * algorithm: 'ECDH-ES',\n * keyId: 'key_123'\n * });\n */\nexport const EncryptionError = (message, code = 'ENCRYPTION_ERROR', details) => {\n const error = createBasisTheoryError(code, message, details);\n error.name = 'EncryptionError';\n return error;\n};\n","/**\n * Proxy Request Validation\n *\n * Shared validation utilities for proxy requests across SDK and Coordinator.\n * Ensures consistent security controls and validation behavior.\n */\nimport { ValidationError } from './errors';\n/**\n * Security: Allowed URL schemes for proxy requests\n *\n * Only HTTPS are permitted to prevent:\n * - javascript: XSS attacks\n * - file:// local file access\n * - data: data exfiltration\n * - Other dangerous schemes\n */\nexport const ALLOWED_PROXY_SCHEMES = new Set(['https:']);\n/**\n * Allowed HTTP methods for proxy requests\n */\nexport const ALLOWED_METHODS = new Set([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n]);\n/**\n * Security: Headers that could enable request smuggling or bypass controls\n *\n * These headers are blocked to prevent various attack vectors:\n *\n * Request Smuggling Prevention:\n * - host: Prevents host header injection attacks\n * - content-length: Prevents content-length manipulation for request smuggling\n * - transfer-encoding: Prevents TE.CL and CL.TE smuggling attacks\n * - te: Transfer-Encoding negotiation header used in smuggling\n * - trailer: Used with chunked encoding, potential smuggling vector\n *\n * Connection Manipulation Prevention:\n * - connection: Prevents hop-by-hop header manipulation\n * - upgrade: Prevents protocol upgrade attacks (e.g., WebSocket hijacking)\n * - keep-alive: Prevents connection persistence manipulation\n * - proxy-connection: Non-standard proxy connection header\n *\n * Proxy Bypass Prevention:\n * - via: Prevents proxy chain manipulation\n * - proxy-authorization: Prevents authentication to intermediate proxies\n *\n * BasisTheory Credential Protection:\n * - bt-api-key: Prevents API key override/leakage\n * - bt-proxy-key: Prevents proxy key override/leakage\n * - bt-idempotency-key: Prevents idempotency key manipulation\n */\nexport const FORBIDDEN_PROXY_HEADERS = new Set([\n // Request smuggling prevention\n 'host',\n 'content-length',\n 'transfer-encoding',\n 'te',\n 'trailer',\n // Connection manipulation prevention\n 'connection',\n 'upgrade',\n 'keep-alive',\n 'proxy-connection',\n // Proxy bypass prevention\n 'via',\n 'proxy-authorization',\n // BasisTheory credential protection\n 'bt-api-key',\n 'bt-proxy-key',\n 'bt-proxy-url',\n 'bt-idempotency-key',\n // Forwarded headers\n 'x-forwarded-for',\n 'x-forwarded-host',\n 'x-real-ip',\n // SDK owns serialization format — body is always JSON.stringify'd\n 'content-type',\n]);\n/**\n * Validate that headers don't contain forbidden values\n *\n * @param headers - Headers object to validate\n * @throws ValidationError if a forbidden header is found\n */\nexport const validateProxyHeaders = (headers) => {\n if (!headers)\n return;\n for (const [key, value] of Object.entries(headers)) {\n if (/[\\r\\n]/.test(value)) {\n throw ValidationError(`Header '${key}' value contains illegal CRLF`, 'headers');\n }\n if (/[\\r\\n]/.test(key)) {\n throw ValidationError(`Header name '${key}' contains illegal CRLF`, 'headers');\n }\n if (FORBIDDEN_PROXY_HEADERS.has(key.toLowerCase().trim())) {\n throw ValidationError(`Header '${key}' is not allowed in proxy requests`, 'headers');\n }\n }\n};\n/**\n * Parse an IP address from various encoded formats\n *\n * Handles:\n * - Standard dotted decimal: 127.0.0.1\n * - Hex-encoded: 0x7f000001\n * - Decimal-encoded: 2130706433\n * - Octal-encoded: 0177.0.0.1\n * - Mixed formats: 0x7f.0.0.1\n *\n * @param hostname - Hostname that may be an encoded IP\n * @returns Parsed IP as array of 4 octets, or null if not a valid IP\n */\nconst parseIPv4 = (hostname) => {\n // Remove brackets if present (shouldn't happen for IPv4 but be safe)\n const clean = hostname.replace(/^\\[|\\]$/g, '');\n // Check for single decimal number (e.g., 2130706433 = 127.0.0.1)\n if (/^(0x[\\da-f]+|\\d+)$/i.test(clean)) {\n const num = clean.toLowerCase().startsWith('0x')\n ? parseInt(clean, 16)\n : parseInt(clean, 10);\n if (num >= 0 && num <= 0xffffffff) {\n return [\n (num >>> 24) & 0xff,\n (num >>> 16) & 0xff,\n (num >>> 8) & 0xff,\n num & 0xff,\n ];\n }\n return null;\n }\n // Check for dotted format (potentially with hex/octal octets)\n const parts = clean.split('.');\n if (parts.length !== 4) {\n return null;\n }\n const octets = [];\n for (const part of parts) {\n let value;\n if (part.toLowerCase().startsWith('0x')) {\n // Hex: 0x7f\n value = parseInt(part, 16);\n }\n else if (part.startsWith('0') && part.length > 1 && !/[89]/.test(part)) {\n // Octal: 0177 (but not 08 or 09 which are invalid octal)\n value = parseInt(part, 8);\n }\n else {\n // Decimal\n value = parseInt(part, 10);\n }\n if (isNaN(value) || value < 0 || value > 255) {\n return null;\n }\n octets.push(value);\n }\n return octets;\n};\n/**\n * Check if an IPv4 address is in a private/internal range\n *\n * Blocked ranges:\n * - 127.0.0.0/8: Loopback\n * - 10.0.0.0/8: RFC1918 Class A private\n * - 172.16.0.0/12: RFC1918 Class B private\n * - 192.168.0.0/16: RFC1918 Class C private\n * - 169.254.0.0/16: Link-local (includes AWS IMDS 169.254.169.254)\n * - 0.0.0.0/8: \"This\" network\n *\n * @param octets - Array of 4 octets representing the IP\n * @returns true if the IP is private/internal\n */\nconst isPrivateIPv4 = (octets) => {\n const a = octets[0];\n const b = octets[1];\n // Fail closed: block if input is malformed (security guard should deny on unknown)\n if (a === undefined || b === undefined)\n return true;\n // 127.0.0.0/8 - Loopback\n if (a === 127)\n return true;\n // 10.0.0.0/8 - RFC1918 Class A\n if (a === 10)\n return true;\n // 172.16.0.0/12 - RFC1918 Class B (172.16.x.x - 172.31.x.x)\n if (a === 172 && b >= 16 && b <= 31)\n return true;\n // 192.168.0.0/16 - RFC1918 Class C\n if (a === 192 && b === 168)\n return true;\n // 169.254.0.0/16 - Link-local (AWS IMDS at 169.254.169.254)\n if (a === 169 && b === 254)\n return true;\n // 0.0.0.0/8 - \"This\" network\n if (a === 0)\n return true;\n return false;\n};\n/**\n * Check if a hostname is an IPv6 loopback, link-local, or private address\n *\n * Blocked:\n * - ::1 - IPv6 loopback\n * - fe80::/10 - IPv6 link-local\n * - fc00::/7 - IPv6 Unique Local Addresses (ULA, equivalent to RFC1918)\n * - ::ffff:x.x.x.x - IPv4-mapped IPv6 (checked via IPv4 rules)\n *\n * Note: URL API normalizes IPv4-mapped IPv6 to hex format:\n * - ::ffff:127.0.0.1 becomes ::ffff:7f00:1\n * - ::ffff:169.254.169.254 becomes ::ffff:a9fe:a9fe\n *\n * @param hostname - Hostname to check (with or without brackets)\n * @returns true if the hostname is a blocked IPv6 address\n */\nconst isBlockedIPv6 = (hostname) => {\n // Remove brackets if present\n const clean = hostname.replace(/^\\[|\\]$/g, '').toLowerCase();\n // Check for IPv6 loopback (::1 in various forms)\n if (clean === '::1' ||\n clean === '0:0:0:0:0:0:0:1' ||\n clean === '0000:0000:0000:0000:0000:0000:0000:0001') {\n return true;\n }\n // Check for IPv6 link-local (fe80::/10)\n if (clean.startsWith('fe8') || clean.startsWith('fe9') ||\n clean.startsWith('fea') || clean.startsWith('feb')) {\n return true;\n }\n // Check for IPv6 Unique Local Addresses (fc00::/7 - equivalent to RFC1918 private)\n if (clean.startsWith('fc') || clean.startsWith('fd')) {\n return true;\n }\n // Check for IPv4-mapped IPv6 in dotted format (::ffff:x.x.x.x)\n const ipv4MappedDotted = clean.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/);\n if (ipv4MappedDotted) {\n const ipv4Part = ipv4MappedDotted[1];\n if (ipv4Part) {\n const ipv4Octets = parseIPv4(ipv4Part);\n if (ipv4Octets && isPrivateIPv4(ipv4Octets)) {\n return true;\n }\n }\n }\n // Check for IPv4-mapped IPv6 in hex format (::ffff:XXXX:XXXX)\n // URL API normalizes ::ffff:127.0.0.1 to ::ffff:7f00:1\n const ipv4MappedHex = clean.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n if (ipv4MappedHex) {\n const highPart = ipv4MappedHex[1];\n const lowPart = ipv4MappedHex[2];\n // Fail closed: block if capture groups unexpectedly absent\n if (!highPart || !lowPart) {\n return true;\n }\n const high = parseInt(highPart, 16);\n const low = parseInt(lowPart, 16);\n // Convert to IPv4 octets\n const octets = [\n (high >>> 8) & 0xff,\n high & 0xff,\n (low >>> 8) & 0xff,\n low & 0xff,\n ];\n if (isPrivateIPv4(octets)) {\n return true;\n }\n }\n return false;\n};\n/**\n * Validate that a URL doesn't target internal/private resources (SSRF prevention)\n *\n * @param parsed - Parsed URL object\n * @throws ValidationError if URL targets internal resources\n */\nconst validateSsrfProtection = (parsed) => {\n const hostname = parsed.hostname.toLowerCase();\n // Block userinfo (credentials in URL)\n // - Leaks credentials to proxy logs\n // - Parser confusion attacks: https://evil@target.com@attacker.com\n if (parsed.username || parsed.password) {\n throw ValidationError('URL must not contain userinfo (username/password)', 'url');\n }\n // Block localhost (URL API doesn't resolve DNS, so we must check the hostname)\n if (hostname === 'localhost') {\n throw ValidationError('URL must not target localhost', 'url');\n }\n // Check for IPv6 addresses (in brackets)\n if (hostname.startsWith('[') || isBlockedIPv6(hostname)) {\n if (isBlockedIPv6(hostname)) {\n throw ValidationError('URL must not target loopback or link-local IPv6 addresses', 'url');\n }\n }\n // Check for IPv4 addresses (including encoded formats)\n const ipv4Octets = parseIPv4(hostname);\n if (ipv4Octets && isPrivateIPv4(ipv4Octets)) {\n throw ValidationError('URL must not target private or internal IP addresses', 'url');\n }\n};\n/**\n * Validate URL for proxy requests\n *\n * Performs comprehensive URL validation:\n * 1. URL is well-formed\n * 2. Scheme is https: only\n * 3. No userinfo (username/password) in URL\n * 4. No internal/private IP addresses (SSRF prevention)\n * 5. No blocked hostnames (cloud metadata, localhost, etc.)\n *\n * @param url - URL string to validate\n * @throws ValidationError if URL fails any validation\n */\nconst validateProxyUrl = (url) => {\n let parsed;\n try {\n parsed = new URL(url);\n }\n catch {\n throw ValidationError('Invalid URL format', 'url');\n }\n // Validate scheme\n if (!ALLOWED_PROXY_SCHEMES.has(parsed.protocol)) {\n throw ValidationError(`URL scheme '${parsed.protocol}' is not allowed. Only https: is permitted`, 'url');\n }\n // Validate SSRF protection (userinfo, private IPs, blocked hostnames)\n validateSsrfProtection(parsed);\n};\n/**\n * Validate proxy request options (url XOR proxyKey)\n *\n * Ensures exactly one of `url` or `proxyKey` is provided.\n * - `url`: Ephemeral proxy - destination URL provided at request time\n * - `proxyKey`: Pre-configured proxy - uses server-side proxy configuration\n *\n * When `url` is provided, also validates:\n * - URL is well-formed\n * - URL scheme is https: only (prevents javascript:, file://, http:, etc.)\n * - No userinfo (username/password) in URL\n * - No private/internal IP addresses (SSRF prevention)\n * - No blocked hostnames (cloud metadata, localhost, etc.)\n *\n * @param url - Destination URL (optional)\n * @param proxyKey - Pre-configured proxy key (optional)\n * @throws ValidationError if neither or both are provided, or if URL is invalid\n */\nexport const validateProxyTarget = (url, proxyKey) => {\n const hasUrl = typeof url === 'string' && url.length > 0;\n const hasKey = typeof proxyKey === 'string' && proxyKey.length > 0;\n if (hasUrl === hasKey) {\n throw ValidationError('Specify exactly one of url or proxyKey', 'url/proxyKey');\n }\n // Validate URL when url is provided (scheme + SSRF protection)\n if (hasUrl) {\n validateProxyUrl(url);\n }\n};\n/**\n * Validate complete proxy request options\n *\n * Performs all proxy validation:\n * 1. Validates options is a plain object (if provided)\n * 2. Validates url XOR proxyKey requirement\n * 3. Validates headers don't contain forbidden values\n * 4. When `method` is present, validates it is an allowed HTTP verb\n *\n * @param options - Proxy request options\n * @throws ValidationError on validation failure\n */\nexport const validateProxyOptions = (options) => {\n if (options !== undefined && (typeof options !== 'object' || options === null)) {\n throw ValidationError('Proxy options must be a plain object', 'options');\n }\n if (options?.method !== undefined && !ALLOWED_METHODS.has(options.method)) {\n throw ValidationError(`Method '${options.method}' is not allowed`, 'method');\n }\n validateProxyTarget(options?.url, options?.proxyKey);\n validateProxyHeaders(options?.headers);\n};\n","/**\n * PostMessage Client (Parent Side)\n * Production-ready client for sending requests to iframe with retry logic\n */\nimport { createDebugLogger, BasisTheoryError, generateId, } from '@basis-theory-elements/shared';\n// Default retry configuration\nconst DEFAULT_RETRY_CONFIG = {\n maxRetries: 2,\n initialDelay: 500,\n maxDelay: 3000,\n backoffFactor: 2,\n};\n// Helper: Calculate exponential backoff delay\nconst getRetryDelay = (attempt, config) => {\n const delay = config.initialDelay * Math.pow(config.backoffFactor, attempt);\n return Math.min(delay, config.maxDelay);\n};\n// Helper: Sleep for retry delay\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nexport const createPostMessageClient = (iframe, config) => {\n const pendingRequests = new Map();\n const eventSubscribers = new Map();\n const log = createDebugLogger('PostMessageClient', config.debug || false);\n const isValidOrigin = (origin) => {\n return origin === config.targetOrigin;\n };\n const handleMessage = (event) => {\n // 1. ✅ Quick filter: Ignore noise from browser extensions (React DevTools, etc)\n const { nonce, type, payload, error } = event.data || {};\n if (!type) {\n // Silently ignore - likely browser extension spam\n return;\n }\n // 2. ✅ Origin validation (CRITICAL for security)\n if (!isValidOrigin(event.origin)) {\n log('Rejected message (origin mismatch)', {\n receivedOrigin: event.origin,\n expectedOrigin: config.targetOrigin,\n messageType: type,\n });\n return;\n }\n // 🎯 Source window validation - only accept from OUR iframe!\n // This prevents cross-iframe message leakage and impersonation attacks\n // SECURITY: Reject null sources to prevent any script from impersonating iframe\n if (event.source !== iframe.contentWindow) {\n // Silently reject messages from other iframes or non-iframe sources\n return;\n }\n // 3. ✅ Check if this is a response to a pending request (has nonce)\n if (nonce) {\n const pending = pendingRequests.get(nonce);\n if (pending) {\n // Log only when nonce matches a pending request (reduces duplicate log spam)\n log('Message received', {\n origin: event.origin,\n expectedOrigin: config.targetOrigin,\n type,\n nonce,\n });\n // 4. ✅ Cleanup\n clearTimeout(pending.timeout);\n pendingRequests.delete(nonce);\n // 5. ✅ Resolve or reject\n if (error) {\n // Create error with [CODE] Message format for backward compatibility\n const reconstructedError = BasisTheoryError(error.code, `[${error.code}] ${error.message}`);\n // Attach all error properties directly (not in details)\n Object.assign(reconstructedError, {\n ...(error.status !== undefined && { status: error.status }),\n ...(error.statusCode !== undefined && {\n statusCode: error.statusCode,\n }),\n ...(error.validationErrors && {\n validationErrors: error.validationErrors,\n }),\n ...(error.body && { body: error.body }),\n ...(error.retryCount !== undefined && {\n retryCount: error.retryCount,\n }),\n ...(error.details && { details: error.details }),\n });\n pending.reject(reconstructedError);\n }\n else {\n pending.resolve(payload);\n }\n return;\n }\n // Silently ignore responses with non-matching nonces (prevents duplicate log spam)\n return;\n }\n // 6. ✅ Handle as an event (no nonce = unsolicited message from iframe)\n const subscribers = eventSubscribers.get(type);\n if (subscribers && subscribers.size > 0) {\n // Log only when there are actual subscribers (relevant events only)\n log('Event received', {\n origin: event.origin,\n expectedOrigin: config.targetOrigin,\n type,\n nonce,\n subscriberCount: subscribers.size,\n });\n subscribers.forEach((callback) => {\n try {\n callback(payload);\n }\n catch (err) {\n log('Error in event subscriber', {\n type,\n error: err.message\n });\n }\n });\n }\n else if (!nonce) {\n // Event with no subscribers - log for debugging remount issues\n log('Event received but no subscribers', {\n type,\n availableSubscribers: Array.from(eventSubscribers.keys()),\n });\n }\n };\n // Start listening\n window.addEventListener('message', handleMessage);\n // Parse retry config\n const retryConfig = typeof config.retries === 'number'\n ? { ...DEFAULT_RETRY_CONFIG, maxRetries: config.retries }\n : typeof config.retries === 'object'\n ? config.retries\n : DEFAULT_RETRY_CONFIG;\n // Internal: Send single request (no retry)\n const sendRequestOnce = (type, payload) => {\n return new Promise((resolve, reject) => {\n const nonce = generateId();\n const timestamp = Date.now();\n // Check iframe ready BEFORE setting up timeout\n if (!iframe.contentWindow) {\n reject(BasisTheoryError('IFRAME_NOT_READY', 'Iframe not ready'));\n return;\n }\n // Timeout handling\n const timeout = setTimeout(() => {\n pendingRequests.delete(nonce);\n reject(BasisTheoryError('REQUEST_TIMEOUT', `Request timeout: ${type} (${config.timeout || 5000}ms)`));\n }, config.timeout || 5000);\n // Store pending request\n pendingRequests.set(nonce, { resolve, reject, timeout, timestamp });\n // Send message\n log('Sending request', { type, nonce });\n iframe.contentWindow.postMessage({ type, nonce, timestamp, payload }, config.targetOrigin);\n });\n };\n // Public: Send request with retry logic\n const sendRequest = async (type, payload, options) => {\n // Allow per-request retry override (0 disables retries)\n const maxRetries = options?.retries !== undefined ? options.retries : retryConfig.maxRetries;\n let lastError = null;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await sendRequestOnce(type, payload);\n }\n catch (error) {\n lastError = error;\n const errorMessage = error.message;\n /**\n * Non-retriable error detection\n *\n * Some errors should NOT be retried because:\n *\n * 1. HANDLER_ERROR - Application-level errors from the iframe handler\n * - Examples: validation errors, business logic failures, 401 Unauthorized\n * - Retrying won't change the outcome\n *\n * 2. Client destroyed - Client lifecycle ended\n * - Client.destroy() was called, all pending requests rejected\n * - Retrying is impossible and meaningless\n * - CRITICAL: Without this, destroy() errors would trigger retry delays, hanging tests\n *\n * 3. Iframe not ready - Structural problem, not transient\n * - iframe.contentWindow is null\n * - Retrying won't fix this - requires proper iframe initialization\n *\n * Network errors, timeouts, and other transient issues SHOULD be retried.\n */\n const isHandlerError = errorMessage.startsWith('[HANDLER_ERROR]');\n const isClientDestroyed = errorMessage === 'Client destroyed';\n const isIframeNotReady = errorMessage === 'Iframe not ready';\n if (isHandlerError || isClientDestroyed || isIframeNotReady) {\n log('Not retrying error', {\n error: errorMessage,\n reason: 'Non-retriable error',\n });\n throw error;\n }\n if (attempt < maxRetries) {\n const delay = getRetryDelay(attempt, retryConfig);\n log('Retrying request', {\n attempt: attempt + 1,\n maxRetries,\n delayMs: delay,\n error: errorMessage,\n });\n await sleep(delay);\n }\n }\n }\n // All retries failed\n throw (lastError ||\n new Error(`Request failed after ${maxRetries} retries: ${type}`));\n };\n // Health check: Ping iframe to verify it's responsive\n const ping = async (timeout = 1000) => {\n const start = Date.now();\n log('Starting health check', {\n timeoutMs: timeout,\n iframeReady: !!iframe.contentWindow,\n targetOrigin: config.targetOrigin,\n });\n try {\n await sendRequestOnce('SYS_PING', undefined);\n const latency = Date.now() - start;\n log('Health check passed', { latencyMs: latency });\n return latency;\n }\n catch (error) {\n const errorMsg = `Health check failed after ${Date.now() - start}ms: ${error.message}. Target: ${config.targetOrigin}`;\n if (config.debug) {\n log(`❌ [PostMessage Client] ${errorMsg}`);\n log(`📊 [PostMessage Client] Pending requests: ${pendingRequests.size}`);\n }\n throw BasisTheoryError('HEALTH_CHECK_FAILED', errorMsg);\n }\n };\n // Subscribe to events from iframe\n const subscribe = (type, callback) => {\n if (!eventSubscribers.has(type)) {\n eventSubscribers.set(type, new Set());\n }\n eventSubscribers.get(type).add(callback);\n // Return unsubscribe function\n return () => {\n const subscribers = eventSubscribers.get(type);\n if (subscribers) {\n subscribers.delete(callback);\n if (subscribers.size === 0) {\n eventSubscribers.delete(type);\n }\n }\n };\n };\n const destroy = () => {\n window.removeEventListener('message', handleMessage);\n pendingRequests.forEach(({ timeout, reject }) => {\n clearTimeout(timeout);\n reject(BasisTheoryError('CLIENT_DESTROYED', 'Client destroyed'));\n });\n pendingRequests.clear();\n eventSubscribers.clear();\n };\n return {\n sendRequest,\n ping,\n subscribe,\n destroy,\n getPendingCount: () => pendingRequests.size,\n };\n};\n","/**\n * Element Mounter Factory\n * Handles DOM mounting/unmounting of iframes\n */\n\nimport type { ElementMounter, MountConfig } from '../types';\n\n/**\n * Factory function to create an element mounter\n * Handles DOM mounting/unmounting of iframes\n */\nexport const createMounter = (): ElementMounter => {\n // Private helper functions\n const applyIframeStyles = (iframe: HTMLIFrameElement) => {\n iframe.style.border = 'none';\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n iframe.style.display = 'block';\n };\n\n // Public API\n return {\n mount: async (\n container: HTMLElement,\n iframe: HTMLIFrameElement,\n _config: MountConfig\n ) => {\n // Apply standard iframe styles\n applyIframeStyles(iframe);\n\n // Append to DOM\n container.appendChild(iframe);\n\n // ✅ PERFORMANCE FIX: Return immediately (like Adyen/VGS/Stripe)\n // Don't wait for iframe load - let it load in background\n // Iframe will post EVENT_READY when actually loaded\n\n // NOTE: async kept for interface compatibility, but returns immediately\n // Callers should listen for 'ready' event if they need to know when loaded\n },\n\n unmount: (iframe: HTMLIFrameElement) => {\n iframe.remove();\n },\n };\n};\n","/**\n * Iframe creation utility\n */\n\nimport type { IframeConfig } from '../types';\n\n/**\n * Create a secure iframe with proper attributes\n * Pure function, no side effects\n */\nexport const createIframe = (config: IframeConfig): HTMLIFrameElement => {\n const iframe = document.createElement('iframe');\n\n iframe.src = config.src;\n iframe.setAttribute('sandbox', config.sandbox);\n iframe.title = config.title;\n\n // Security attributes - use config.allow if provided, otherwise default to payment API\n iframe.setAttribute('allow', config.allow ?? 'payment *');\n iframe.setAttribute('importance', 'high'); // Loading priority\n\n // Hide iframe until theme is applied (prevents blank white flash before document loads)\n iframe.style.opacity = '0';\n\n return iframe;\n};\n","/**\n * Centralized event dispatcher factory\n * Creates consistent event handlers for all element types\n *\n * Benefits:\n * - Single source of truth for event mapping\n * - Consistent BaseEventDetail (elementType, elementId, timestamp)\n * - Type-safe event dispatch\n * - No code duplication across element factories\n */\n\nimport type { PostMessageClient } from '@basis-theory-elements/postmessage';\nimport type { ElementType } from '../types';\nimport type {\n BaseEventDetail,\n ChangeEventDetail,\n CardNumberChangeEventDetail,\n ElementEventType,\n ErrorCode,\n NetworkChangedEventDetail,\n} from '../types/events';\n\n/**\n * Event dispatcher configuration\n */\ninterface EventDispatcherConfig {\n /** Element type */\n elementType: ElementType;\n\n /** Unique element ID */\n elementId: string;\n\n /** PostMessage client for subscribing to iframe events */\n client: PostMessageClient;\n\n /** EventTarget for dispatching DOM events */\n eventTarget: EventTarget;\n}\n\n/**\n * Create event dispatcher with consistent behavior\n *\n * @example\n * ```typescript\n * const dispatcher = createEventDispatcher({\n * elementType: 'cardNumber',\n * elementId: 'card-123',\n * client,\n * eventTarget,\n * });\n *\n * dispatcher.setupSubscriptions();\n * ```\n */\nexport const createEventDispatcher = (config: EventDispatcherConfig) => {\n const { elementType, elementId, client, eventTarget } = config;\n\n /**\n * Create base event detail metadata (shared by all events)\n */\n const createBaseDetail = (): BaseEventDetail => ({\n elementType,\n elementId,\n timestamp: Date.now(),\n });\n\n /**\n * Dispatch a CustomEvent with type-safe detail\n */\n const dispatch = <T extends ElementEventType>(\n eventType: T,\n detail: object\n ): void => {\n const event = new CustomEvent(eventType, {\n detail: {\n ...createBaseDetail(),\n ...detail,\n },\n });\n eventTarget.dispatchEvent(event);\n };\n\n /**\n * Setup event subscriptions from PostMessage\n */\n const setupSubscriptions = () => {\n // READY event\n client.subscribe('EVENT_READY', () => {\n dispatch('ready', {});\n });\n\n // CHANGE event\n client.subscribe('EVENT_VALUE_CHANGED', (payload: any) => {\n const changeDetail: Partial<ChangeEventDetail> = {\n isValid: payload.isValid,\n isEmpty: payload.isEmpty,\n error: payload.error || null,\n };\n\n // Add card-specific fields if present\n if (elementType === 'cardNumber') {\n const cardDetail: Partial<CardNumberChangeEventDetail> = {\n ...changeDetail,\n cardBrand: payload.cardBrand,\n last4: payload.last4,\n bin: payload.bin,\n cvvLengths: payload.cvvLengths,\n potentialBrands: payload.potentialBrands,\n matchStrength: payload.matchStrength,\n networks: payload.networks,\n selectedNetwork: payload.selectedNetwork,\n };\n dispatch('change', cardDetail);\n } else if (elementType === 'card') {\n dispatch('change', {\n ...changeDetail,\n cardBrand: payload.cardBrand,\n last4: payload.last4,\n bin: payload.bin,\n networks: payload.networks,\n selectedNetwork: payload.selectedNetwork,\n errors: payload.errors || null,\n });\n } else {\n dispatch('change', changeDetail);\n }\n });\n\n client.subscribe(\n 'EVENT_NETWORK_CHANGED',\n (payload: {\n network?: string;\n previousNetwork?: string;\n availableNetworks?: string[];\n selectionMode?: 'auto' | 'manual' | 'user';\n }) => {\n if (elementType !== 'cardNumber' && elementType !== 'card') {\n return;\n }\n const detail: Partial<NetworkChangedEventDetail> = {\n network: payload.network,\n previousNetwork: payload.previousNetwork,\n availableNetworks: payload.availableNetworks ?? [],\n selectionMode: payload.selectionMode ?? 'auto',\n };\n dispatch('networkChanged', detail);\n }\n );\n\n // FOCUS event\n client.subscribe('EVENT_FOCUS', () => {\n dispatch('focus', {});\n });\n\n // BLUR event\n client.subscribe('EVENT_BLUR', () => {\n dispatch('blur', {});\n });\n\n // ERROR event\n client.subscribe(\n 'EVENT_ERROR',\n (payload: {\n code?: ErrorCode;\n message?: string;\n status?: number;\n validationErrors?: Array<{ field: string; message: string }>;\n metadata?: Record<string, unknown>;\n }) => {\n dispatch('error', {\n code: payload.code,\n message: payload.message,\n status: payload.status,\n validationErrors: payload.validationErrors,\n metadata: payload.metadata || {},\n });\n }\n );\n };\n\n /**\n * Dispatch error event (for mount/initialization errors)\n *\n * @example\n * ```typescript\n * try {\n * await mount();\n * } catch (error) {\n * dispatcher.dispatchError('MOUNT_ERROR', error.message, error);\n * throw error;\n * }\n * ```\n */\n const dispatchError = (\n code: ErrorCode,\n message: string,\n error?: Error\n ): void => {\n dispatch('error', {\n code,\n message,\n metadata: {\n source: 'initialization',\n originalError: error,\n },\n });\n };\n\n return {\n setupSubscriptions,\n dispatchError,\n };\n};\n","/**\n * Card Number Element Factory\n */\n\nimport type { PostMessageClient } from '@basis-theory-elements/postmessage';\nimport { createPostMessageClient } from '@basis-theory-elements/postmessage';\nimport { ElementError, log } from '@basis-theory-elements/shared';\nimport { createMounter } from '../mounter/create-mounter';\nimport type {\n Element,\n ElementMounter,\n ElementOptions,\n EventListener,\n EventType,\n SDKConfig,\n} from '../types';\nimport { createIframe } from '../utils/create-iframe';\nimport { createEventDispatcher } from '../utils/create-event-dispatcher';\n\n/**\n * Factory function to create a card number element\n * No class, pure functional approach with closure-based state\n *\n * PERFORMANCE OPTIMIZATION (Step 3):\n * Now receives LAZY coordinator initializer - mount() calls it when needed\n */\nexport const createCardNumberElement = (\n apiKey: string,\n sdkConfig: SDKConfig,\n options: ElementOptions = {},\n coordinatorElementId: string, // Unique ID (now generated locally)\n ensureCoordinatorReady: () => Promise<void>, // ← LAZY: Call in mount() to init\n notifyCoordinatorElementUnmount: (elementId: string) => Promise<void> // ← Notify coordinator on unmount\n): Element => {\n // Private state (closure)\n let iframe: HTMLIFrameElement | null = null;\n let client: PostMessageClient | null = null;\n let mounter: ElementMounter | null = null;\n let isMounted = false;\n let container: HTMLElement | null = null;\n let eventDispatcher: ReturnType<typeof createEventDispatcher> | null = null;\n\n // Event target for event emission (native browser API)\n const eventTarget = new EventTarget();\n\n // Use coordinator-generated ID for all references\n const id = coordinatorElementId;\n const type = 'cardNumber';\n\n // Setup event dispatcher (centralized event mapping logic)\n const setupEventListeners = () => {\n if (!client) {\n return;\n }\n\n eventDispatcher = createEventDispatcher({\n elementType: type,\n elementId: id,\n client,\n eventTarget,\n });\n\n eventDispatcher.setupSubscriptions();\n\n client.subscribe('EVENT_CONTENT_HEIGHT', (payload: { heightPx?: number }) => {\n const h = payload?.heightPx;\n if (iframe && typeof h === 'number' && h > 0) {\n iframe.style.height = `${Math.ceil(h)}px`;\n }\n });\n };\n\n // Public API (Element interface)\n return {\n id,\n type,\n get mounted() {\n return isMounted;\n },\n get loaded() {\n return isMounted;\n },\n\n mount: async (selector: string | HTMLElement) => {\n if (isMounted) {\n throw ElementError('Element is already mounted');\n }\n\n // Resolve container\n container =\n typeof selector === 'string'\n ? document.querySelector(selector)\n : selector;\n\n if (!container) {\n throw ElementError(`Container not found: ${selector}`);\n }\n\n // Create iframe\n // Pass parent origin + element ID via URL parameters\n const parentOrigin = window.location.origin;\n const iframeUrl = new URL(\n `${sdkConfig.elementsBaseUrl}/card-number.html`\n );\n iframeUrl.searchParams.set('parentOrigin', parentOrigin);\n iframeUrl.searchParams.set('elementId', id); // Use locally-generated ID\n iframeUrl.searchParams.set(\n 'measurePerformance',\n String(sdkConfig.measurePerformance || false)\n );\n iframeUrl.searchParams.set('debug', String(sdkConfig.debug || false));\n\n iframe = createIframe({\n src: iframeUrl.toString(),\n sandbox: 'allow-scripts allow-same-origin',\n title: options.ariaLabel || 'Card Number Input',\n });\n\n // Add element ID and theme mode attributes for SDK updates\n iframe.setAttribute('data-bt-element-id', id);\n iframe.setAttribute('data-theme-mode', sdkConfig.themeMode || 'auto');\n\n // Create PostMessage client\n client = createPostMessageClient(iframe, {\n targetOrigin: sdkConfig.iframeOrigin,\n timeout: sdkConfig.timeoutMs,\n retries: sdkConfig.retryConfig.maxRetries,\n debug: sdkConfig.debug,\n });\n\n // Create mounter\n mounter = createMounter();\n\n // Set up event listeners\n setupEventListeners();\n\n // ✅ Subscribe to 'ready' event BEFORE mounting iframe (prevents race condition)\n // Create the promise early so the listener is in place when EVENT_READY arrives\n const readyPromise = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(\n ElementError(\n `Iframe EVENT_READY not received within ${sdkConfig.timeoutMs}ms`,\n id,\n { elementType: type, timeoutMs: sdkConfig.timeoutMs }\n )\n );\n }, sdkConfig.timeoutMs);\n\n const handleReady = () => {\n clearTimeout(timeout);\n resolve();\n };\n\n // Subscribe to ready event (dispatched when iframe sends EVENT_READY)\n // This listener is now in place BEFORE iframe is mounted\n eventTarget.addEventListener('ready', handleReady, { once: true });\n });\n\n /**\n * Mount iframe to DOM (synchronous)\n */\n mounter.mount(container, iframe, {\n timeoutMs: sdkConfig.timeoutMs,\n });\n\n isMounted = true;\n\n // Wait for coordinator + configuration to complete before returning\n // This ensures mount() contract: \"When mount() resolves, element is fully interactive\"\n try {\n // Wait for coordinator (loads Core SDK if needed)\n await ensureCoordinatorReady();\n\n // Wait for EVENT_READY (listener already attached above before mount)\n // This proves PostMessage handlers are set up and ready\n await readyPromise;\n\n // Now iframe is fully ready for PostMessage communication\n // Skip ping since EVENT_READY already proves communication works\n // await client!.ping(200); // Not needed - EVENT_READY already validated connection\n\n // Send initial configuration\n await client!.sendRequest('CMD_SET_CONFIG', {\n elementId: id, // Include element ID for validation\n apiKey,\n apiTimeout: sdkConfig.timeoutMs,\n apiRetries: sdkConfig.retryConfig.maxRetries,\n theme: sdkConfig.theme,\n darkTheme: sdkConfig.darkTheme,\n themeMode: sdkConfig.themeMode,\n placeholder: options.placeholder,\n disabled: options.disabled,\n readOnly: options.readOnly,\n debug: sdkConfig.debug,\n binLookup: options.binLookup,\n coBadge: options.coBadge,\n });\n\n // Reveal iframe now that theme is fully applied (fixes blank iframe flash on mobile)\n if (iframe) iframe.style.opacity = '1';\n\n // Element is now fully interactive\n // Note: ready event is dispatched by the EVENT_READY subscription handler (line 74)\n // when the iframe signals it's ready, so we don't dispatch here to avoid duplication\n } catch (error) {\n // Dispatch error event before cleanup\n if (eventDispatcher) {\n eventDispatcher.dispatchError(\n 'MOUNT_ERROR',\n (error as Error).message,\n error as Error\n );\n }\n\n // Mount failed - clean up and mark as unmounted\n isMounted = false;\n\n // Clean up partially initialized state\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n eventDispatcher = null;\n container = null;\n\n // Re-throw to indicate mount failure\n throw error;\n }\n },\n\n unmount: () => {\n if (!isMounted) {\n throw ElementError('Element is not mounted');\n }\n\n // PCI DSS 3.2.1: Notify coordinator to broadcast ELEMENT_UNMOUNTED\n // This clears cached values and notifies other elements (like CopyButton)\n // Done via coordinator (always alive) to avoid race conditions with iframe destruction\n notifyCoordinatorElementUnmount(id).catch((error) => {\n log('Failed to notify coordinator of element unmount', {\n elementId: id,\n error: (error as Error).message,\n });\n });\n\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n iframe.style.height = '';\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n // Clean up event dispatcher\n eventDispatcher = null;\n\n container = null;\n isMounted = false;\n },\n\n update: async (\n newOptions: Partial<ElementOptions> & { themeMode?: string }\n ) => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before updating');\n }\n\n // Only send keys that are present so we never overwrite iframe config with undefined\n // (matches create-card / create-text update behavior).\n const updatePayload: Record<string, unknown> = {\n elementId: id,\n };\n\n if (newOptions.placeholder !== undefined) {\n updatePayload.placeholder = newOptions.placeholder;\n }\n if (newOptions.disabled !== undefined) {\n updatePayload.disabled = newOptions.disabled;\n }\n if (newOptions.readOnly !== undefined) {\n updatePayload.readOnly = newOptions.readOnly;\n }\n if (newOptions.binLookup !== undefined) {\n updatePayload.binLookup = newOptions.binLookup;\n }\n if (newOptions.coBadge !== undefined) {\n updatePayload.coBadge = newOptions.coBadge;\n }\n if (newOptions.themeMode !== undefined) {\n updatePayload.themeMode = newOptions.themeMode;\n updatePayload.theme = sdkConfig.theme;\n updatePayload.darkTheme = sdkConfig.darkTheme;\n }\n\n await client.sendRequest('CMD_UPDATE_CONFIG', updatePayload);\n },\n\n focus: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before focusing');\n }\n\n client.sendRequest('CMD_FOCUS', {});\n },\n\n blur: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before blurring');\n }\n\n client.sendRequest('CMD_BLUR', {});\n },\n\n clear: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before clearing');\n }\n\n client.sendRequest('CMD_CLEAR', {});\n },\n\n setNetwork: async (network: string) => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before setNetwork');\n }\n\n await client.sendRequest('CMD_SET_NETWORK', { network });\n },\n\n on: (eventType: EventType, listener: EventListener) => {\n eventTarget.addEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n\n // Return unsubscribe function\n return () =>\n eventTarget.removeEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n },\n };\n};\n","/**\n * CVV Element Factory\n */\n\nimport type { PostMessageClient } from '@basis-theory-elements/postmessage';\nimport { createPostMessageClient } from '@basis-theory-elements/postmessage';\nimport { ElementError, log } from '@basis-theory-elements/shared';\nimport { createMounter } from '../mounter/create-mounter';\nimport type {\n Element,\n ElementMounter,\n ElementOptions,\n EventListener,\n EventType,\n SDKConfig,\n} from '../types';\nimport { createIframe } from '../utils/create-iframe';\nimport { createEventDispatcher } from '../utils/create-event-dispatcher';\n\n/**\n * Factory function to create a CVV element\n */\nexport const createCVVElement = (\n apiKey: string,\n sdkConfig: SDKConfig,\n options: ElementOptions = {},\n coordinatorElementId: string, // Unique ID (now generated locally)\n ensureCoordinatorReady: () => Promise<void>, // ← LAZY: Call in mount()\n notifyCoordinatorElementUnmount: (elementId: string) => Promise<void> // ← Notify coordinator on unmount\n): Element => {\n // Private state (closure)\n let iframe: HTMLIFrameElement | null = null;\n let client: PostMessageClient | null = null;\n let mounter: ElementMounter | null = null;\n let isMounted = false;\n let container: HTMLElement | null = null;\n let eventDispatcher: ReturnType<typeof createEventDispatcher> | null = null;\n\n const eventTarget = new EventTarget();\n // Use coordinator-generated ID for all references\n const id = coordinatorElementId;\n const type = 'cvv';\n\n // Setup event dispatcher (centralized event mapping logic)\n const setupEventListeners = () => {\n if (!client) return;\n\n eventDispatcher = createEventDispatcher({\n elementType: type,\n elementId: id,\n client,\n eventTarget,\n });\n\n eventDispatcher.setupSubscriptions();\n };\n\n return {\n id,\n type,\n get mounted() {\n return isMounted;\n },\n get loaded() {\n return isMounted;\n },\n\n mount: async (selector: string | HTMLElement) => {\n if (isMounted) {\n throw ElementError('Element is already mounted', id);\n }\n\n container =\n typeof selector === 'string'\n ? document.querySelector(selector)\n : selector;\n\n if (!container) {\n throw ElementError(`Container not found: ${selector}`);\n }\n\n // Pass parent origin + coordinator-generated element ID via URL parameters\n const parentOrigin = window.location.origin;\n const iframeUrl = new URL(`${sdkConfig.elementsBaseUrl}/cvv.html`);\n iframeUrl.searchParams.set('parentOrigin', parentOrigin);\n iframeUrl.searchParams.set('elementId', id); // Use coordinator-generated ID\n iframeUrl.searchParams.set(\n 'measurePerformance',\n String(sdkConfig.measurePerformance || false)\n );\n iframeUrl.searchParams.set('debug', String(sdkConfig.debug || false));\n\n iframe = createIframe({\n src: iframeUrl.toString(),\n sandbox: 'allow-scripts allow-same-origin',\n title: options.ariaLabel || 'CVV Input',\n });\n\n // Add element ID attribute for debugging\n iframe.setAttribute('data-bt-element-id', id);\n\n client = createPostMessageClient(iframe, {\n targetOrigin: sdkConfig.iframeOrigin,\n timeout: sdkConfig.timeoutMs,\n retries: sdkConfig.retryConfig.maxRetries,\n debug: sdkConfig.debug,\n });\n\n mounter = createMounter();\n setupEventListeners();\n\n // ✅ Subscribe to 'ready' event BEFORE mounting iframe (prevents race condition)\n const readyPromise = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(\n ElementError(\n `Iframe EVENT_READY not received within ${sdkConfig.timeoutMs}ms`,\n id,\n { elementType: type, timeoutMs: sdkConfig.timeoutMs }\n )\n );\n }, sdkConfig.timeoutMs);\n\n const handleReady = () => {\n clearTimeout(timeout);\n resolve();\n };\n\n // Subscribe to ready event (dispatched when iframe sends EVENT_READY)\n eventTarget.addEventListener('ready', handleReady, { once: true });\n });\n\n /**\n * Mount iframe to DOM (synchronous)\n */\n mounter.mount(container, iframe, {\n timeoutMs: sdkConfig.timeoutMs,\n });\n\n isMounted = true;\n\n // Wait for coordinator + configuration to complete before returning\n // This ensures mount() contract: \"When mount() resolves, element is fully interactive\"\n try {\n await ensureCoordinatorReady();\n\n // Wait for EVENT_READY (listener already attached above before mount)\n await readyPromise;\n\n // Now iframe is fully ready for PostMessage communication\n // Skip ping since EVENT_READY already proves communication works\n // await client!.ping(200); // Not needed - EVENT_READY already validated connection\n\n await client!.sendRequest('CMD_SET_CONFIG', {\n elementId: id, // Include element ID for validation\n theme: sdkConfig.theme,\n darkTheme: sdkConfig.darkTheme,\n themeMode: sdkConfig.themeMode,\n apiKey,\n apiTimeout: sdkConfig.timeoutMs,\n apiRetries: sdkConfig.retryConfig.maxRetries,\n placeholder: options.placeholder,\n disabled: options.disabled,\n readOnly: options.readOnly,\n showToggle: options.showToggle,\n debug: sdkConfig.debug,\n });\n\n // Reveal iframe now that theme is fully applied (fixes blank iframe flash on mobile)\n if (iframe) iframe.style.opacity = '1';\n\n // Element is now fully interactive\n // Note: ready event is dispatched by the EVENT_READY subscription handler\n // when the iframe signals it's ready, so we don't dispatch here to avoid duplication\n } catch (error) {\n // Dispatch error event before cleanup\n if (eventDispatcher) {\n eventDispatcher.dispatchError(\n 'MOUNT_ERROR',\n (error as Error).message,\n error as Error\n );\n }\n\n // Mount failed - clean up and mark as unmounted\n isMounted = false;\n\n // Clean up partially initialized state\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n eventDispatcher = null;\n container = null;\n\n // Re-throw to indicate mount failure\n throw error;\n }\n },\n\n unmount: () => {\n if (!isMounted) {\n throw ElementError('Element is not mounted');\n }\n\n // PCI DSS 3.2.1: Notify coordinator to broadcast ELEMENT_UNMOUNTED\n // This clears cached values and notifies other elements (like CopyButton)\n notifyCoordinatorElementUnmount(id).catch((error) => {\n log('Failed to notify coordinator of element unmount', {\n elementId: id,\n error: (error as Error).message,\n });\n });\n\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n // Clean up event dispatcher\n eventDispatcher = null;\n\n container = null;\n isMounted = false;\n },\n\n update: async (\n newOptions: Partial<ElementOptions> & { themeMode?: string }\n ) => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before updating', id);\n }\n\n // Build update payload with theme mode support\n const updatePayload: Record<string, any> = {\n placeholder: newOptions.placeholder,\n disabled: newOptions.disabled,\n readOnly: newOptions.readOnly,\n // ✅ SDK auto-coordination: Pass brand info for dynamic maxlength\n cardBrand: newOptions.cardBrand,\n cvvLengths: newOptions.cvvLengths,\n };\n\n // Include theme mode update if provided\n if (newOptions.themeMode !== undefined) {\n updatePayload.themeMode = newOptions.themeMode;\n updatePayload.theme = sdkConfig.theme;\n updatePayload.darkTheme = sdkConfig.darkTheme;\n }\n\n await client.sendRequest('CMD_UPDATE_CONFIG', updatePayload);\n },\n\n focus: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before focusing', id);\n }\n\n client.sendRequest('CMD_FOCUS', {});\n },\n\n blur: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before blurring', id);\n }\n\n client.sendRequest('CMD_BLUR', {});\n },\n\n clear: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before clearing', id);\n }\n\n client.sendRequest('CMD_CLEAR', {});\n },\n\n on: (eventType: EventType, listener: EventListener) => {\n eventTarget.addEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n\n return () =>\n eventTarget.removeEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n },\n };\n};\n","/**\n * Expiry Date Element Factory\n */\n\nimport type { PostMessageClient } from '@basis-theory-elements/postmessage';\nimport { createPostMessageClient } from '@basis-theory-elements/postmessage';\nimport { ElementError, log } from '@basis-theory-elements/shared';\nimport { createMounter } from '../mounter/create-mounter';\nimport type {\n Element,\n ElementMounter,\n ElementOptions,\n EventListener,\n EventType,\n SDKConfig,\n} from '../types';\nimport { createIframe } from '../utils/create-iframe';\nimport { createEventDispatcher } from '../utils/create-event-dispatcher';\n\n/**\n * Factory function to create an expiry date element\n */\nexport const createExpiryElement = (\n apiKey: string,\n sdkConfig: SDKConfig,\n options: ElementOptions = {},\n coordinatorElementId: string, // Unique ID (now generated locally)\n ensureCoordinatorReady: () => Promise<void>, // ← LAZY: Call in mount()\n notifyCoordinatorElementUnmount: (elementId: string) => Promise<void> // ← Notify coordinator on unmount\n): Element => {\n // Private state (closure)\n let iframe: HTMLIFrameElement | null = null;\n let client: PostMessageClient | null = null;\n let mounter: ElementMounter | null = null;\n let isMounted = false;\n let container: HTMLElement | null = null;\n let eventDispatcher: ReturnType<typeof createEventDispatcher> | null = null;\n\n const eventTarget = new EventTarget();\n // Use coordinator-generated ID for all references\n const id = coordinatorElementId;\n const type = 'expiry';\n\n // Setup event dispatcher (centralized event mapping logic)\n const setupEventListeners = () => {\n if (!client) return;\n\n eventDispatcher = createEventDispatcher({\n elementType: type,\n elementId: id,\n client,\n eventTarget,\n });\n\n eventDispatcher.setupSubscriptions();\n };\n\n return {\n id,\n type,\n get mounted() {\n return isMounted;\n },\n get loaded() {\n return isMounted;\n },\n\n mount: async (selector: string | HTMLElement) => {\n if (isMounted) {\n throw ElementError('Element is already mounted', id);\n }\n\n container =\n typeof selector === 'string'\n ? document.querySelector(selector)\n : selector;\n\n if (!container) {\n throw ElementError(`Container not found: ${selector}`);\n }\n\n // Pass parent origin + coordinator-generated element ID via URL parameters\n const parentOrigin = window.location.origin;\n const iframeUrl = new URL(`${sdkConfig.elementsBaseUrl}/expiry.html`);\n iframeUrl.searchParams.set('parentOrigin', parentOrigin);\n iframeUrl.searchParams.set('elementId', id); // Use coordinator-generated ID\n iframeUrl.searchParams.set(\n 'measurePerformance',\n String(sdkConfig.measurePerformance || false)\n );\n iframeUrl.searchParams.set('debug', String(sdkConfig.debug || false));\n\n iframe = createIframe({\n src: iframeUrl.toString(),\n sandbox: 'allow-scripts allow-same-origin',\n title: options.ariaLabel || 'Expiry Date Input',\n });\n\n // Add element ID and theme mode attributes for SDK updates\n iframe.setAttribute('data-bt-element-id', id);\n\n client = createPostMessageClient(iframe, {\n targetOrigin: sdkConfig.iframeOrigin,\n timeout: sdkConfig.timeoutMs,\n retries: sdkConfig.retryConfig.maxRetries,\n debug: sdkConfig.debug,\n });\n\n mounter = createMounter();\n setupEventListeners();\n\n // ✅ Subscribe to 'ready' event BEFORE mounting iframe (prevents race condition)\n const readyPromise = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(\n ElementError(\n `Iframe EVENT_READY not received within ${sdkConfig.timeoutMs}ms`,\n id,\n { elementType: type, timeoutMs: sdkConfig.timeoutMs }\n )\n );\n }, sdkConfig.timeoutMs);\n\n const handleReady = () => {\n clearTimeout(timeout);\n resolve();\n };\n\n // Subscribe to ready event (dispatched when iframe sends EVENT_READY)\n eventTarget.addEventListener('ready', handleReady, { once: true });\n });\n\n /**\n * Mount iframe to DOM (synchronous)\n */\n mounter.mount(container, iframe, {\n timeoutMs: sdkConfig.timeoutMs,\n });\n\n isMounted = true;\n\n // Wait for coordinator + configuration to complete before returning\n // This ensures mount() contract: \"When mount() resolves, element is fully interactive\"\n try {\n await ensureCoordinatorReady();\n\n // Wait for EVENT_READY (listener already attached above before mount)\n await readyPromise;\n\n // Now iframe is fully ready for PostMessage communication\n // Skip ping since EVENT_READY already proves communication works\n // await client!.ping(200); // Not needed - EVENT_READY already validated connection\n\n await client!.sendRequest('CMD_SET_CONFIG', {\n elementId: id, // Include element ID for validation\n theme: sdkConfig.theme,\n darkTheme: sdkConfig.darkTheme,\n themeMode: sdkConfig.themeMode,\n apiKey,\n apiTimeout: sdkConfig.timeoutMs,\n apiRetries: sdkConfig.retryConfig.maxRetries,\n placeholder: options.placeholder,\n disabled: options.disabled,\n readOnly: options.readOnly,\n debug: sdkConfig.debug,\n });\n\n // Reveal iframe now that theme is fully applied (fixes blank iframe flash on mobile)\n if (iframe) iframe.style.opacity = '1';\n\n // Element is now fully interactive\n // Note: ready event is dispatched by the EVENT_READY subscription handler\n // when the iframe signals it's ready, so we don't dispatch here to avoid duplication\n } catch (error) {\n // Dispatch error event before cleanup\n if (eventDispatcher) {\n eventDispatcher.dispatchError(\n 'MOUNT_ERROR',\n (error as Error).message,\n error as Error\n );\n }\n\n // Mount failed - clean up and mark as unmounted\n isMounted = false;\n\n // Clean up partially initialized state\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n eventDispatcher = null;\n container = null;\n\n // Re-throw to indicate mount failure\n throw error;\n }\n },\n\n unmount: () => {\n if (!isMounted) {\n throw ElementError('Element is not mounted');\n }\n\n // PCI DSS 3.2.1: Notify coordinator to broadcast ELEMENT_UNMOUNTED\n // This clears cached values and notifies other elements (like CopyButton)\n notifyCoordinatorElementUnmount(id).catch((error) => {\n log('Failed to notify coordinator of element unmount', {\n elementId: id,\n error: (error as Error).message,\n });\n });\n\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n // Clean up event dispatcher\n eventDispatcher = null;\n\n container = null;\n isMounted = false;\n },\n\n update: async (\n newOptions: Partial<ElementOptions> & { themeMode?: string }\n ) => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before updating', id);\n }\n\n // Build update payload with theme mode support\n const updatePayload: Record<string, any> = {\n placeholder: newOptions.placeholder,\n disabled: newOptions.disabled,\n readOnly: newOptions.readOnly,\n };\n\n // Include theme mode update if provided\n if (newOptions.themeMode !== undefined) {\n updatePayload.themeMode = newOptions.themeMode;\n updatePayload.theme = sdkConfig.theme;\n updatePayload.darkTheme = sdkConfig.darkTheme;\n }\n\n await client.sendRequest('CMD_UPDATE_CONFIG', updatePayload);\n },\n\n focus: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before focusing', id);\n }\n\n client.sendRequest('CMD_FOCUS', {});\n },\n\n blur: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before blurring', id);\n }\n\n client.sendRequest('CMD_BLUR', {});\n },\n\n clear: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before clearing', id);\n }\n\n client.sendRequest('CMD_CLEAR', {});\n },\n\n on: (eventType: EventType, listener: EventListener) => {\n eventTarget.addEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n\n return () =>\n eventTarget.removeEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n },\n };\n};\n","/**\n * Text Element Factory\n *\n * General-purpose text input with optional validation and masking\n * Follows same pattern as CVV/Expiry elements\n */\n\nimport type { PostMessageClient } from '@basis-theory-elements/postmessage';\nimport { createPostMessageClient } from '@basis-theory-elements/postmessage';\nimport { ElementError, log } from '@basis-theory-elements/shared';\nimport { createMounter } from '../mounter/create-mounter';\nimport type {\n Element,\n ElementMounter,\n ElementOptions,\n EventListener,\n EventType,\n SDKConfig,\n} from '../types';\nimport { createIframe } from '../utils/create-iframe';\nimport { createEventDispatcher } from '../utils/create-event-dispatcher';\n\n/**\n * Factory function to create a text element\n */\nexport const createTextElement = (\n apiKey: string,\n sdkConfig: SDKConfig,\n options: ElementOptions = {},\n coordinatorElementId: string, // Unique ID (now generated locally)\n ensureCoordinatorReady: () => Promise<void>, // ← LAZY: Call in mount()\n notifyCoordinatorElementUnmount: (elementId: string) => Promise<void> // ← Notify coordinator on unmount\n): Element => {\n // Private state (closure)\n let iframe: HTMLIFrameElement | null = null;\n let client: PostMessageClient | null = null;\n let mounter: ElementMounter | null = null;\n let isMounted = false;\n let container: HTMLElement | null = null;\n let eventDispatcher: ReturnType<typeof createEventDispatcher> | null = null;\n\n const eventTarget = new EventTarget();\n // Use coordinator-generated ID for all references\n const id = coordinatorElementId;\n const type = 'text';\n\n // Validate transform config upfront\n if (options.transform) {\n if (\n !Array.isArray(options.transform) ||\n options.transform.length !== 2 ||\n !(options.transform[0] instanceof RegExp) ||\n typeof options.transform[1] !== 'string'\n ) {\n throw new TypeError(\n 'transform must be a tuple of [RegExp, string]. Example: [/-/g, \"\"]'\n );\n }\n }\n\n // Setup event dispatcher (centralized event mapping logic)\n const setupEventListeners = () => {\n if (!client) return;\n\n eventDispatcher = createEventDispatcher({\n elementType: type,\n elementId: id,\n client,\n eventTarget,\n });\n\n eventDispatcher.setupSubscriptions();\n };\n\n return {\n id,\n type,\n get mounted() {\n return isMounted;\n },\n get loaded() {\n return isMounted;\n },\n\n mount: async (selector: string | HTMLElement) => {\n if (isMounted) {\n throw ElementError('Element is already mounted', id);\n }\n\n container =\n typeof selector === 'string'\n ? document.querySelector(selector)\n : selector;\n\n if (!container) {\n throw ElementError(`Container not found: ${selector}`);\n }\n\n // Pass parent origin + coordinator-generated element ID via URL parameters\n const parentOrigin = window.location.origin;\n const iframeUrl = new URL(`${sdkConfig.elementsBaseUrl}/text.html`);\n iframeUrl.searchParams.set('parentOrigin', parentOrigin);\n iframeUrl.searchParams.set('elementId', id); // Use coordinator-generated ID\n iframeUrl.searchParams.set(\n 'measurePerformance',\n String(sdkConfig.measurePerformance || false)\n );\n iframeUrl.searchParams.set('debug', String(sdkConfig.debug || false));\n\n iframe = createIframe({\n src: iframeUrl.toString(),\n sandbox: 'allow-scripts allow-same-origin',\n title: options.ariaLabel || 'Text Input',\n });\n\n // Add element ID attribute for debugging\n iframe.setAttribute('data-bt-element-id', id);\n\n client = createPostMessageClient(iframe, {\n targetOrigin: sdkConfig.iframeOrigin,\n timeout: sdkConfig.timeoutMs,\n retries: sdkConfig.retryConfig.maxRetries,\n debug: sdkConfig.debug,\n });\n\n mounter = createMounter();\n setupEventListeners();\n\n // ✅ Subscribe to 'ready' event BEFORE mounting iframe (prevents race condition)\n const readyPromise = new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(\n ElementError(\n `Iframe EVENT_READY not received within ${sdkConfig.timeoutMs}ms`,\n id,\n { elementType: type, timeoutMs: sdkConfig.timeoutMs }\n )\n );\n }, sdkConfig.timeoutMs);\n\n const handleReady = () => {\n clearTimeout(timeout);\n resolve();\n };\n\n // Subscribe to ready event (dispatched when iframe sends EVENT_READY)\n eventTarget.addEventListener('ready', handleReady, { once: true });\n });\n\n /**\n * Mount iframe to DOM (synchronous)\n */\n mounter.mount(container, iframe, {\n timeoutMs: sdkConfig.timeoutMs,\n });\n\n isMounted = true;\n\n // Wait for coordinator + configuration to complete before returning\n // This ensures mount() contract: \"When mount() resolves, element is fully interactive\"\n try {\n await ensureCoordinatorReady();\n\n // Wait for EVENT_READY (listener already attached above before mount)\n await readyPromise;\n\n // Now iframe is fully ready for PostMessage communication\n // Skip ping since EVENT_READY already proves communication works\n // await client!.ping(200); // Not needed - EVENT_READY already validated connection\n\n // Serialize transform for postMessage (RegExp doesn't serialize)\n const serializedTransform = options.transform\n ? {\n pattern: options.transform[0].source,\n flags: options.transform[0].flags,\n replacement: options.transform[1],\n }\n : undefined;\n\n // Serialize mask for postMessage (RegExp doesn't serialize)\n const serializedMask = options.mask\n ? options.mask.map((item) => {\n if (typeof item === 'string') {\n return item; // Static characters pass through as-is\n } else if (item instanceof RegExp) {\n // Serialize RegExp to { source, flags }\n return { source: item.source, flags: item.flags };\n }\n return item;\n })\n : undefined;\n\n // Send text-specific config\n await client!.sendRequest('CMD_SET_CONFIG', {\n elementId: id, // Include element ID for validation\n theme: sdkConfig.theme,\n darkTheme: sdkConfig.darkTheme,\n themeMode: sdkConfig.themeMode,\n apiKey,\n apiTimeout: sdkConfig.timeoutMs,\n apiRetries: sdkConfig.retryConfig.maxRetries,\n placeholder: options.placeholder,\n disabled: options.disabled,\n readOnly: options.readOnly,\n // Text-specific options\n validation: options.validation,\n required: options.required,\n maxLength: options.maxLength,\n password: options.password,\n inputMode: options.inputMode,\n mask: serializedMask,\n transform: serializedTransform,\n debug: sdkConfig.debug,\n });\n\n // Reveal iframe now that theme is fully applied (fixes blank iframe flash on mobile)\n if (iframe) iframe.style.opacity = '1';\n\n // Element is now fully interactive\n // Note: ready event is dispatched by the EVENT_READY subscription handler\n // when the iframe signals it's ready, so we don't dispatch here to avoid duplication\n } catch (error) {\n // Dispatch error event before cleanup\n if (eventDispatcher) {\n eventDispatcher.dispatchError(\n 'MOUNT_ERROR',\n (error as Error).message,\n error as Error\n );\n }\n\n // Mount failed - clean up and mark as unmounted\n isMounted = false;\n\n // Clean up partially initialized state\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n eventDispatcher = null;\n container = null;\n\n // Re-throw to indicate mount failure\n throw error;\n }\n },\n\n unmount: () => {\n if (!isMounted) {\n throw ElementError('Element is not mounted');\n }\n\n // PCI DSS 3.2.1: Notify coordinator to broadcast ELEMENT_UNMOUNTED\n // This clears cached values and notifies other elements (like CopyButton)\n notifyCoordinatorElementUnmount(id).catch((error) => {\n log('Failed to notify coordinator of element unmount', {\n elementId: id,\n error: (error as Error).message,\n });\n });\n\n if (client) {\n client.destroy();\n client = null;\n }\n\n if (mounter && iframe) {\n mounter.unmount(iframe);\n iframe = null;\n mounter = null;\n }\n\n // Clean up event dispatcher\n eventDispatcher = null;\n\n container = null;\n isMounted = false;\n },\n\n update: async (\n newOptions: Partial<ElementOptions> & { themeMode?: string }\n ) => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before updating', id);\n }\n\n // Build update payload with theme mode support\n // ⚠️ NOTE: validation, mask, transform are IMMUTABLE (set at creation only)\n // They define the data schema/contract and shouldn't change mid-flow\n const updatePayload: Record<string, any> = {\n placeholder: newOptions.placeholder,\n disabled: newOptions.disabled,\n readOnly: newOptions.readOnly,\n // Text-specific UI updates (not data schema)\n required: newOptions.required,\n maxLength: newOptions.maxLength,\n password: newOptions.password,\n inputMode: newOptions.inputMode,\n };\n\n // Include theme mode update if provided\n if (newOptions.themeMode !== undefined) {\n updatePayload.themeMode = newOptions.themeMode;\n updatePayload.theme = sdkConfig.theme;\n updatePayload.darkTheme = sdkConfig.darkTheme;\n }\n\n await client.sendRequest('CMD_UPDATE_CONFIG', updatePayload);\n },\n\n focus: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before focusing', id);\n }\n\n client.sendRequest('CMD_FOCUS', {});\n },\n\n blur: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before blurring', id);\n }\n\n client.sendRequest('CMD_BLUR', {});\n },\n\n clear: () => {\n if (!isMounted || !client) {\n throw ElementError('Element must be mounted before clearing', id);\n }\n\n client.sendRequest('CMD_CLEAR', {});\n },\n\n on: (eventType: EventType, listener: EventListener) => {\n eventTarget.addEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n\n return () =>\n eventTarget.removeEventListener(\n eventType,\n listener as EventListenerOrEventListenerObject\n );\n },\n };\n};\n","/**\n * Element Reference Resolution Utilities (SDK Client-Side)\n *\n * Converts Element objects to ID strings before sending to coordinator.\n * Only the `data` field of tokenization requests may contain Element references.\n *\n * @see packages/elements/src/shared/utils/replace-element-references.ts\n * for Step 2 (Coordinator tokenization - ID strings → raw values)\n */\n\nimport { ElementError } from '@basis-theory-elements/shared';\nimport type { Element } from '../types';\n\ntype Primitive = string | number | boolean | null | undefined;\n\nconst isPrimitive = (value: unknown): value is Primitive =>\n value === null ||\n value === undefined ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean';\n\n/**\n * Elements may be loader placeholders before SDK loads (only have mount/update/on methods).\n * Duck-type detect to avoid postMessage cloning errors.\n */\nconst isElement = (value: unknown): value is Element => {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.mount === 'function' &&\n typeof v.update === 'function' &&\n typeof v.on === 'function'\n );\n};\n\n/**\n * Recursively resolves any value — primitives pass through, Element instances\n * become their ID string, arrays and objects are traversed.\n */\nexport const resolveElementReferences = (value: unknown): unknown => {\n if (isPrimitive(value)) return value;\n\n if (isElement(value)) {\n if (!value.id) {\n throw ElementError(\n 'Element is missing id property. Ensure createElement is called after the SDK loads ' +\n 'and all elements are mounted before calling tokenize().'\n );\n }\n return value.id;\n }\n\n if (Array.isArray(value)) return value.map(resolveElementReferences);\n\n if (typeof value === 'object' && value !== null) {\n const resolved: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n resolved[key] = resolveElementReferences(v);\n }\n return resolved;\n }\n\n return value;\n};\n\n/**\n * Extracts element ID strings from a resolved payload.\n * Used to identify which elements are referenced before tokenization.\n */\nexport const extractElementIds = (payload: unknown): string[] => {\n const elementIds = new Set<string>();\n\n const traverse = (value: unknown): void => {\n if (typeof value === 'string' && /^[a-z]+-[a-f0-9-]{36}$/i.test(value)) {\n elementIds.add(value);\n return;\n }\n if (isPrimitive(value)) return;\n if (Array.isArray(value)) { value.forEach(traverse); return; }\n if (typeof value === 'object' && value !== null) {\n Object.values(value).forEach(traverse);\n }\n };\n\n traverse(payload);\n return Array.from(elementIds);\n};\n","/**\n * Default Theme\n * Provides sensible defaults for all theme tokens\n */\n\nimport type { ThemeTokens } from '../types/theme';\n\n/**\n * Default light theme\n * Inspired by Tailwind CSS color system + Inter font\n */\nexport const DEFAULT_THEME: ThemeTokens = {\n colors: {\n primary: '#3b82f6', // blue-500\n error: '#ef4444', // red-500\n success: '#10b981', // emerald-500\n text: {\n primary: '#1f2937', // gray-800\n secondary: '#6b7280', // gray-500\n placeholder: '#9ca3af', // gray-400\n disabled: '#d1d5db', // gray-300\n },\n background: {\n default: '#ffffff',\n hover: '#f9fafb', // gray-50\n focus: '#eff6ff', // blue-50\n disabled: '#f9fafb', // gray-50\n },\n border: {\n default: '#d1d5db', // gray-300\n hover: '#9ca3af', // gray-400\n focus: '#3b82f6', // blue-500\n error: '#ef4444', // red-500\n },\n },\n typography: {\n fontFamily:\n '\"Inter\", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: {\n sm: '14px',\n base: '16px',\n lg: '18px',\n },\n fontWeight: {\n normal: '400',\n medium: '500',\n semibold: '600',\n },\n lineHeight: {\n tight: '1.25',\n normal: '1.5',\n relaxed: '1.75',\n },\n },\n spacing: {\n xs: '4px',\n sm: '8px',\n md: '12px',\n lg: '16px',\n xl: '24px',\n },\n borders: {\n radius: {\n none: '0',\n sm: '2px',\n base: '4px',\n md: '6px',\n lg: '8px',\n full: '9999px',\n },\n width: {\n thin: '1px',\n base: '2px',\n thick: '3px',\n },\n },\n shadows: {\n none: 'none',\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n base: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)',\n focus: '0 0 0 3px rgba(59, 130, 246, 0.1)', // blue-500 with alpha\n },\n transitions: {\n fast: '150ms cubic-bezier(0.4, 0, 0.2, 1)',\n base: '200ms cubic-bezier(0.4, 0, 0.2, 1)',\n slow: '300ms cubic-bezier(0.4, 0, 0.2, 1)',\n },\n};\n\n/**\n * Default dark theme\n * Optimized for dark mode with high contrast\n */\nexport const DEFAULT_DARK_THEME: ThemeTokens = {\n colors: {\n primary: '#07e0e0', // cyan-400\n error: '#ef4444', // red-500\n success: '#07e0e0', // cyan-400\n text: {\n primary: '#fafafa', // gray-50\n secondary: '#a1a1aa', // gray-400\n placeholder: '#71717a', // gray-500\n disabled: '#52525b', // gray-600\n },\n background: {\n default: '#18181b', // zinc-900\n hover: '#27272a', // zinc-800\n focus: '#3f3f46', // zinc-700\n disabled: '#27272a', // zinc-800\n },\n border: {\n default: '#3f3f46', // zinc-700\n hover: '#52525b', // zinc-600\n focus: '#07e0e0', // cyan-400\n error: '#ef4444', // red-500\n },\n },\n typography: {\n fontFamily:\n '\"Inter\", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: {\n sm: '14px',\n base: '16px',\n lg: '18px',\n },\n fontWeight: {\n normal: '400',\n medium: '500',\n semibold: '600',\n },\n lineHeight: {\n tight: '1.25',\n normal: '1.5',\n relaxed: '1.75',\n },\n },\n spacing: {\n xs: '4px',\n sm: '8px',\n md: '12px',\n lg: '16px',\n xl: '24px',\n },\n borders: {\n radius: {\n none: '0',\n sm: '2px',\n base: '4px',\n md: '6px',\n lg: '8px',\n full: '9999px',\n },\n width: {\n thin: '1px',\n base: '2px',\n thick: '3px',\n },\n },\n shadows: {\n none: 'none',\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.3)',\n base: '0 1px 3px 0 rgba(0, 0, 0, 0.5), 0 1px 2px -1px rgba(0, 0, 0, 0.5)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -2px rgba(0, 0, 0, 0.5)',\n focus: '0 0 0 3px rgba(7, 224, 224, 0.2)', // cyan-400 with alpha\n },\n transitions: {\n fast: '150ms cubic-bezier(0.4, 0, 0.2, 1)',\n base: '200ms cubic-bezier(0.4, 0, 0.2, 1)',\n slow: '300ms cubic-bezier(0.4, 0, 0.2, 1)',\n },\n};\n\n/**\n * Merge user theme with default theme\n * User values take precedence, missing values use defaults\n * Handles nested color groups (text, background, border)\n */\nexport const mergeWithDefaultTheme = (\n userTheme?: Partial<ThemeTokens>\n): ThemeTokens => {\n if (!userTheme) return DEFAULT_THEME;\n\n return {\n colors: {\n primary: userTheme.colors?.primary ?? DEFAULT_THEME.colors.primary,\n error: userTheme.colors?.error ?? DEFAULT_THEME.colors.error,\n success: userTheme.colors?.success ?? DEFAULT_THEME.colors.success,\n text: {\n ...DEFAULT_THEME.colors.text,\n ...userTheme.colors?.text,\n },\n background: {\n ...DEFAULT_THEME.colors.background,\n ...userTheme.colors?.background,\n },\n border: {\n ...DEFAULT_THEME.colors.border,\n ...userTheme.colors?.border,\n },\n },\n typography: {\n ...DEFAULT_THEME.typography,\n ...userTheme.typography,\n fontSize: {\n ...DEFAULT_THEME.typography.fontSize,\n ...userTheme.typography?.fontSize,\n },\n fontWeight: {\n ...DEFAULT_THEME.typography.fontWeight,\n ...userTheme.typography?.fontWeight,\n },\n lineHeight: {\n ...DEFAULT_THEME.typography.lineHeight,\n ...userTheme.typography?.lineHeight,\n },\n },\n spacing: { ...DEFAULT_THEME.spacing, ...userTheme.spacing },\n borders: {\n radius: {\n ...DEFAULT_THEME.borders.radius,\n ...userTheme.borders?.radius,\n },\n width: {\n ...DEFAULT_THEME.borders.width,\n ...userTheme.borders?.width,\n },\n },\n shadows: { ...DEFAULT_THEME.shadows, ...userTheme.shadows },\n transitions: { ...DEFAULT_THEME.transitions, ...userTheme.transitions },\n };\n};\n","/**\n * Warn about unknown keys in configuration objects\n * Follows Stripe's pattern: warn but don't throw\n */\n\n/**\n * Warn about unknown keys in a configuration object.\n * Follows Stripe's pattern: warn but don't throw.\n *\n * @param label - Context label for the warning (e.g., 'SDKOptions', 'ElementOptions')\n * @param obj - The configuration object to check\n * @param knownKeys - Set of valid keys\n * @param deprecatedKeys - Optional map of deprecated keys to migration messages\n */\nexport const warnUnknownKeys = (\n label: string,\n obj: Record<string, unknown>,\n knownKeys: ReadonlySet<string>,\n deprecatedKeys?: ReadonlyMap<string, string>\n): void => {\n for (const key of Object.keys(obj)) {\n if (knownKeys.has(key)) {\n continue;\n }\n\n // Check for deprecated keys first (more specific message)\n if (deprecatedKeys?.has(key)) {\n console.warn(\n `[BasisTheory] Deprecated option \"${key}\" in ${label}. ${deprecatedKeys.get(key)}`\n );\n continue;\n }\n\n // Unknown key\n console.warn(\n `[BasisTheory] Unknown option \"${key}\" in ${label}. ` +\n `This option will be ignored. ` +\n `See https://developers.basistheory.com/docs/ for supported options.`\n );\n }\n};\n","/**\n * Configuration validation utilities\n */\n\nimport { ConfigurationError } from '@basis-theory-elements/shared';\nimport { mergeWithDefaultTheme } from '../theme/default-theme';\nimport type { SDKConfig, SDKOptions } from '../types';\nimport { warnUnknownKeys } from './warn-unknown-keys';\n\n// Define known SDK keys (matches SDKOptions interface)\nconst KNOWN_SDK_KEYS: ReadonlySet<string> = new Set([\n 'elementsBaseUrl',\n 'whitelabelDomain',\n 'apiBaseUrl',\n 'debug',\n 'measurePerformance',\n 'timeoutMs',\n 'retryConfig',\n 'themeMode',\n 'theme',\n 'darkTheme',\n 'sessionAuthorizationUrl',\n]);\n\n// Migration messages for deprecated options (still functional but discouraged)\nconst DEPRECATED_SDK_KEYS: ReadonlyMap<string, string> = new Map([\n ['iframeOrigin', 'Use \"elementsBaseUrl\" instead.'],\n]);\n\n/**\n * Validate API key format\n * Throws if API key is invalid\n */\nexport const validateAPIKey = (apiKey: string): void => {\n if (!apiKey || typeof apiKey !== 'string' || apiKey.trim().length === 0) {\n throw ConfigurationError('API key is required');\n }\n};\n\n/**\n * Validate and normalize SDK configuration\n * Returns complete config with defaults applied\n */\nexport const validateSDKConfig = (options: SDKOptions = {}): SDKConfig => {\n // Warn about unknown/deprecated keys FIRST (before throwing on invalid values)\n warnUnknownKeys(\n 'SDKOptions',\n options as Record<string, unknown>,\n KNOWN_SDK_KEYS,\n DEPRECATED_SDK_KEYS\n );\n\n // Support both elementsBaseUrl (preferred) and iframeOrigin (deprecated)\n const baseUrl = options.elementsBaseUrl || options.iframeOrigin;\n\n // Validate base URL if provided\n if (baseUrl !== undefined) {\n if (typeof baseUrl !== 'string' || baseUrl.trim().length === 0) {\n throw ConfigurationError('elementsBaseUrl must be a non-empty string');\n }\n\n // Validate URL format\n try {\n new URL(baseUrl);\n } catch {\n throw ConfigurationError('elementsBaseUrl must be a valid URL');\n }\n }\n\n // Validate API base URL if provided\n if (options.apiBaseUrl !== undefined) {\n if (typeof options.apiBaseUrl !== 'string' || options.apiBaseUrl.trim().length === 0) {\n throw ConfigurationError('apiBaseUrl must be a non-empty string');\n }\n\n // Validate URL format\n try {\n new URL(options.apiBaseUrl);\n } catch {\n throw ConfigurationError('apiBaseUrl must be a valid URL');\n }\n }\n\n // Validate debug flag\n if (options.debug !== undefined && typeof options.debug !== 'boolean') {\n throw ConfigurationError('debug must be a boolean');\n }\n\n // Validate measurePerformance flag\n if (\n options.measurePerformance !== undefined &&\n typeof options.measurePerformance !== 'boolean'\n ) {\n throw ConfigurationError('measurePerformance must be a boolean');\n }\n\n // Validate timeout\n if (options.timeoutMs !== undefined) {\n if (typeof options.timeoutMs !== 'number' || options.timeoutMs <= 0) {\n throw ConfigurationError('timeoutMs must be a positive number');\n }\n }\n\n // Validate retry config\n const retryConfig = {\n maxRetries: options.retryConfig?.maxRetries ?? 3,\n delayMs: options.retryConfig?.delayMs ?? 1000,\n backoffFactor: options.retryConfig?.backoffFactor ?? 2,\n };\n\n if (\n typeof retryConfig.maxRetries !== 'number' ||\n retryConfig.maxRetries < 0\n ) {\n throw ConfigurationError('maxRetries must be a non-negative number');\n }\n\n if (typeof retryConfig.delayMs !== 'number' || retryConfig.delayMs <= 0) {\n throw ConfigurationError('retryConfig.delayMs must be a positive number');\n }\n\n if (\n typeof retryConfig.backoffFactor !== 'number' ||\n retryConfig.backoffFactor < 1\n ) {\n throw ConfigurationError('retryConfig.backoffFactor must be >= 1');\n }\n\n // Validate theme mode\n const themeMode = options.themeMode || 'auto';\n if (!['light', 'dark', 'auto'].includes(themeMode)) {\n throw ConfigurationError('themeMode must be \"light\", \"dark\", or \"auto\"');\n }\n\n // Validate sessionAuthorizationUrl if provided (must be non-empty string or valid URL)\n if (options.sessionAuthorizationUrl !== undefined) {\n if (typeof options.sessionAuthorizationUrl !== 'string' || options.sessionAuthorizationUrl.trim() === '') {\n throw ConfigurationError('sessionAuthorizationUrl must be a non-empty string');\n }\n\n try {\n const parsed = new URL(options.sessionAuthorizationUrl, window.location.origin);\n if (parsed.protocol === 'http:' && parsed.hostname !== 'localhost' && parsed.hostname !== '127.0.0.1') {\n throw ConfigurationError('sessionAuthorizationUrl must use https://.');\n }\n } catch (error) {\n // Re-throw our own validation error; swallow URL parse failures for\n // relative paths or other valid fetch() targets.\n if (error instanceof Error && error.name === 'ConfigurationError') {\n throw error;\n }\n }\n }\n\n let resolvedBaseUrl = baseUrl;\n\n if (resolvedBaseUrl === undefined && options.whitelabelDomain !== undefined) {\n const { whitelabelDomain } = options;\n\n if (typeof whitelabelDomain !== 'string' || whitelabelDomain.trim().length === 0) {\n throw ConfigurationError('whitelabelDomain must be a non-empty string');\n }\n\n let domainOrigin: string;\n try {\n const parsed = new URL(whitelabelDomain);\n if (parsed.protocol !== 'https:') {\n throw ConfigurationError('whitelabelDomain must use https://');\n }\n domainOrigin = parsed.origin;\n } catch (error) {\n if (error instanceof Error && error.name === 'ConfigurationError') {\n throw error;\n }\n throw ConfigurationError('whitelabelDomain must be a valid URL');\n }\n\n // Swap only the origin, keeping the build-time /{version}/elements path\n const { pathname } = new URL(__ELEMENTS_BASE_URL__);\n resolvedBaseUrl = `${domainOrigin}${pathname}`;\n }\n\n // FRD-2026-003: Use build-time injected CDN URL or explicit override\n // Build-time default is environment-specific (dev/PR/prod)\n const finalBaseUrl = resolvedBaseUrl || __ELEMENTS_BASE_URL__;\n\n // Extract origin for PostMessage validation (protocol + domain + port only, no path)\n const iframeOrigin = new URL(finalBaseUrl).origin;\n\n return {\n iframeOrigin,\n elementsBaseUrl: finalBaseUrl,\n apiBaseUrl: options.apiBaseUrl, // Optional - auto-detects if not provided\n debug: options.debug ?? false,\n measurePerformance: options.measurePerformance ?? false,\n timeoutMs: options.timeoutMs || 30000, // 30s default for slow 3G connections\n themeMode,\n theme: mergeWithDefaultTheme(options.theme), // Light theme or only theme\n darkTheme: options.darkTheme\n ? mergeWithDefaultTheme(options.darkTheme)\n : undefined, // Optional dark theme\n retryConfig,\n sessionAuthorizationUrl: options.sessionAuthorizationUrl, // Optional - required for cardDisplay\n };\n};\n","/**\n * Element options validation\n */\n\nimport { ConfigurationError } from '@basis-theory-elements/shared';\nimport type { CopyButtonOptions, ElementOptions, ElementType } from '../types';\nimport { warnUnknownKeys } from './warn-unknown-keys';\n\n// Keys valid for ALL element types\nconst COMMON_ELEMENT_KEYS: ReadonlySet<string> = new Set([\n 'placeholder',\n 'ariaLabel',\n 'disabled',\n 'readOnly',\n]);\n\n// Keys valid ONLY for specific element types\nconst ELEMENT_TYPE_KEYS: Record<ElementType, ReadonlySet<string>> = {\n cardNumber: new Set([...COMMON_ELEMENT_KEYS, 'binLookup', 'coBadge']),\n cvv: new Set([...COMMON_ELEMENT_KEYS, 'cardBrand', 'cvvLengths']), // Internal coordination props\n expiry: new Set([...COMMON_ELEMENT_KEYS]),\n text: new Set([\n ...COMMON_ELEMENT_KEYS,\n 'validation',\n 'required',\n 'maxLength',\n 'password',\n 'inputMode',\n 'mask',\n 'transform',\n ]),\n card: new Set([\n ...COMMON_ELEMENT_KEYS,\n 'layout',\n 'stackAt',\n 'iconPosition',\n 'cardBrands',\n 'binLookup',\n 'coBadge',\n ]),\n copyButton: new Set([\n 'allowClipboard',\n 'value',\n 'text',\n 'disabled',\n ]),\n cardDisplay: new Set([\n 'tokenId',\n 'number',\n 'cvc',\n 'expiration',\n ]),\n};\n\n/**\n * Validate element options for a specific element type.\n * Warns about unknown keys and options not applicable to the element type.\n * Throws on invalid values for known keys.\n */\nexport const validateElementOptions = (\n type: ElementType,\n options: ElementOptions = {}\n): void => {\n const validKeys = ELEMENT_TYPE_KEYS[type];\n\n // Warn about unknown/inapplicable keys\n warnUnknownKeys(\n `ElementOptions (${type})`,\n options as Record<string, unknown>,\n validKeys\n );\n\n // Type validation for known keys\n if (options.placeholder !== undefined) {\n // CardElement has structured placeholder: { cardNumber, expiryDate, cvv }\n if (type === 'card') {\n if (typeof options.placeholder !== 'object' || options.placeholder === null) {\n throw ConfigurationError('placeholder for card element must be an object with cardNumber, expiryDate, and cvv keys');\n }\n } else if (typeof options.placeholder !== 'string') {\n throw ConfigurationError('placeholder must be a string');\n }\n }\n\n if (options.disabled !== undefined && typeof options.disabled !== 'boolean') {\n throw ConfigurationError('disabled must be a boolean');\n }\n\n if (options.readOnly !== undefined && typeof options.readOnly !== 'boolean') {\n throw ConfigurationError('readOnly must be a boolean');\n }\n\n if (options.ariaLabel !== undefined && typeof options.ariaLabel !== 'string') {\n throw ConfigurationError('ariaLabel must be a string');\n }\n\n // Text-element-specific validation\n if (type === 'text') {\n if (options.maxLength !== undefined) {\n if (typeof options.maxLength !== 'number' || options.maxLength <= 0) {\n throw ConfigurationError('maxLength must be a positive number');\n }\n }\n\n if (options.password !== undefined && typeof options.password !== 'boolean') {\n throw ConfigurationError('password must be a boolean');\n }\n\n if (options.required !== undefined && typeof options.required !== 'boolean') {\n throw ConfigurationError('required must be a boolean');\n }\n\n if (options.validation !== undefined && !(options.validation instanceof RegExp)) {\n throw ConfigurationError('validation must be a RegExp');\n }\n\n // Transform validation (must be [RegExp, string] tuple)\n if (options.transform) {\n if (\n !Array.isArray(options.transform) ||\n options.transform.length !== 2 ||\n !(options.transform[0] instanceof RegExp) ||\n typeof options.transform[1] !== 'string'\n ) {\n throw ConfigurationError(\n 'transform must be a tuple of [RegExp, string]. Example: [/-/g, \"\"]'\n );\n }\n }\n }\n\n // CopyButton-specific validation\n if (type === 'copyButton') {\n const copyOpts = options as CopyButtonOptions;\n if (copyOpts.allowClipboard !== true) {\n throw ConfigurationError(\n 'CopyButton requires allowClipboard: true. ' +\n 'Clipboard access for raw card data may not be PCI compliant ' +\n 'and must be explicitly enabled.'\n );\n }\n }\n\n // Card-element-specific validation\n if (type === 'card') {\n // Cast to any to access card-specific properties not in ElementOptions\n const cardOptions = options as any;\n\n if (cardOptions.layout !== undefined) {\n if (!['row', 'column', 'auto'].includes(cardOptions.layout)) {\n throw ConfigurationError('layout must be \"row\", \"column\", or \"auto\"');\n }\n }\n\n if (cardOptions.stackAt !== undefined) {\n if (typeof cardOptions.stackAt !== 'number' || cardOptions.stackAt <= 0) {\n throw ConfigurationError('stackAt must be a positive number');\n }\n }\n\n if (cardOptions.iconPosition !== undefined) {\n if (!['left', 'right', 'none'].includes(cardOptions.iconPosition)) {\n throw ConfigurationError('iconPosition must be \"left\", \"right\", or \"none\"');\n }\n }\n\n if (cardOptions.cardBrands !== undefined) {\n if (!Array.isArray(cardOptions.cardBrands)) {\n throw ConfigurationError('cardBrands must be an array of strings');\n }\n // Validate all elements are strings\n if (cardOptions.cardBrands.some((brand: any) => typeof brand !== 'string')) {\n throw ConfigurationError('All cardBrands must be strings');\n }\n }\n }\n};\n","/**\n * @basis-theory/web-elements\n * Main SDK factory function\n */\n\nimport { createPostMessageClient } from '@basis-theory-elements/postmessage';\nimport {\n createDebugLogger,\n type DebugLogger,\n ConfigurationError,\n CoordinatorError,\n ElementError,\n ValidationError,\n validateProxyOptions as sharedValidateProxyOptions,\n} from '@basis-theory-elements/shared';\nimport { createCardNumberElement } from './elements/create-card-number';\nimport { createCVVElement } from './elements/create-cvv';\nimport { createExpiryElement } from './elements/create-expiry';\nimport { createTextElement } from './elements/create-text';\n// Lazy-loaded: card and copyButton elements are only imported when createElement() is called\nimport type { createCardElement as CreateCardElementType } from './elements/create-card';\nimport type { createCopyButtonElement as CreateCopyButtonElementType } from './elements/create-copy-button';\nimport type { createCardDisplayElement as CreateCardDisplayElementType } from './elements/create-card-display';\nimport type {\n BasisTheorySDK,\n CopyButtonOptions,\n Element,\n ElementOptions,\n ElementType,\n EncryptedToken,\n EncryptToken,\n EventType,\n EventListener,\n ProxyRequestOptions,\n ProxyResponse,\n SDKConfig,\n SDKOptions,\n Session,\n ElementInputObject,\n TokenCreateRequest,\n TokenIntent,\n TokenIntentRequest,\n TokenizeResult,\n TokenUpdateRequest,\n} from './types';\nimport { resolveElementReferences } from './utils/resolve-element-references';\nimport { validateAPIKey, validateSDKConfig } from './utils/validate-sdk-config';\nimport { validateElementOptions } from './utils/validate-element-options';\n// Theme injection now handled via PostMessage CMD_SET_CONFIG\n\n/**\n * Queued command from loader\n * Commands are queued before SDK loads, then replayed\n */\ninterface QueuedCommand {\n method: 'createElement' | 'tokenize' | 'updateThemeMode';\n args: any[];\n resolve: (result: any) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * Creates a BasisTheory SDK instance\n * Factory function (no class, pure functional approach)\n *\n * @param apiKey - Your Basis Theory public API key (starts with 'pk_')\n * @param options - SDK configuration options\n * @param queuedCommands - Optional: Commands queued by loader before SDK loaded\n * @returns SDK instance with methods to create and tokenize elements\n *\n * @example\n * ```typescript\n * import BasisTheory from '@basis-theory/web-elements';\n *\n * const bt = BasisTheory('pk_test_YOUR_API_KEY');\n *\n * const cardNumber = bt.createElement('cardNumber', {\n * placeholder: '4111 1111 1111 1111'\n * });\n *\n * await cardNumber.mount('#card-number');\n * ```\n */\nconst BasisTheory = (\n apiKey: string,\n options: SDKOptions = {},\n queuedCommands?: QueuedCommand[]\n): BasisTheorySDK => {\n // Validate inputs\n validateAPIKey(apiKey);\n const config: SDKConfig = validateSDKConfig(options);\n\n // Create debug logger\n const log: DebugLogger = createDebugLogger('SDK', config.debug || false);\n\n log('SDK initialized', {\n apiKeyPrefix: apiKey.substring(0, 7) + '...',\n elementsBaseUrl: config.elementsBaseUrl,\n iframeOrigin: config.iframeOrigin,\n debug: config.debug || false,\n });\n\n // Shared state (private to SDK instance)\n const elements = new Map<string, Element>();\n\n // Coordinator iframe reference\n let coordinatorIframe: HTMLIFrameElement | null = null;\n let coordinatorClient: ReturnType<typeof createPostMessageClient> | null =\n null;\n\n /**\n * PERFORMANCE OPTIMIZATION (Step 3):\n * Start coordinator initialization IMMEDIATELY (but don't wait)\n * Elements will await this promise in their mount() function\n */\n let coordinatorReadyPromise: Promise<void> | null = null;\n let coordinatorInitStarted = false;\n // Timeout + reject for the coordinator load-wait, so destroy() can settle it.\n // Otherwise a destroy() mid-load removes the iframe (so its `load` never fires)\n // and a mount() awaiting coordinatorReadyPromise waits out the full timeout\n // before rejecting. Null when no load is pending.\n let coordinatorLoadTimeout: ReturnType<typeof setTimeout> | null = null;\n let rejectCoordinatorLoad: ((error: Error) => void) | null = null;\n\n // Once destroyed, every public method throws so callers can detect a stale\n // instance and re-initialize with a fresh BasisTheory() call.\n let destroyed = false;\n\n const assertNotDestroyed = (): void => {\n if (destroyed) {\n throw ConfigurationError(\n 'SDK instance has been destroyed. Create a new instance with BasisTheory()'\n );\n }\n };\n\n // Wrap public methods with the destroyed check so each one doesn't repeat\n // assertNotDestroyed(). guardAsync rejects instead of throwing, so callers\n // awaiting the method see a rejected promise rather than a synchronous throw.\n const guardSync = <A extends unknown[], R>(\n fn: (...args: A) => R\n ): ((...args: A) => R) => (...args: A): R => {\n assertNotDestroyed();\n return fn(...args);\n };\n\n const guardAsync = <A extends unknown[], R>(\n fn: (...args: A) => Promise<R>\n ): ((...args: A) => Promise<R>) => async (...args: A): Promise<R> => {\n assertNotDestroyed();\n return fn(...args);\n };\n\n // Store current theme mode for updates\n let currentThemeMode: string = options.themeMode || 'auto';\n\n // Element factory registry\n // Card element is lazy-loaded to reduce initial bundle size\n type ElementFactory = (\n apiKey: string,\n sdkConfig: SDKConfig,\n options: ElementOptions | CopyButtonOptions | undefined,\n coordinatorElementId: string,\n ensureCoordinatorReady: () => Promise<void>,\n notifyCoordinatorElementUnmount: (elementId: string) => Promise<void>,\n coordinatorRequest: <T>(command: string, payload: unknown) => Promise<T>\n ) => Element;\n type LazyElementFactory = () => Promise<ElementFactory>;\n\n /**\n * Create a lazy-loaded element wrapper that delegates to the real element after import\n * Shared by all lazy-loaded element types (card, copyButton, cardDisplay)\n */\n const createLazyElementWrapper = (\n lazyFactory: LazyElementFactory,\n elementType: ElementType,\n elementId: string,\n elementApiKey: string,\n elementConfig: SDKConfig,\n elementOptions: ElementOptions | CopyButtonOptions | undefined,\n ensureCoordinator: () => Promise<void>,\n notifyUnmount: (id: string) => Promise<void>,\n coordinatorRequest: <T>(command: string, payload: unknown) => Promise<T>\n ): Element => {\n let realElement: Element | null = null;\n let loadPromise: Promise<void> | null = null;\n\n const loadRealElement = async () => {\n if (!loadPromise) {\n loadPromise = (async () => {\n const factory = await lazyFactory();\n realElement = factory(\n elementApiKey,\n elementConfig,\n elementOptions,\n elementId,\n ensureCoordinator,\n notifyUnmount,\n coordinatorRequest\n );\n })();\n }\n await loadPromise;\n };\n\n const ensureLoaded = () => {\n if (!realElement) throw ElementError('Element not initialized');\n return realElement;\n };\n\n const wrapper = {\n id: elementId,\n type: elementType,\n get mounted() {\n return realElement?.mounted ?? false;\n },\n get loaded() {\n return realElement?.loaded ?? false;\n },\n mount: async (selector: string | HTMLElement) => {\n await loadRealElement();\n return realElement!.mount(selector);\n },\n unmount: () => ensureLoaded().unmount(),\n update: async (opts: Partial<ElementOptions>) => ensureLoaded().update(opts),\n focus: () => ensureLoaded().focus(),\n blur: () => ensureLoaded().blur(),\n clear: () => ensureLoaded().clear(),\n on: (eventType: EventType, listener: EventListener) => {\n if (!realElement) {\n // Lazy path: the real subscription doesn't exist yet. Capture a\n // cancellation flag and forward to the real unsubscribe once it\n // resolves, so callers that clean up before (or after) the load\n // completes still tear down the listener.\n let unsubscribe: (() => void) | null = null;\n let cancelled = false;\n loadRealElement().then(() => {\n if (!cancelled) unsubscribe = realElement!.on(eventType, listener);\n });\n return () => {\n cancelled = true;\n unsubscribe?.();\n };\n }\n return realElement.on(eventType, listener);\n },\n setValueRef: async (refElement: Element) => {\n if (!realElement) {\n await loadRealElement();\n }\n if (realElement && 'setValueRef' in realElement && typeof realElement.setValueRef === 'function') {\n return realElement.setValueRef(refElement);\n }\n throw ElementError('setValueRef not available on this element type');\n },\n } as Element;\n\n // The number/expiryDate/cvc sub-field refs exist only on the card element;\n // don't expose them on copyButton/cardDisplay wrappers where they'd be undefined.\n if (elementType === 'card') {\n Object.defineProperties(wrapper, {\n number: {\n get: () => (realElement as any)?.number,\n enumerable: true,\n },\n expiryDate: {\n get: () => (realElement as any)?.expiryDate,\n enumerable: true,\n },\n cvc: {\n get: () => (realElement as any)?.cvc,\n enumerable: true,\n },\n });\n }\n\n return wrapper;\n };\n\n /**\n * Notify coordinator to broadcast ELEMENT_UNMOUNTED\n * This is called by elements during unmount to clear cached values\n * and notify other elements (like CopyButton) about the unmount.\n * Using coordinator ensures reliable delivery since it's always alive.\n */\n const notifyCoordinatorElementUnmount = async (elementId: string): Promise<void> => {\n if (!coordinatorClient) {\n log('Cannot notify coordinator of unmount - coordinator not initialized', {\n elementId,\n });\n return;\n }\n\n try {\n await coordinatorClient.sendRequest('CMD_BROADCAST_ELEMENT_UNMOUNT', {\n elementId,\n });\n log('Notified coordinator of element unmount', { elementId });\n } catch (error) {\n log('Failed to notify coordinator of element unmount', {\n elementId,\n error: (error as Error).message,\n });\n }\n };\n\n /**\n * Send a request to the coordinator iframe and await its response.\n *\n * Used by the cardDisplay element to drive the display-token flow that spans\n * the iframe boundary (create session -> parent authorizes -> retrieve token).\n * Callers must await ensureCoordinatorInitialized() before invoking this.\n */\n const sendCoordinatorRequest = async <T>(\n command: string,\n payload: unknown\n ): Promise<T> => {\n if (!coordinatorClient) {\n throw CoordinatorError('Coordinator not initialized');\n }\n\n return coordinatorClient.sendRequest<T>(command, payload);\n };\n\n // Cache for lazy-loaded modules\n let cardElementFactory: typeof CreateCardElementType | null = null;\n let copyButtonElementFactory: typeof CreateCopyButtonElementType | null = null;\n let cardDisplayElementFactory: typeof CreateCardDisplayElementType | null = null;\n\n // Lazy loader for card element - only loads when first used\n const lazyCardElement: LazyElementFactory = async () => {\n if (!cardElementFactory) {\n const module = await import('./elements/create-card');\n cardElementFactory = module.createCardElement;\n }\n return cardElementFactory as unknown as ElementFactory;\n };\n\n // Lazy loader for copy button element - only loads when first used\n const lazyCopyButtonElement: LazyElementFactory = async () => {\n if (!copyButtonElementFactory) {\n const module = await import('./elements/create-copy-button');\n copyButtonElementFactory = module.createCopyButtonElement;\n }\n return copyButtonElementFactory as unknown as ElementFactory;\n };\n\n // Lazy loader for cardDisplay element\n const lazyCardDisplayElement: LazyElementFactory = async () => {\n if (!cardDisplayElementFactory) {\n const module = await import('./elements/create-card-display');\n cardDisplayElementFactory = module.createCardDisplayElement;\n }\n return cardDisplayElementFactory as unknown as ElementFactory;\n };\n\n // Factory registry: sync factories for common elements, async for card\n const syncFactories: Record<string, ElementFactory> = {\n cardNumber: createCardNumberElement,\n cvv: createCVVElement,\n expiry: createExpiryElement,\n text: createTextElement,\n };\n\n const lazyFactories: Record<string, LazyElementFactory> = {\n card: lazyCardElement,\n copyButton: lazyCopyButtonElement,\n cardDisplay: lazyCardDisplayElement,\n };\n\n /**\n * PERFORMANCE OPTIMIZATION (Step 3):\n * Start coordinator initialization (non-blocking)\n * Returns a promise that resolves when coordinator is ready\n */\n const ensureCoordinatorInitialized = (): Promise<void> => {\n if (coordinatorReadyPromise) {\n return coordinatorReadyPromise;\n }\n\n if (coordinatorInitStarted) {\n return coordinatorReadyPromise!;\n }\n\n coordinatorInitStarted = true;\n coordinatorReadyPromise = initializeCoordinator();\n return coordinatorReadyPromise;\n };\n\n /**\n * Initialize coordinator iframe (internal async logic)\n */\n const initializeCoordinator = async (): Promise<void> => {\n if (coordinatorIframe) {\n log('Coordinator already initialized', {\n loaded: coordinatorIframe.contentWindow !== null,\n });\n return; // Already initialized\n }\n\n log('Initializing coordinator iframe', {\n elementsBaseUrl: config.elementsBaseUrl,\n });\n\n // Create hidden iframe for coordinator\n coordinatorIframe = document.createElement('iframe');\n coordinatorIframe.setAttribute('name', 'bt-coordinator');\n coordinatorIframe.setAttribute('title', 'BasisTheory Coordinator');\n coordinatorIframe.setAttribute('role', 'none');\n coordinatorIframe.style.border = 'none';\n coordinatorIframe.style.width = '0';\n coordinatorIframe.style.height = '0';\n coordinatorIframe.style.position = 'absolute';\n coordinatorIframe.style.top = '-9999px';\n coordinatorIframe.style.left = '-9999px';\n\n // Set iframe src with parent origin for PostMessage validation\n // Ensure elementsBaseUrl ends with / for proper URL resolution\n const baseUrl = config.elementsBaseUrl.endsWith('/')\n ? config.elementsBaseUrl\n : `${config.elementsBaseUrl}/`;\n const coordinatorUrl = new URL('coordinator.html', baseUrl);\n coordinatorUrl.searchParams.set('parentOrigin', window.location.origin);\n coordinatorIframe.src = coordinatorUrl.toString();\n\n // Mount coordinator iframe\n document.body.appendChild(coordinatorIframe);\n\n log('Coordinator iframe mounted', {\n url: coordinatorIframe.src,\n });\n\n // Wait for coordinator to load (use configured timeout for slow connections)\n await new Promise<void>((resolve, reject) => {\n // Expose this wait's reject so destroy() can abort it.\n rejectCoordinatorLoad = reject;\n coordinatorLoadTimeout = setTimeout(() => {\n coordinatorLoadTimeout = null;\n rejectCoordinatorLoad = null;\n reject(\n new Error(\n `Coordinator load timeout (${config.timeoutMs}ms). Try increasing timeoutMs for slow connections.`\n )\n );\n }, config.timeoutMs);\n\n coordinatorIframe!.addEventListener(\n 'load',\n () => {\n if (coordinatorLoadTimeout !== null) {\n clearTimeout(coordinatorLoadTimeout);\n }\n // Load settled — destroy() has nothing left to abort.\n coordinatorLoadTimeout = null;\n rejectCoordinatorLoad = null;\n log('Coordinator iframe loaded');\n resolve();\n },\n { once: true }\n );\n });\n\n // A destroy() can land between the load resolving and this continuation\n // running, after it has already removed and nulled the iframe. Bail before\n // createPostMessageClient(null), which would otherwise register a window\n // message listener that destroy() already passed and never cleans up.\n if (destroyed) {\n log('Coordinator load resolved after destroy — aborting init');\n return;\n }\n\n // Create PostMessage client for coordinator\n coordinatorClient = createPostMessageClient(coordinatorIframe, {\n targetOrigin: new URL(config.elementsBaseUrl).origin,\n timeout: 30000,\n retries: 3,\n debug: config.debug || false,\n });\n\n log('Coordinator PostMessage client created');\n\n // Send configuration to coordinator\n await coordinatorClient.sendRequest('CMD_SET_CONFIG', {\n apiKey,\n apiBaseUrl: config.apiBaseUrl, // Optional - auto-detects if not provided\n apiTimeout: 30000,\n apiRetries: 3,\n debug: config.debug || false,\n theme: config.theme,\n darkTheme: config.darkTheme,\n themeMode: config.themeMode,\n // sessionAuthorizationUrl is intentionally NOT sent to the coordinator:\n // the merchant-authorization fetch now runs in the parent page (see\n // create-card-display.ts), so the coordinator never needs the URL.\n });\n\n log('Coordinator initialized successfully');\n };\n\n /**\n * Coordinator initialization is LAZY - starts on first mount()\n * This keeps SDK initialization fast (<5ms) to match competitors\n * All iframes (coordinator + elements) load in PARALLEL during mount()\n */\n\n // Public API\n const sdk: BasisTheorySDK = {\n /**\n * PERFORMANCE OPTIMIZATION (Step 2 & 3):\n * createElement is now SYNCHRONOUS - returns Element instantly\n * Coordinator initialization starts on first element (but doesn't block)\n */\n createElement: (guardSync((\n type: ElementType,\n elementOptions?: ElementOptions | CopyButtonOptions\n ) => {\n // Validate element type - check both sync and lazy factories\n const syncFactory = syncFactories[type];\n const lazyFactory = lazyFactories[type];\n\n if (!syncFactory && !lazyFactory) {\n throw ConfigurationError(`Unknown element type: ${type}`);\n }\n\n // Validate element options (warns about unknown keys, throws on invalid values)\n if (elementOptions) {\n validateElementOptions(type, elementOptions);\n }\n\n // Generate local element ID immediately (don't wait for coordinator)\n const localElementId = `${type}-${Date.now()}-${Math.random()\n .toString(36)\n .slice(2, 9)}`;\n\n log('Creating element (sync)', {\n type,\n elementId: localElementId,\n coordinatorInitialized: coordinatorIframe !== null,\n isLazyLoaded: !!lazyFactory,\n });\n\n // ✅ STEP 3: Coordinator initialization deferred to first mount() call\n // No blocking or async work in createElement!\n\n let element: Element;\n\n if (syncFactory) {\n // Sync factory - create element immediately\n element = syncFactory(\n apiKey,\n config,\n elementOptions,\n localElementId,\n ensureCoordinatorInitialized,\n notifyCoordinatorElementUnmount,\n sendCoordinatorRequest\n );\n } else {\n element = createLazyElementWrapper(\n lazyFactory!,\n type,\n localElementId,\n apiKey,\n config,\n elementOptions,\n ensureCoordinatorInitialized,\n notifyCoordinatorElementUnmount,\n sendCoordinatorRequest\n );\n }\n\n elements.set(element.id, element);\n\n // ✅ Auto-coordination: Card number brand detection → CVV maxlength update\n if (type === 'cardNumber') {\n element.on('change', (event: CustomEvent) => {\n const { cardBrand, cvvLengths } = event.detail;\n\n log('Card number change event received', {\n cardBrand,\n cvvLengths,\n cvvElementsCount: Array.from(elements.values()).filter(\n (el) => el.type === 'cvv'\n ).length,\n });\n\n // If card brand detected, notify all CVV elements\n if (cardBrand && cardBrand !== 'Unknown' && cvvLengths) {\n for (const [id, cvvElement] of elements) {\n if (cvvElement.type === 'cvv' && cvvElement.mounted) {\n log('Coordinating CVV element with card brand', {\n cvvElementId: id,\n cardBrand,\n cvvLengths,\n mounted: cvvElement.mounted,\n });\n\n // Send brand info to CVV element\n cvvElement\n .update({\n cardBrand,\n cvvLengths, // Send cvvLengths array instead of full brandDefinition\n })\n .catch((error) => {\n log('Failed to update CVV element with card brand', {\n cvvElementId: id,\n cardBrand,\n error: (error as Error).message,\n });\n });\n }\n }\n }\n });\n }\n\n return element;\n }) as BasisTheorySDK['createElement']),\n\n tokenize: guardAsync(async (\n payload?: ElementInputObject,\n options?: Record<string, unknown>\n ): Promise<TokenizeResult> => {\n log('tokenize called', {\n hasPayload: !!payload,\n hasOptions: !!options,\n coordinatorReady: !!coordinatorClient,\n });\n\n // Wait for coordinator to be ready\n if (!coordinatorClient) {\n log('Waiting for coordinator initialization');\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw CoordinatorError('Coordinator failed to initialize');\n }\n\n try {\n // ✅ V2 API Compatibility: Resolve element references in payload\n // Recursively converts Element instances → { __elementRef__: elementId }\n const resolvedPayload = payload\n ? resolveElementReferences(payload)\n : {};\n\n log('Element references resolved', {\n originalPayload: !!payload,\n resolvedPayload: !!resolvedPayload,\n });\n\n // Delegate to coordinator (collects values from cache, 0ms latency!)\n log('Delegating tokenization to coordinator');\n\n const token = await coordinatorClient.sendRequest<TokenizeResult>(\n 'CMD_TOKENIZE',\n {\n payload: resolvedPayload,\n options,\n }\n );\n\n log('tokenize successful', {\n tokenId: token.id,\n });\n\n return token;\n } catch (error) {\n log('tokenize failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n\n /**\n * Token CRUD operations\n * Supports Element references - automatically resolves to secure values\n */\n tokens: {\n /**\n * Create a new token\n * Supports Element references in data (same as tokenize)\n */\n create: guardAsync(async (request: TokenCreateRequest): Promise<TokenizeResult> => {\n // Validate input\n if (!request || typeof request !== 'object' || Array.isArray(request)) {\n throw ValidationError('Token data must be a non-null object');\n }\n\n log('tokens.create called', {\n type: request.type,\n hasData: !!request.data,\n });\n\n // Wait for coordinator to be ready (needed for element value resolution)\n if (!coordinatorClient) {\n log('Waiting for coordinator initialization');\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw new Error('Coordinator failed to initialize');\n }\n\n try {\n // Only `data` can contain Element references — resolve it, preserve the rest\n const resolvedRequest = {\n ...request,\n data: resolveElementReferences(request.data),\n };\n\n log('Element references resolved for tokens.create', {\n resolvedData: !!resolvedRequest,\n });\n\n // Delegate to coordinator for token creation\n const token = await coordinatorClient.sendRequest<TokenizeResult>(\n 'CMD_TOKENS_CREATE',\n { data: resolvedRequest }\n );\n\n log('tokens.create successful', { tokenId: token.id });\n\n return token;\n } catch (error) {\n log('tokens.create failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n\n /**\n * Retrieve a token by ID\n *\n * @param id - Token ID to retrieve\n * @param options - Optional configuration\n * @param options.apiKey - Optional session key for authorized access (from sessions.create + authorize)\n */\n retrieve: guardAsync(async (\n id: string,\n options?: { apiKey?: string }\n ): Promise<TokenizeResult> => {\n log('tokens.retrieve called', {\n tokenId: id,\n hasSessionKey: !!options?.apiKey,\n });\n\n // Wait for coordinator (needed for API calls)\n if (!coordinatorClient) {\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw new Error('Coordinator failed to initialize');\n }\n\n try {\n const token = await coordinatorClient.sendRequest<TokenizeResult>(\n 'CMD_TOKENS_RETRIEVE',\n {\n id,\n apiKey: options?.apiKey, // Pass session key to coordinator\n }\n );\n\n log('tokens.retrieve successful', {\n tokenId: token.id,\n });\n\n return token;\n } catch (error) {\n log('tokens.retrieve failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n\n /**\n * Update a token\n * Supports Element references in data\n */\n update: guardAsync(async (id: string, request: TokenUpdateRequest): Promise<TokenizeResult> => {\n log('tokens.update called', { tokenId: id });\n\n // Wait for coordinator\n if (!coordinatorClient) {\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw new Error('Coordinator failed to initialize');\n }\n\n try {\n // Only `data` can contain Element references — resolve it, preserve the rest\n const resolvedRequest = request.data\n ? { ...request, data: resolveElementReferences(request.data) }\n : request;\n\n const token = await coordinatorClient.sendRequest<TokenizeResult>(\n 'CMD_TOKENS_UPDATE',\n { id, data: resolvedRequest }\n );\n\n log('tokens.update successful', { tokenId: token.id });\n\n return token;\n } catch (error) {\n log('tokens.update failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n\n /**\n * Encrypt token data with client-side JWE\n * Uses ECDH-ES key agreement and A256GCM authenticated encryption\n * Supports Element references - automatically resolves to secure values\n *\n * @param tokenData - Single token or multiple tokens to encrypt\n * @param publicKeyPEM - X25519 public key in PEM format\n * @param keyId - Key identifier for decryption lookup\n * @returns Encrypted JWE token(s)\n */\n encrypt: guardAsync(async (\n tokenData: EncryptToken | Record<string, EncryptToken>,\n publicKeyPEM: string,\n keyId: string\n ): Promise<EncryptedToken | Record<string, EncryptedToken>> => {\n log('tokens.encrypt called', {\n isSingleToken: 'type' in tokenData && 'data' in tokenData,\n keyId,\n });\n\n // Validate inputs\n if (!tokenData || typeof tokenData !== 'object') {\n throw ValidationError('tokenData must be an object');\n }\n\n if (!publicKeyPEM || typeof publicKeyPEM !== 'string') {\n throw ValidationError('publicKeyPEM is required');\n }\n\n if (!keyId || typeof keyId !== 'string') {\n throw ValidationError('keyId is required');\n }\n\n // Wait for coordinator\n if (!coordinatorClient) {\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw new Error('Coordinator failed to initialize');\n }\n\n try {\n // Recursively resolve Element references at any depth.\n // Coordinator owns single-vs-multiple dispatch; we just normalize the payload.\n const resolvedTokenData = resolveElementReferences(tokenData);\n\n log('Element references resolved for tokens.encrypt', {\n originalData: !!tokenData,\n resolvedData: !!resolvedTokenData,\n });\n\n // Delegate to coordinator for encryption\n const encrypted = await coordinatorClient.sendRequest<\n EncryptedToken | Record<string, EncryptedToken>\n >('CMD_TOKENS_ENCRYPT', {\n tokenRequests: resolvedTokenData,\n publicKeyPEM,\n keyId,\n });\n\n log('tokens.encrypt successful', {\n isSingleToken: 'encrypted' in encrypted && 'type' in encrypted,\n });\n\n return encrypted;\n } catch (error) {\n log('tokens.encrypt failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n },\n\n sessions: {\n /**\n * Create a new session for temporary elevated access\n * Note: Session must be authorized by a Private Application on your backend\n */\n create: guardAsync(async (): Promise<Session> => {\n log('sessions.create called');\n\n // Wait for coordinator\n if (!coordinatorClient) {\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw new Error('Coordinator failed to initialize');\n }\n\n try {\n const session = await coordinatorClient.sendRequest<Session>(\n 'CMD_SESSIONS_CREATE',\n {}\n );\n\n log('sessions.create successful', {\n nonce: session.nonce,\n expiresAt: session.expires_at,\n });\n\n return session;\n } catch (error) {\n log('sessions.create failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n },\n\n tokenIntents: {\n /**\n * Create a token intent with element reference support\n */\n create: guardAsync(async (data: TokenIntentRequest, options?: { apiKey?: string }): Promise<TokenIntent> => {\n log('tokenIntents.create called', {\n type: data.type,\n hasData: !!data.data,\n hasOptions: !!options,\n });\n\n // Wait for coordinator\n if (!coordinatorClient) {\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw new Error('Coordinator failed to initialize');\n }\n\n try {\n const resolvedData = resolveElementReferences(data.data);\n\n log('Element references resolved for token intent');\n\n // Delegate to coordinator\n const intent = await coordinatorClient.sendRequest<TokenIntent>(\n 'CMD_TOKEN_INTENTS_CREATE',\n {\n type: data.type,\n data: resolvedData,\n options,\n }\n );\n\n log('tokenIntents.create successful', {\n intentId: intent.id,\n });\n\n return intent;\n } catch (error) {\n log('tokenIntents.create failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n\n /**\n * Get a token intent by ID\n */\n get: guardAsync(async (id: string, options?: { apiKey?: string }): Promise<TokenIntent> => {\n log('tokenIntents.get called', {\n intentId: id,\n });\n\n // Wait for coordinator\n if (!coordinatorClient) {\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw new Error('Coordinator failed to initialize');\n }\n\n try {\n const intent = await coordinatorClient.sendRequest<TokenIntent>(\n 'CMD_TOKEN_INTENTS_GET',\n {\n id,\n options,\n }\n );\n\n log('tokenIntents.get successful', {\n intentId: intent.id,\n });\n\n return intent;\n } catch (error) {\n log('tokenIntents.get failed', {\n error: (error as Error).message,\n });\n throw error;\n }\n }),\n },\n\n proxy: (() => {\n type ProxyMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\n const invokeProxy = guardAsync(async (\n method: ProxyMethod,\n options: ProxyRequestOptions = {}\n ): Promise<unknown | ProxyResponse> => {\n sharedValidateProxyOptions({ ...options, method });\n\n log('proxy invoked', {\n method,\n hasUrl: !!options.url,\n hasProxyKey: !!options.proxyKey,\n });\n\n if (!coordinatorClient) {\n log('Waiting for coordinator initialization');\n await initializeCoordinator();\n }\n\n if (!coordinatorClient) {\n throw CoordinatorError('Coordinator failed to initialize');\n }\n\n const resolvedBody =\n options.body !== undefined\n ? resolveElementReferences(options.body as ElementInputObject)\n : undefined;\n\n try {\n // Proxy requests should NOT retry - they may be non-idempotent operations\n const result = await coordinatorClient.sendRequest<\n unknown | ProxyResponse\n >(\n 'CMD_PROXY',\n {\n method,\n url: options.url,\n proxyKey: options.proxyKey,\n headers: options.headers,\n body: resolvedBody,\n includeResponseHeaders: options.includeResponseHeaders,\n },\n { retries: 0 }\n );\n\n log('proxy successful', { method });\n\n return result;\n } catch (error) {\n log('proxy failed', {\n method,\n error: (error as Error).message,\n });\n throw error;\n }\n });\n\n const proxyVerb = (method: ProxyMethod) => (options?: ProxyRequestOptions) =>\n invokeProxy(method, options ?? {});\n\n return {\n get: proxyVerb('GET'),\n post: proxyVerb('POST'),\n put: proxyVerb('PUT'),\n patch: proxyVerb('PATCH'),\n delete: proxyVerb('DELETE'),\n } as BasisTheorySDK['proxy'];\n })(),\n\n updateThemeMode: guardAsync(async (mode: string) => {\n log('updateThemeMode called', {\n oldMode: currentThemeMode,\n newMode: mode,\n mountedElements: Array.from(elements.values()).filter(\n (el) => el.mounted\n ).length,\n });\n\n currentThemeMode = mode;\n\n // Send theme mode update to all mounted elements via PostMessage\n const updatePromises: Promise<void>[] = [];\n\n for (const [id, element] of elements) {\n if (element.mounted) {\n log('Sending theme mode update to element', {\n elementId: id,\n elementType: element.type,\n mode,\n });\n\n // Update iframe attribute (for CSS-based detection)\n const iframe = document.querySelector(\n `iframe[data-bt-element-id=\"${element.id}\"]`\n );\n\n if (iframe) {\n iframe.setAttribute('data-theme-mode', mode);\n }\n\n // Send theme update via PostMessage\n // Element factories now support themeMode in update()\n const updatePromise = element\n .update({\n themeMode: mode,\n } as any) // Type assertion needed until Element interface is updated\n .catch((error) => {\n log('Failed to update theme mode for element', {\n elementId: id,\n error: (error as Error).message,\n });\n });\n\n updatePromises.push(updatePromise);\n }\n }\n\n // Wait for all updates to complete\n await Promise.all(updatePromises);\n\n log('Theme mode updated for all mounted elements', {\n mode,\n updatedCount: Array.from(elements.values()).filter((el) => el.mounted)\n .length,\n });\n }),\n\n /**\n * Destroys this instance and removes its elements from the page. Once\n * destroyed, its other methods throw; create a new instance with\n * BasisTheory() to recover. Safe to call more than once.\n */\n destroy: async () => {\n if (destroyed) {\n return;\n }\n\n // Flag first so any in-flight async work (mid-mount, mid-tokenize) that\n // re-enters a guarded method short-circuits instead of touching torn-down state.\n destroyed = true;\n\n log('Destroying SDK instance', {\n elementCount: elements.size,\n hasCoordinator: coordinatorIframe !== null,\n });\n\n // Unmount every mounted element. unmount() throws when not mounted (and\n // lazy wrappers throw when never loaded), so guard on mounted and isolate\n // failures so one bad element can't abort teardown of the rest.\n for (const [id, element] of elements) {\n if (!element.mounted) {\n continue;\n }\n\n try {\n element.unmount();\n } catch (error) {\n log('Failed to unmount element during destroy', {\n elementId: id,\n error: (error as Error).message,\n });\n }\n }\n elements.clear();\n\n // Abort a still-in-flight coordinator load so a mount() awaiting\n // coordinatorReadyPromise rejects immediately instead of waiting out the\n // full timeout. destroy removes the iframe below, so its `load` event\n // would otherwise never fire.\n if (coordinatorLoadTimeout !== null) {\n clearTimeout(coordinatorLoadTimeout);\n coordinatorLoadTimeout = null;\n }\n if (rejectCoordinatorLoad) {\n rejectCoordinatorLoad(\n ConfigurationError(\n 'SDK instance has been destroyed. Create a new instance with BasisTheory()'\n )\n );\n rejectCoordinatorLoad = null;\n }\n\n // Clear the cached values while the coordinator is still alive (PCI DSS\n // 3.2.1). unmount() only queues the notification, so if we removed the\n // iframe first that message would be dropped and raw card data would sit\n // in the detached heap until GC. We wait for the clear to confirm, but\n // cap the wait so a stuck coordinator can't block teardown. If it times\n // out we move on and let GC handle the removed iframe.\n if (coordinatorClient) {\n const CACHE_CLEAR_TIMEOUT_MS = 2000;\n\n // Swallow the request's own rejection so a late (post-cap) failure\n // doesn't surface as an unhandled rejection once the cap wins the race.\n const cacheCleared = coordinatorClient\n .sendRequest('CMD_CLEAR_ALL_CACHE', {}, { retries: 0 })\n .catch((error) => {\n log('Failed to clear coordinator cache during destroy', {\n error: (error as Error).message,\n });\n });\n\n let capTimeout: ReturnType<typeof setTimeout> | undefined;\n const cap = new Promise<void>((resolve) => {\n capTimeout = setTimeout(() => {\n log('Coordinator cache-clear timed out during destroy', {\n timeoutMs: CACHE_CLEAR_TIMEOUT_MS,\n });\n resolve();\n }, CACHE_CLEAR_TIMEOUT_MS);\n });\n\n await Promise.race([cacheCleared, cap]);\n if (capTimeout !== undefined) {\n clearTimeout(capTimeout);\n }\n }\n\n // Destroy the coordinator client — rejects any pending requests so\n // in-flight tokenize/token operations fail fast rather than hang.\n if (coordinatorClient) {\n coordinatorClient.destroy();\n coordinatorClient = null;\n }\n\n // Remove the coordinator iframe from the DOM.\n if (coordinatorIframe) {\n coordinatorIframe.remove();\n coordinatorIframe = null;\n }\n\n // Reset coordinator init state. (This instance is dead — these resets\n // matter for symmetry and to release the cached rejected promise.)\n coordinatorReadyPromise = null;\n coordinatorInitStarted = false;\n\n log('SDK instance destroyed');\n },\n\n };\n\n // ============================================================================\n // Queue Drain Logic - Replay commands queued by loader\n // ============================================================================\n\n if (queuedCommands && queuedCommands.length > 0) {\n log('Draining command queue from loader', {\n queueLength: queuedCommands.length,\n commands: queuedCommands.map((cmd) => cmd.method),\n });\n\n // Process each queued command\n for (const cmd of queuedCommands) {\n try {\n const method = sdk[cmd.method] as Function;\n\n if (!method) {\n throw new Error(`Unknown method: ${cmd.method}`);\n }\n\n log('Replaying queued command', {\n method: cmd.method,\n argsCount: cmd.args.length,\n });\n\n // Execute the method with queued arguments\n const result = method(...cmd.args);\n\n // Handle both sync and async results\n if (result && typeof result.then === 'function') {\n result\n .then((value: any) => {\n log('Queued command completed (async)', {\n method: cmd.method,\n });\n cmd.resolve(value);\n })\n .catch((error: Error) => {\n log('Queued command failed (async)', {\n method: cmd.method,\n error: error.message,\n });\n cmd.reject(error);\n });\n } else {\n log('Queued command completed (sync)', {\n method: cmd.method,\n });\n cmd.resolve(result);\n }\n } catch (error) {\n log('Queued command failed (sync)', {\n method: cmd.method,\n error: (error as Error).message,\n });\n cmd.reject(error as Error);\n }\n }\n\n log('Command queue drain complete', {\n processedCount: queuedCommands.length,\n });\n }\n\n return sdk;\n};\n\n// ============================================================================\n// UMD Support - Auto-attach to window for script tags\n// ============================================================================\n\ndeclare global {\n interface Window {\n BasisTheory?: typeof BasisTheory;\n }\n}\n\n/**\n * Attaches to window when importing via `<script>` tags\n * Matches v2's pattern: window.basistheory → window.BasisTheory in v3\n */\nif (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n document.currentScript &&\n !window.BasisTheory\n) {\n window.BasisTheory = BasisTheory;\n}\n\n// Default export for ESM\nexport default BasisTheory;\n\n// Named exports for tree-shaking\nexport { BasisTheory };\n\n// Type exports\nexport type {\n BasisTheorySDK,\n CardDisplayElement,\n CardDisplayOptions,\n CardElement,\n ChangeEventDetail,\n Element,\n ElementOptions,\n ElementType,\n ErrorEventDetail,\n EventListener,\n EventType,\n ProxyRequestOptions,\n ProxyResponse,\n ReadyEventDetail,\n SDKOptions,\n TokenizeInput,\n TokenizeResult,\n} from './types';\n","/**\n * FR-009: Build-Time Version Injection\n *\n * Version and build metadata injected at build time via Vite's define option.\n * These constants are replaced during bundling with actual values from package.json.\n */\n\n// These are injected at build time by Vite\ndeclare const __VERSION__: string;\ndeclare const __BUILD_DATE__: string;\n\n/**\n * SDK version from package.json\n * @example\n * ```typescript\n * import { version } from '@basis-theory/web-elements';\n * console.log(`Using SDK version ${version}`);\n * ```\n */\nexport const version = __VERSION__;\n\n/**\n * ISO 8601 timestamp when the SDK was built\n * @example\n * ```typescript\n * import { buildDate } from '@basis-theory/web-elements';\n * console.log(`Built on ${buildDate}`);\n * ```\n */\nexport const buildDate = __BUILD_DATE__;\n","/**\n * @basis-theory/web-elements\n * Secure, PCI-compliant SDK for creating payment input elements\n *\n * @example ESM (bundlers)\n * ```typescript\n * import BasisTheory from '@basis-theory/web-elements';\n *\n * const bt = BasisTheory('pk_test_YOUR_API_KEY');\n * const cardNumber = bt.createElement('cardNumber');\n * await cardNumber.mount('#card-number');\n * ```\n *\n * @example UMD (script tags)\n * ```html\n * <script src=\"https://cdn.basistheory.com/elements/index.umd.js\"></script>\n * <script>\n * const bt = window.BasisTheory('pk_test_YOUR_API_KEY');\n * const cardNumber = bt.createElement('cardNumber');\n * cardNumber.mount('#card-number');\n * </script>\n * ```\n */\n\n// Export only default for cleaner UMD usage\n// Named export still available for tree-shaking in ESM\nexport { default } from './BasisTheory';\n\n// FR-009: Export version and build metadata\nexport { version, buildDate } from './version';\n\n// Expose SDK on internal global for the loader to find after async script load\n// The loader calls window.__BasisTheorySDK__(apiKey, options, queuedCommands)\nimport BasisTheory from './BasisTheory';\nif (typeof window !== 'undefined') {\n (window as any).__BasisTheorySDK__ = BasisTheory;\n}\n\nexport type {\n BaseEventDetail,\n BasisTheorySDK,\n BlurEventDetail,\n CardDisplayChangeEventDetail,\n CardDisplayElement,\n CardDisplayEventType,\n CardDisplayOptions,\n CardElement,\n CardElementChangeEventDetail,\n CardElementOptions,\n CardNumberChangeEventDetail,\n ChangeEventDetail,\n CopyButtonElement,\n CopyButtonOptions,\n CopyEventDetail,\n Element,\n ElementInputArray,\n ElementInputObject,\n ElementLeaf,\n ElementOptions,\n ElementType,\n EncryptedToken,\n EncryptToken,\n ErrorCode,\n ErrorEventDetail,\n EventListener,\n EventType,\n FocusEventDetail,\n ProxyRequestOptions,\n ProxyResponse,\n NetworkChangedEventDetail,\n ReadyEventDetail,\n SDKOptions,\n Session,\n SubElementRef,\n TokenCreateRequest,\n TokenIntent,\n TokenIntentRequest,\n TokenizeInput,\n TokenizeResult,\n TokenUpdateRequest,\n ValidationError,\n} from './types';\n\n"],"names":["log","options","sharedValidateProxyOptions"],"mappings":"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"}