@z_06/relay-temp-mail 2.1.0 → 2.1.1

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.
package/dist/index.cjs CHANGED
@@ -390,6 +390,8 @@ var DuckDuckGoEmailProvider = class {
390
390
  var EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
391
391
  var MOZMAIL_SUFFIX_PATTERN = /@mozmail\.com$/i;
392
392
  var DUCK_SUFFIX_PATTERN = /@duck\.com$/i;
393
+ var DUCK_ALIAS_PATTERN = /([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)+@duck\.com)/gi;
394
+ var DUCK_SYSTEM_ADDRESSES = /* @__PURE__ */ new Set(["support@duck.com", "noreply@duck.com"]);
393
395
  var ENCODED_WORD_PATTERN = /=\?([^?]+)\?([BbQq])\?([^?]*)\?=/g;
394
396
  var EmailParser = class {
395
397
  parseEmail(raw) {
@@ -414,11 +416,20 @@ var EmailParser = class {
414
416
  const headers = this.parseHeaders(raw);
415
417
  const duckOriginalTo = headers.get("duck-original-to");
416
418
  if (duckOriginalTo) {
417
- const duckAddress2 = this.extractEmailAddress(duckOriginalTo);
418
- if (duckAddress2 && DUCK_SUFFIX_PATTERN.test(duckAddress2)) {
419
- return duckAddress2;
419
+ const duckAddress = this.extractEmailAddress(duckOriginalTo);
420
+ if (duckAddress && DUCK_SUFFIX_PATTERN.test(duckAddress)) {
421
+ return duckAddress;
420
422
  }
421
423
  }
424
+ const duckMatches = raw.match(DUCK_ALIAS_PATTERN);
425
+ if (duckMatches && duckMatches.length > 0) {
426
+ return duckMatches[0].toLowerCase();
427
+ }
428
+ const rawEmails = raw.match(EMAIL_PATTERN) ?? [];
429
+ const duckFallback = rawEmails.find(
430
+ (e) => DUCK_SUFFIX_PATTERN.test(e) && !DUCK_SYSTEM_ADDRESSES.has(e.toLowerCase())
431
+ );
432
+ if (duckFallback) return duckFallback.toLowerCase();
422
433
  const fromAddresses = this.extractHeaderEmails(headers.get("from"));
423
434
  const toAddresses = this.extractHeaderEmails(headers.get("to"));
424
435
  const allAddresses = [...fromAddresses, ...toAddresses];
@@ -426,10 +437,6 @@ var EmailParser = class {
426
437
  (address) => MOZMAIL_SUFFIX_PATTERN.test(address)
427
438
  );
428
439
  if (mozmailAddress) return mozmailAddress;
429
- const duckAddress = allAddresses.find(
430
- (address) => DUCK_SUFFIX_PATTERN.test(address)
431
- );
432
- if (duckAddress) return duckAddress;
433
440
  return toAddresses[0] ?? null;
434
441
  } catch {
435
442
  return null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/cf-api.ts","../src/http.ts","../src/duckduckgo-api.ts","../src/parser.ts","../src/relay-api.ts","../src/client.ts"],"sourcesContent":["export type {\n AliasProvider,\n MailProvider,\n TempMailConfig,\n FirefoxRelayConfig,\n DuckDuckGoEmailConfig,\n DuckDuckGoAliasStore,\n CFTempMailConfig,\n AliasProviderConfig,\n MailProviderConfig,\n RelayAlias,\n Email,\n ParsedEmail,\n ListAliasesOptions,\n GetEmailsOptions,\n CFMailsResponse,\n RelayAddressesResponse,\n CreateAliasResponse,\n RelayConfig,\n} from './types.js';\n\nexport {\n RelayTempMailError,\n NetworkError,\n AuthError,\n NotFoundError,\n ParseError,\n RateLimitError,\n} from './errors.js';\n\nexport { TempMailClient, RelayClient } from './client.js';\n\nexport { FirefoxRelayProvider, RelayAPIClient } from './relay-api.js';\n\nexport { CFTempMailProvider, CFEmailClient } from './cf-api.js';\n\nexport {\n DuckDuckGoEmailProvider,\n InMemoryDuckDuckGoAliasStore,\n} from './duckduckgo-api.js';\n","/**\n * Custom error classes for the relay-temp-mail package.\n *\n * These errors provide structured error information including error codes,\n * HTTP status codes, and response data for better error handling.\n */\n\n/**\n * Base error class for all relay-temp-mail errors.\n *\n * Extends the built-in Error class with additional context about the error,\n * including an error code for programmatic error handling and optional\n * response data from the API.\n */\nexport class RelayTempMailError extends Error {\n /**\n * Machine-readable error code for programmatic error handling.\n * Examples: 'NETWORK_ERROR', 'AUTH_ERROR', 'NOT_FOUND'\n */\n code: string;\n\n /**\n * HTTP status code associated with this error, if applicable.\n */\n statusCode?: number;\n\n /**\n * Raw response data from the API, if available.\n */\n response?: any;\n\n /**\n * Creates a new RelayTempMailError instance.\n *\n * @param message - Human-readable error message describing the error.\n * @param code - Machine-readable error code (e.g., 'UNKNOWN_ERROR').\n * @param statusCode - Optional HTTP status code associated with the error.\n * @param response - Optional raw response data from the API.\n */\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n response?: any\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.statusCode = statusCode;\n this.response = response;\n\n // Maintains proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error for network-related failures.\n *\n * Thrown when there is a problem establishing or maintaining a network\n * connection, such as DNS resolution failures, connection timeouts,\n * or network unreachability.\n */\nexport class NetworkError extends RelayTempMailError {\n code = 'NETWORK_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NETWORK_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for authentication and authorization failures.\n *\n * Thrown when API requests fail due to invalid or missing credentials\n * (401) or when the authenticated user lacks permission for the\n * requested operation (403).\n */\nexport class AuthError extends RelayTempMailError {\n code = 'AUTH_ERROR' as const;\n\n constructor(message: string, statusCode?: number, response?: any) {\n super(message, 'AUTH_ERROR', statusCode, response);\n }\n}\n\n/**\n * Error for resource not found errors.\n *\n * Thrown when the requested resource does not exist (404 response),\n * such as when trying to access a non-existent alias or email.\n */\nexport class NotFoundError extends RelayTempMailError {\n code = 'NOT_FOUND' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NOT_FOUND', 404, response);\n }\n}\n\n/**\n * Error for MIME message parsing failures.\n *\n * Thrown when there is an error parsing email MIME content,\n * such as malformed headers or invalid message structure.\n */\nexport class ParseError extends RelayTempMailError {\n code = 'PARSE_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'PARSE_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for rate limiting responses.\n *\n * Thrown when the API rate limit has been exceeded (429 response).\n * The client should wait and retry the request after the indicated\n * cooldown period.\n */\nexport class RateLimitError extends RelayTempMailError {\n code = 'RATE_LIMIT_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'RATE_LIMIT_ERROR', 429, response);\n }\n}\n","import type { MailProvider, Email } from './types.js';\nimport { AuthError, NetworkError, NotFoundError, RateLimitError, RelayTempMailError } from './errors.js';\n\ninterface CFRawEmail {\n id: number;\n message_id: string;\n source: string;\n address: string;\n raw: string;\n metadata: any | null;\n created_at: string;\n}\n\ninterface CFRawResponse {\n results: CFRawEmail[];\n count: number;\n}\n\nexport class CFTempMailProvider implements MailProvider {\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly httpClient: HttpClient;\n\n constructor(apiUrl: string, token: string, httpClient?: HttpClient) {\n this.apiUrl = apiUrl.replace(/\\/+$/, '');\n this.token = token;\n this.httpClient = httpClient ?? new DefaultHttpClient();\n }\n\n async getMails(limit: number = 20, offset: number = 0): Promise<Email[]> {\n const url = new URL(`${this.apiUrl}/api/mails`);\n url.searchParams.set('limit', String(limit));\n url.searchParams.set('offset', String(offset));\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.token}`,\n };\n\n try {\n const response = await this.httpClient.get(url.toString(), { headers });\n return this.mapCFResponse(response as CFRawResponse);\n } catch (error) {\n throw this.handleError(error);\n }\n }\n\n private mapCFResponse(response: CFRawResponse): Email[] {\n return response.results.map((item): Email => ({\n id: item.id,\n messageId: item.message_id,\n source: item.source,\n address: item.address,\n raw: item.raw,\n metadata: item.metadata,\n createdAt: item.created_at,\n }));\n }\n\n private handleError(error: unknown): RelayTempMailError {\n if (error instanceof RelayTempMailError) {\n const statusCode = error.statusCode;\n\n if (statusCode === 401 || statusCode === 403) {\n return new AuthError(error.message, statusCode, error.response);\n }\n if (statusCode === 404) {\n return new NotFoundError(error.message, error.response);\n }\n if (statusCode === 429) {\n return new RateLimitError(error.message, error.response);\n }\n\n return error;\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError(error.message);\n }\n\n if (error instanceof Error) {\n return new NetworkError(error.message);\n }\n\n return new RelayTempMailError(\n 'Unknown error occurred',\n 'UNKNOWN_ERROR',\n undefined,\n error\n );\n }\n}\n\n/** @deprecated Use CFTempMailProvider instead */\nexport const CFEmailClient = CFTempMailProvider;\n\nexport interface HttpClient {\n get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown>;\n}\n\nexport class DefaultHttpClient implements HttpClient {\n async get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown> {\n const response = await fetch(url, {\n method: 'GET',\n headers: options?.headers,\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw new RelayTempMailError(\n `HTTP ${response.status}: ${errorBody}`,\n 'HTTP_ERROR',\n response.status,\n errorBody\n );\n }\n\n return response.json();\n }\n}\n","/**\n * HTTP client utilities for the relay-temp-mail package.\n *\n * This module provides a configurable HTTP client with timeout support,\n * automatic retry logic, and proper error classification for API responses.\n */\n\nimport {\n RelayTempMailError,\n NetworkError,\n AuthError,\n NotFoundError,\n RateLimitError,\n} from './errors';\n\n/**\n * Options for individual HTTP requests.\n */\nexport interface RequestOptions {\n /** Custom headers to include in the request */\n headers?: Record<string, string>;\n\n /** Request body (will be JSON serialized) */\n body?: unknown;\n\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n\n /** Number of retries on failure (overrides client default) */\n retries?: number;\n}\n\n/**\n * HTTP client for making requests to the relay-temp-mail API.\n *\n * Provides a configurable base URL with timeout, retry, and automatic\n * JSON parsing capabilities.\n */\nexport class HttpClient {\n private baseUrl: string;\n private defaultTimeout: number;\n private defaultRetries: number;\n\n /**\n * Creates a new HttpClient instance.\n *\n * @param baseUrl - Base URL for all requests (e.g., 'https://api.example.com')\n * @param defaultTimeout - Default timeout in milliseconds (default: 30000)\n * @param defaultRetries - Default number of retries on failure (default: 0)\n */\n constructor(\n baseUrl: string,\n defaultTimeout: number = 30000,\n defaultRetries: number = 0\n ) {\n this.baseUrl = baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.defaultTimeout = defaultTimeout;\n this.defaultRetries = defaultRetries;\n }\n\n /**\n * Makes an HTTP request to the specified path.\n *\n * @param method - HTTP method (GET, POST, PUT, DELETE, etc.)\n * @param path - API path (will be appended to baseUrl)\n * @param options - Optional request configuration\n * @returns Promise resolving to the parsed JSON response\n */\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const timeout = options.timeout ?? this.defaultTimeout;\n const retries = options.retries ?? this.defaultRetries;\n\n let lastError: RelayTempMailError | Error | undefined;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const response = await this.executeRequest(method, path, options, timeout);\n return await this.handleResponse<T>(response);\n } catch (error) {\n lastError = error as Error;\n\n // Check if we should retry\n if (attempt < retries && this.shouldRetry(error)) {\n const delay = 1000 * Math.pow(2, attempt);\n await this.sleep(delay);\n continue;\n }\n\n // Don't retry, throw the classified error\n if (error instanceof RelayTempMailError) {\n throw error;\n }\n\n // Classify the error if not already classified\n throw this.classifyError(error);\n }\n }\n\n // This should never be reached, but just in case\n throw lastError || new NetworkError('Request failed');\n }\n\n /**\n * Executes the actual HTTP request with timeout support.\n */\n private async executeRequest(\n method: string,\n path: string,\n options: RequestOptions,\n timeout: number\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n signal: controller.signal,\n };\n\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n const response = await fetch(url, fetchOptions);\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Handles the HTTP response, parsing JSON and checking for errors.\n */\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n throw this.classifyError(new Error(`HTTP ${response.status}`), response);\n }\n\n const text = await response.text();\n\n // Handle empty responses\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n }\n\n /**\n * Classifies an error based on the error type and HTTP response.\n */\n private classifyError(error: unknown, response?: Response): RelayTempMailError {\n // Network errors (fetch failed)\n if (error instanceof Error && error.name === 'AbortError') {\n return new NetworkError('Request timed out');\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError('Network request failed');\n }\n\n if (error instanceof Error && error.message.includes('Failed to fetch')) {\n return new NetworkError('Network request failed');\n }\n\n // HTTP status-based classification\n if (response) {\n const status = response.status;\n\n if (status === 401 || status === 403) {\n return new AuthError(\n `Authentication failed: ${response.statusText}`,\n status\n );\n }\n\n if (status === 404) {\n return new NotFoundError(`Resource not found: ${response.statusText}`);\n }\n\n if (status === 429) {\n return new RateLimitError(\n `Rate limit exceeded: ${response.statusText}`\n );\n }\n\n if (status >= 500) {\n return new NetworkError(\n `Server error: ${response.statusText}`,\n status\n );\n }\n }\n\n // Default error\n if (error instanceof Error) {\n return new RelayTempMailError(\n error.message,\n 'REQUEST_ERROR',\n response?.status\n );\n }\n\n return new RelayTempMailError('Unknown error occurred', 'UNKNOWN_ERROR');\n }\n\n /**\n * Determines if a request should be retried based on the error.\n */\n private shouldRetry(error: unknown): boolean {\n if (error instanceof NetworkError) {\n return true;\n }\n\n if (error instanceof RelayTempMailError && error.statusCode) {\n return error.statusCode >= 500;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n return true;\n }\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Sleep for a specified duration.\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient } from './http';\nimport { RelayTempMailError } from './errors';\nimport type { AliasProvider, RelayAlias, DuckDuckGoAliasStore } from './types';\n\ninterface DuckDuckGoCreateAddressResponse {\n address: string;\n}\n\nexport class InMemoryDuckDuckGoAliasStore implements DuckDuckGoAliasStore {\n private aliases: RelayAlias[] = [];\n\n getAll(): RelayAlias[] {\n return [...this.aliases];\n }\n\n add(alias: RelayAlias): void {\n this.aliases.push(alias);\n }\n\n remove(id: number): void {\n this.aliases = this.aliases.filter((a) => a.id !== id);\n }\n}\n\nexport class DuckDuckGoEmailProvider implements AliasProvider {\n private jwtToken: string;\n private httpClient: HttpClient;\n private store: DuckDuckGoAliasStore;\n private nextId: number;\n\n constructor(\n jwtToken: string,\n store?: DuckDuckGoAliasStore,\n httpClient?: HttpClient\n ) {\n this.jwtToken = jwtToken;\n this.store = store ?? new InMemoryDuckDuckGoAliasStore();\n this.httpClient =\n httpClient ?? new HttpClient('https://quack.duckduckgo.com');\n this.nextId = 1;\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.store.getAll();\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response =\n await this.httpClient.request<DuckDuckGoCreateAddressResponse>(\n 'POST',\n '/api/email/addresses',\n {\n headers: {\n Authorization: `Bearer ${this.jwtToken}`,\n },\n }\n );\n\n const fullAddress = `${response.address}@duck.com`;\n\n const existing = await this.store.getAll();\n if (existing.some((a) => a.fullAddress === fullAddress)) {\n throw new RelayTempMailError(\n `DuckDuckGo returned a duplicate alias: ${fullAddress}`,\n 'DUPLICATE_ALIAS',\n 201\n );\n }\n\n const alias: RelayAlias = {\n id: this.nextId++,\n address: response.address,\n fullAddress,\n enabled: true,\n createdAt: new Date().toISOString(),\n domain: 3,\n maskType: 'random',\n };\n\n await this.store.add(alias);\n return alias;\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.store.remove(id);\n }\n}\n","/**\n * MIME email parser for extracting Firefox Relay alias information.\n */\nimport type { ParsedEmail } from './types.js';\n\nconst EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g;\nconst MOZMAIL_SUFFIX_PATTERN = /@mozmail\\.com$/i;\nconst DUCK_SUFFIX_PATTERN = /@duck\\.com$/i;\nconst ENCODED_WORD_PATTERN = /=\\?([^?]+)\\?([BbQq])\\?([^?]*)\\?=/g;\n\n/**\n * EmailParser class for parsing MIME email content.\n */\nexport class EmailParser {\n parseEmail(raw: string): ParsedEmail {\n const headers = this.parseHeaders(raw);\n const toHeader = headers.get('to') || '';\n const fromHeader = headers.get('from') || '';\n const messageIdHeader = headers.get('message-id') || '';\n const relayAlias = this.extractRelayAlias(raw);\n \n return {\n id: 0,\n messageId: this.extractMessageId(messageIdHeader),\n source: this.extractEmailAddress(fromHeader),\n address: this.extractEmailAddress(toHeader),\n raw,\n metadata: null,\n createdAt: new Date().toISOString(),\n relayAlias: relayAlias || undefined,\n };\n }\n\n extractRelayAlias(raw: string): string | null {\n try {\n const headers = this.parseHeaders(raw);\n\n // DuckDuckGo Email Protection adds a Duck-Original-To header\n // containing the @duck.com alias the email was forwarded to\n const duckOriginalTo = headers.get('duck-original-to');\n if (duckOriginalTo) {\n const duckAddress = this.extractEmailAddress(duckOriginalTo);\n if (duckAddress && DUCK_SUFFIX_PATTERN.test(duckAddress)) {\n return duckAddress;\n }\n }\n\n const fromAddresses = this.extractHeaderEmails(headers.get('from'));\n const toAddresses = this.extractHeaderEmails(headers.get('to'));\n const allAddresses = [...fromAddresses, ...toAddresses];\n\n const mozmailAddress = allAddresses.find((address) =>\n MOZMAIL_SUFFIX_PATTERN.test(address)\n );\n if (mozmailAddress) return mozmailAddress;\n\n const duckAddress = allAddresses.find((address) =>\n DUCK_SUFFIX_PATTERN.test(address)\n );\n if (duckAddress) return duckAddress;\n\n return toAddresses[0] ?? null;\n } catch {\n return null;\n }\n }\n\n private parseHeaders(raw: string): Map<string, string> {\n const headers = new Map<string, string>();\n const headerEnd = raw.indexOf('\\r\\n\\r\\n');\n const headerSection = headerEnd === -1 ? raw : raw.substring(0, headerEnd);\n const lines = headerSection.split(/\\r?\\n/);\n let currentHeader: string | null = null;\n let currentValue = '';\n \n for (const line of lines) {\n if (/^\\s/.test(line)) {\n if (currentHeader) currentValue += ' ' + line.trim();\n } else {\n if (currentHeader) headers.set(currentHeader, currentValue);\n const colonIndex = line.indexOf(':');\n if (colonIndex > 0) {\n currentHeader = line.substring(0, colonIndex).toLowerCase().trim();\n currentValue = line.substring(colonIndex + 1).trim();\n } else {\n currentHeader = null;\n currentValue = '';\n }\n }\n }\n if (currentHeader) headers.set(currentHeader, currentValue);\n return headers;\n }\n\n private decodeHeader(value: string): string {\n return value.replace(ENCODED_WORD_PATTERN, (_, charset, encoding, encoded) => {\n try {\n if (encoding.toUpperCase() === 'Q') {\n return this.decodeQuotedPrintable(encoded);\n } else if (encoding.toUpperCase() === 'B') {\n return this.decodeBase64(encoded);\n }\n return encoded;\n } catch {\n return encoded;\n }\n });\n }\n\n private decodeQuotedPrintable(encoded: string): string {\n // RFC 2047: underscores represent spaces in encoded-word\n let decoded = encoded.replace(/_/g, ' ');\n decoded = decoded.replace(/=([0-9A-Fa-f]{2})/g, (_, hex) => \n String.fromCharCode(parseInt(hex, 16))\n );\n return decoded;\n }\n\n private decodeBase64(encoded: string): string {\n return Buffer.from(encoded, 'base64').toString('utf-8');\n }\n\n private extractEmailAddress(headerValue: string): string {\n if (!headerValue) return '';\n const decoded = this.decodeHeader(headerValue);\n const bracketMatch = decoded.match(/<([^>]+)>/);\n if (bracketMatch) return bracketMatch[1].trim().toLowerCase();\n const emailMatch = decoded.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/);\n return emailMatch ? emailMatch[0].toLowerCase() : decoded.trim().toLowerCase();\n }\n\n private extractHeaderEmails(headerValue?: string): string[] {\n if (!headerValue) return [];\n const decoded = this.decodeHeader(headerValue);\n const matches = decoded.match(EMAIL_PATTERN);\n return matches ? matches.map((match) => match.toLowerCase()) : [];\n }\n\n private extractMessageId(headerValue: string): string {\n if (!headerValue) return `<generated-${Date.now()}@relay-temp-mail>`;\n const cleaned = headerValue.replace(/[<>]/g, '').trim();\n return `<${cleaned}>`;\n }\n}\n","import { HttpClient } from './http';\nimport type { AliasProvider, RelayAlias } from './types';\n\ninterface RawAliasResponse {\n id: number;\n address: string;\n full_address: string;\n enabled: boolean;\n created_at: string;\n domain: number;\n mask_type: string;\n description?: string;\n num_forwarded?: number;\n num_blocked?: number;\n last_modified_at?: string;\n last_used_at?: string | null;\n num_level_one_trackers_blocked?: number;\n num_replied?: number;\n num_spam?: number;\n block_list_emails?: boolean;\n generated_for?: string;\n used_on?: string | null;\n}\n\nexport class FirefoxRelayProvider implements AliasProvider {\n private csrfToken: string;\n private sessionId: string;\n private httpClient: HttpClient;\n\n constructor(\n csrfToken: string,\n sessionId: string,\n httpClient?: HttpClient\n ) {\n this.csrfToken = csrfToken;\n this.sessionId = sessionId;\n this.httpClient = httpClient ?? new HttpClient('https://relay.firefox.com');\n }\n\n private getAuthHeaders(): Record<string, string> {\n return {\n 'Origin': 'https://relay.firefox.com',\n 'Referer': 'https://relay.firefox.com/accounts/profile/?',\n 'Accept': 'application/json',\n 'X-CSRFToken': this.csrfToken,\n 'Cookie': `sessionid=${this.sessionId}; csrftoken=${this.csrfToken}`,\n };\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n const response = await this.httpClient.request<RawAliasResponse[]>(\n 'GET',\n '/api/v1/relayaddresses/',\n { headers: this.getAuthHeaders() }\n );\n\n return response.map((item) => this.mapAliasResponse(item));\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response = await this.httpClient.request<RawAliasResponse>(\n 'POST',\n '/api/v1/relayaddresses/',\n {\n headers: this.getAuthHeaders(),\n body: { enabled: true },\n }\n );\n\n return this.mapAliasResponse(response);\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.httpClient.request<void>(\n 'DELETE',\n `/api/v1/relayaddresses/${id}/`,\n { headers: this.getAuthHeaders() }\n );\n }\n\n private mapAliasResponse(data: RawAliasResponse): RelayAlias {\n return {\n id: data.id,\n address: data.address,\n fullAddress: data.full_address,\n enabled: data.enabled,\n createdAt: data.created_at,\n domain: data.domain,\n maskType: data.mask_type,\n description: data.description,\n numForwarded: data.num_forwarded,\n numBlocked: data.num_blocked,\n lastModifiedAt: data.last_modified_at,\n lastUsedAt: data.last_used_at,\n numLevelOneTrackersBlocked: data.num_level_one_trackers_blocked,\n numReplied: data.num_replied,\n numSpam: data.num_spam,\n blockListEmails: data.block_list_emails,\n generatedFor: data.generated_for,\n usedOn: data.used_on,\n };\n }\n}\n\n/** @deprecated Use FirefoxRelayProvider instead */\nexport const RelayAPIClient = FirefoxRelayProvider;\n","import { CFTempMailProvider, DefaultHttpClient } from './cf-api.js';\nimport { DuckDuckGoEmailProvider } from './duckduckgo-api.js';\nimport { EmailParser } from './parser.js';\nimport { FirefoxRelayProvider } from './relay-api.js';\nimport { HttpClient } from './http.js';\nimport type {\n TempMailConfig,\n RelayConfig,\n AliasProvider,\n MailProvider,\n RelayAlias,\n ParsedEmail,\n GetEmailsOptions,\n} from './types.js';\n\nfunction createAliasProvider(config: TempMailConfig, httpClient: HttpClient): AliasProvider {\n const aliasConfig = config.aliasProvider;\n switch (aliasConfig.type) {\n case 'firefox-relay':\n return new FirefoxRelayProvider(\n aliasConfig.csrfToken,\n aliasConfig.sessionId,\n httpClient\n );\n case 'duckduckgo-email':\n return new DuckDuckGoEmailProvider(\n aliasConfig.jwtToken,\n aliasConfig.store\n );\n }\n}\n\nfunction createMailProvider(config: TempMailConfig): MailProvider {\n const mailConfig = config.mailProvider;\n switch (mailConfig.type) {\n case 'cf-temp-mail':\n return new CFTempMailProvider(\n mailConfig.apiUrl,\n mailConfig.token\n );\n }\n}\n\nexport class TempMailClient {\n private readonly aliasProvider: AliasProvider;\n private readonly mailProvider: MailProvider;\n private readonly parser: EmailParser;\n\n constructor(config: TempMailConfig) {\n const timeout = config.timeout ?? 30000;\n const httpClient = new HttpClient('https://relay.firefox.com', timeout);\n this.aliasProvider = createAliasProvider(config, httpClient);\n this.mailProvider = createMailProvider(config);\n this.parser = new EmailParser();\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.aliasProvider.listAliases();\n }\n\n async createAlias(): Promise<RelayAlias> {\n return this.aliasProvider.createAlias();\n }\n\n async deleteAlias(id: number): Promise<void> {\n return this.aliasProvider.deleteAlias(id);\n }\n\n async getEmails(\n aliasAddress?: string,\n options?: GetEmailsOptions\n ): Promise<ParsedEmail[]> {\n const limit = options?.limit ?? 20;\n const offset = options?.offset ?? 0;\n\n const emails = await this.mailProvider.getMails(limit, offset);\n\n const parsedEmails: ParsedEmail[] = emails.map((email) => {\n const parsed = this.parser.parseEmail(email.raw);\n return {\n ...parsed,\n id: email.id,\n messageId: email.messageId,\n source: email.source,\n address: email.address,\n createdAt: email.createdAt,\n metadata: email.metadata,\n };\n });\n\n if (aliasAddress) {\n const normalizedAlias = aliasAddress.toLowerCase();\n return parsedEmails.filter(\n (email) =>\n email.relayAlias?.toLowerCase() === normalizedAlias ||\n email.address.toLowerCase() === normalizedAlias\n );\n }\n\n return parsedEmails;\n }\n}\n\n/** @deprecated Use TempMailClient instead */\nexport const RelayClient = TempMailClient;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACcO,IAAM,qBAAN,cAAiC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyB5C,YACE,SACA,MACA,YACA,UACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO,KAAK,YAAY;AAC7B,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,WAAW;AAGhB,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,IAChD;AAAA,EACF;AACF;AASO,IAAM,eAAN,cAA2B,mBAAmB;AAAA,EAGnD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,iBAAiB,QAAW,QAAQ;AAHrD,gBAAO;AAAA,EAIP;AACF;AASO,IAAM,YAAN,cAAwB,mBAAmB;AAAA,EAGhD,YAAY,SAAiB,YAAqB,UAAgB;AAChE,UAAM,SAAS,cAAc,YAAY,QAAQ;AAHnD,gBAAO;AAAA,EAIP;AACF;AAQO,IAAM,gBAAN,cAA4B,mBAAmB;AAAA,EAGpD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,aAAa,KAAK,QAAQ;AAH3C,gBAAO;AAAA,EAIP;AACF;AAQO,IAAM,aAAN,cAAyB,mBAAmB;AAAA,EAGjD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,eAAe,QAAW,QAAQ;AAHnD,gBAAO;AAAA,EAIP;AACF;AASO,IAAM,iBAAN,cAA6B,mBAAmB;AAAA,EAGrD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,oBAAoB,KAAK,QAAQ;AAHlD,gBAAO;AAAA,EAIP;AACF;;;AC/GO,IAAM,qBAAN,MAAiD;AAAA,EAKtD,YAAY,QAAgB,OAAe,YAAyB;AAClE,SAAK,SAAS,OAAO,QAAQ,QAAQ,EAAE;AACvC,SAAK,QAAQ;AACb,SAAK,aAAa,cAAc,IAAI,kBAAkB;AAAA,EACxD;AAAA,EAEA,MAAM,SAAS,QAAgB,IAAI,SAAiB,GAAqB;AACvE,UAAM,MAAM,IAAI,IAAI,GAAG,KAAK,MAAM,YAAY;AAC9C,QAAI,aAAa,IAAI,SAAS,OAAO,KAAK,CAAC;AAC3C,QAAI,aAAa,IAAI,UAAU,OAAO,MAAM,CAAC;AAE7C,UAAM,UAAkC;AAAA,MACtC,iBAAiB,UAAU,KAAK,KAAK;AAAA,IACvC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW,IAAI,IAAI,SAAS,GAAG,EAAE,QAAQ,CAAC;AACtE,aAAO,KAAK,cAAc,QAAyB;AAAA,IACrD,SAAS,OAAO;AACd,YAAM,KAAK,YAAY,KAAK;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,cAAc,UAAkC;AACtD,WAAO,SAAS,QAAQ,IAAI,CAAC,UAAiB;AAAA,MAC5C,IAAI,KAAK;AAAA,MACT,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,KAAK,KAAK;AAAA,MACV,UAAU,KAAK;AAAA,MACf,WAAW,KAAK;AAAA,IAClB,EAAE;AAAA,EACJ;AAAA,EAEQ,YAAY,OAAoC;AACtD,QAAI,iBAAiB,oBAAoB;AACvC,YAAM,aAAa,MAAM;AAEzB,UAAI,eAAe,OAAO,eAAe,KAAK;AAC5C,eAAO,IAAI,UAAU,MAAM,SAAS,YAAY,MAAM,QAAQ;AAAA,MAChE;AACA,UAAI,eAAe,KAAK;AACtB,eAAO,IAAI,cAAc,MAAM,SAAS,MAAM,QAAQ;AAAA,MACxD;AACA,UAAI,eAAe,KAAK;AACtB,eAAO,IAAI,eAAe,MAAM,SAAS,MAAM,QAAQ;AAAA,MACzD;AAEA,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,aAAa,MAAM,QAAQ,SAAS,OAAO,GAAG;AACjE,aAAO,IAAI,aAAa,MAAM,OAAO;AAAA,IACvC;AAEA,QAAI,iBAAiB,OAAO;AAC1B,aAAO,IAAI,aAAa,MAAM,OAAO;AAAA,IACvC;AAEA,WAAO,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,gBAAgB;AAMtB,IAAM,oBAAN,MAA8C;AAAA,EACnD,MAAM,IAAI,KAAa,SAAkE;AACvF,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,SAAS;AAAA,IACpB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,YAAM,IAAI;AAAA,QACR,QAAQ,SAAS,MAAM,KAAK,SAAS;AAAA,QACrC;AAAA,QACA,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AACF;;;AChFO,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYtB,YACE,SACA,iBAAyB,KACzB,iBAAyB,GACzB;AACA,SAAK,UAAU,QAAQ,QAAQ,OAAO,EAAE;AACxC,SAAK,iBAAiB;AACtB,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QACJ,QACA,MACA,UAA0B,CAAC,GACf;AACZ,UAAM,UAAU,QAAQ,WAAW,KAAK;AACxC,UAAM,UAAU,QAAQ,WAAW,KAAK;AAExC,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,SAAS,WAAW;AACnD,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,eAAe,QAAQ,MAAM,SAAS,OAAO;AACzE,eAAO,MAAM,KAAK,eAAkB,QAAQ;AAAA,MAC9C,SAAS,OAAO;AACd,oBAAY;AAGZ,YAAI,UAAU,WAAW,KAAK,YAAY,KAAK,GAAG;AAChD,gBAAM,QAAQ,MAAO,KAAK,IAAI,GAAG,OAAO;AACxC,gBAAM,KAAK,MAAM,KAAK;AACtB;AAAA,QACF;AAGA,YAAI,iBAAiB,oBAAoB;AACvC,gBAAM;AAAA,QACR;AAGA,cAAM,KAAK,cAAc,KAAK;AAAA,MAChC;AAAA,IACF;AAGA,UAAM,aAAa,IAAI,aAAa,gBAAgB;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,QACA,MACA,SACA,SACmB;AACnB,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAElC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,OAAO;AAE9D,QAAI;AACF,YAAM,eAA4B;AAAA,QAChC;AAAA,QACA,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,GAAG,QAAQ;AAAA,QACb;AAAA,QACA,QAAQ,WAAW;AAAA,MACrB;AAEA,UAAI,QAAQ,SAAS,QAAW;AAC9B,qBAAa,OAAO,KAAK,UAAU,QAAQ,IAAI;AAAA,MACjD;AAEA,YAAM,WAAW,MAAM,MAAM,KAAK,YAAY;AAC9C,aAAO;AAAA,IACT,UAAE;AACA,mBAAa,SAAS;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAkB,UAAgC;AAC9D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,KAAK,cAAc,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE,GAAG,QAAQ;AAAA,IACzE;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,QAAI,CAAC,MAAM;AACT,aAAO,CAAC;AAAA,IACV;AAEA,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,OAAgB,UAAyC;AAE7E,QAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,aAAO,IAAI,aAAa,mBAAmB;AAAA,IAC7C;AAEA,QAAI,iBAAiB,aAAa,MAAM,QAAQ,SAAS,OAAO,GAAG;AACjE,aAAO,IAAI,aAAa,wBAAwB;AAAA,IAClD;AAEA,QAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,iBAAiB,GAAG;AACvE,aAAO,IAAI,aAAa,wBAAwB;AAAA,IAClD;AAGA,QAAI,UAAU;AACZ,YAAM,SAAS,SAAS;AAExB,UAAI,WAAW,OAAO,WAAW,KAAK;AACpC,eAAO,IAAI;AAAA,UACT,0BAA0B,SAAS,UAAU;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAEA,UAAI,WAAW,KAAK;AAClB,eAAO,IAAI,cAAc,uBAAuB,SAAS,UAAU,EAAE;AAAA,MACvE;AAEA,UAAI,WAAW,KAAK;AAClB,eAAO,IAAI;AAAA,UACT,wBAAwB,SAAS,UAAU;AAAA,QAC7C;AAAA,MACF;AAEA,UAAI,UAAU,KAAK;AACjB,eAAO,IAAI;AAAA,UACT,iBAAiB,SAAS,UAAU;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,iBAAiB,OAAO;AAC1B,aAAO,IAAI;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,IAAI,mBAAmB,0BAA0B,eAAe;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,OAAyB;AAC3C,QAAI,iBAAiB,cAAc;AACjC,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,sBAAsB,MAAM,YAAY;AAC3D,aAAO,MAAM,cAAc;AAAA,IAC7B;AAEA,QAAI,iBAAiB,OAAO;AAC1B,UAAI,MAAM,SAAS,cAAc;AAC/B,eAAO;AAAA,MACT;AACA,UAAI,iBAAiB,aAAa,MAAM,QAAQ,SAAS,OAAO,GAAG;AACjE,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AACF;;;AC/OO,IAAM,+BAAN,MAAmE;AAAA,EAAnE;AACL,SAAQ,UAAwB,CAAC;AAAA;AAAA,EAEjC,SAAuB;AACrB,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB;AAAA,EAEA,IAAI,OAAyB;AAC3B,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,UAAU,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,EACvD;AACF;AAEO,IAAM,0BAAN,MAAuD;AAAA,EAM5D,YACE,UACA,OACA,YACA;AACA,SAAK,WAAW;AAChB,SAAK,QAAQ,SAAS,IAAI,6BAA6B;AACvD,SAAK,aACH,cAAc,IAAI,WAAW,8BAA8B;AAC7D,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,cAAqC;AACzC,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B;AAAA,EAEA,MAAM,cAAmC;AACvC,UAAM,WACJ,MAAM,KAAK,WAAW;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS;AAAA,UACP,eAAe,UAAU,KAAK,QAAQ;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAEF,UAAM,cAAc,GAAG,SAAS,OAAO;AAEvC,UAAM,WAAW,MAAM,KAAK,MAAM,OAAO;AACzC,QAAI,SAAS,KAAK,CAAC,MAAM,EAAE,gBAAgB,WAAW,GAAG;AACvD,YAAM,IAAI;AAAA,QACR,0CAA0C,WAAW;AAAA,QACrD;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAoB;AAAA,MACxB,IAAI,KAAK;AAAA,MACT,SAAS,SAAS;AAAA,MAClB;AAAA,MACA,SAAS;AAAA,MACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAEA,UAAM,KAAK,MAAM,IAAI,KAAK;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,IAA2B;AAC3C,UAAM,KAAK,MAAM,OAAO,EAAE;AAAA,EAC5B;AACF;;;ACjFA,IAAM,gBAAgB;AACtB,IAAM,yBAAyB;AAC/B,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAKtB,IAAM,cAAN,MAAkB;AAAA,EACvB,WAAW,KAA0B;AACnC,UAAM,UAAU,KAAK,aAAa,GAAG;AACrC,UAAM,WAAW,QAAQ,IAAI,IAAI,KAAK;AACtC,UAAM,aAAa,QAAQ,IAAI,MAAM,KAAK;AAC1C,UAAM,kBAAkB,QAAQ,IAAI,YAAY,KAAK;AACrD,UAAM,aAAa,KAAK,kBAAkB,GAAG;AAE7C,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,WAAW,KAAK,iBAAiB,eAAe;AAAA,MAChD,QAAQ,KAAK,oBAAoB,UAAU;AAAA,MAC3C,SAAS,KAAK,oBAAoB,QAAQ;AAAA,MAC1C;AAAA,MACA,UAAU;AAAA,MACV,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,YAAY,cAAc;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,kBAAkB,KAA4B;AAC5C,QAAI;AACF,YAAM,UAAU,KAAK,aAAa,GAAG;AAIrC,YAAM,iBAAiB,QAAQ,IAAI,kBAAkB;AACrD,UAAI,gBAAgB;AAClB,cAAMA,eAAc,KAAK,oBAAoB,cAAc;AAC3D,YAAIA,gBAAe,oBAAoB,KAAKA,YAAW,GAAG;AACxD,iBAAOA;AAAA,QACT;AAAA,MACF;AAEA,YAAM,gBAAgB,KAAK,oBAAoB,QAAQ,IAAI,MAAM,CAAC;AAClE,YAAM,cAAc,KAAK,oBAAoB,QAAQ,IAAI,IAAI,CAAC;AAC9D,YAAM,eAAe,CAAC,GAAG,eAAe,GAAG,WAAW;AAEtD,YAAM,iBAAiB,aAAa;AAAA,QAAK,CAAC,YACxC,uBAAuB,KAAK,OAAO;AAAA,MACrC;AACA,UAAI,eAAgB,QAAO;AAE3B,YAAM,cAAc,aAAa;AAAA,QAAK,CAAC,YACrC,oBAAoB,KAAK,OAAO;AAAA,MAClC;AACA,UAAI,YAAa,QAAO;AAExB,aAAO,YAAY,CAAC,KAAK;AAAA,IAC3B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,aAAa,KAAkC;AACrD,UAAM,UAAU,oBAAI,IAAoB;AACxC,UAAM,YAAY,IAAI,QAAQ,UAAU;AACxC,UAAM,gBAAgB,cAAc,KAAK,MAAM,IAAI,UAAU,GAAG,SAAS;AACzE,UAAM,QAAQ,cAAc,MAAM,OAAO;AACzC,QAAI,gBAA+B;AACnC,QAAI,eAAe;AAEnB,eAAW,QAAQ,OAAO;AACxB,UAAI,MAAM,KAAK,IAAI,GAAG;AACpB,YAAI,cAAe,iBAAgB,MAAM,KAAK,KAAK;AAAA,MACrD,OAAO;AACL,YAAI,cAAe,SAAQ,IAAI,eAAe,YAAY;AAC1D,cAAM,aAAa,KAAK,QAAQ,GAAG;AACnC,YAAI,aAAa,GAAG;AAClB,0BAAgB,KAAK,UAAU,GAAG,UAAU,EAAE,YAAY,EAAE,KAAK;AACjE,yBAAe,KAAK,UAAU,aAAa,CAAC,EAAE,KAAK;AAAA,QACrD,OAAO;AACL,0BAAgB;AAChB,yBAAe;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,QAAI,cAAe,SAAQ,IAAI,eAAe,YAAY;AAC1D,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,OAAuB;AAC1C,WAAO,MAAM,QAAQ,sBAAsB,CAAC,GAAG,SAAS,UAAU,YAAY;AAC5E,UAAI;AACF,YAAI,SAAS,YAAY,MAAM,KAAK;AAClC,iBAAO,KAAK,sBAAsB,OAAO;AAAA,QAC3C,WAAW,SAAS,YAAY,MAAM,KAAK;AACzC,iBAAO,KAAK,aAAa,OAAO;AAAA,QAClC;AACA,eAAO;AAAA,MACT,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,sBAAsB,SAAyB;AAErD,QAAI,UAAU,QAAQ,QAAQ,MAAM,GAAG;AACvC,cAAU,QAAQ;AAAA,MAAQ;AAAA,MAAsB,CAAC,GAAG,QAClD,OAAO,aAAa,SAAS,KAAK,EAAE,CAAC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,SAAyB;AAC5C,WAAO,OAAO,KAAK,SAAS,QAAQ,EAAE,SAAS,OAAO;AAAA,EACxD;AAAA,EAEQ,oBAAoB,aAA6B;AACvD,QAAI,CAAC,YAAa,QAAO;AACzB,UAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,UAAM,eAAe,QAAQ,MAAM,WAAW;AAC9C,QAAI,aAAc,QAAO,aAAa,CAAC,EAAE,KAAK,EAAE,YAAY;AAC5D,UAAM,aAAa,QAAQ,MAAM,gDAAgD;AACjF,WAAO,aAAa,WAAW,CAAC,EAAE,YAAY,IAAI,QAAQ,KAAK,EAAE,YAAY;AAAA,EAC/E;AAAA,EAEQ,oBAAoB,aAAgC;AAC1D,QAAI,CAAC,YAAa,QAAO,CAAC;AAC1B,UAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,UAAM,UAAU,QAAQ,MAAM,aAAa;AAC3C,WAAO,UAAU,QAAQ,IAAI,CAAC,UAAU,MAAM,YAAY,CAAC,IAAI,CAAC;AAAA,EAClE;AAAA,EAEQ,iBAAiB,aAA6B;AACpD,QAAI,CAAC,YAAa,QAAO,cAAc,KAAK,IAAI,CAAC;AACjD,UAAM,UAAU,YAAY,QAAQ,SAAS,EAAE,EAAE,KAAK;AACtD,WAAO,IAAI,OAAO;AAAA,EACpB;AACF;;;ACvHO,IAAM,uBAAN,MAAoD;AAAA,EAKzD,YACE,WACA,WACA,YACA;AACA,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,aAAa,cAAc,IAAI,WAAW,2BAA2B;AAAA,EAC5E;AAAA,EAEQ,iBAAyC;AAC/C,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,MACV,eAAe,KAAK;AAAA,MACpB,UAAU,aAAa,KAAK,SAAS,eAAe,KAAK,SAAS;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAM,cAAqC;AACzC,UAAM,WAAW,MAAM,KAAK,WAAW;AAAA,MACrC;AAAA,MACA;AAAA,MACA,EAAE,SAAS,KAAK,eAAe,EAAE;AAAA,IACnC;AAEA,WAAO,SAAS,IAAI,CAAC,SAAS,KAAK,iBAAiB,IAAI,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,cAAmC;AACvC,UAAM,WAAW,MAAM,KAAK,WAAW;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS,KAAK,eAAe;AAAA,QAC7B,MAAM,EAAE,SAAS,KAAK;AAAA,MACxB;AAAA,IACF;AAEA,WAAO,KAAK,iBAAiB,QAAQ;AAAA,EACvC;AAAA,EAEA,MAAM,YAAY,IAA2B;AAC3C,UAAM,KAAK,WAAW;AAAA,MACpB;AAAA,MACA,0BAA0B,EAAE;AAAA,MAC5B,EAAE,SAAS,KAAK,eAAe,EAAE;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,iBAAiB,MAAoC;AAC3D,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,aAAa,KAAK;AAAA,MAClB,cAAc,KAAK;AAAA,MACnB,YAAY,KAAK;AAAA,MACjB,gBAAgB,KAAK;AAAA,MACrB,YAAY,KAAK;AAAA,MACjB,4BAA4B,KAAK;AAAA,MACjC,YAAY,KAAK;AAAA,MACjB,SAAS,KAAK;AAAA,MACd,iBAAiB,KAAK;AAAA,MACtB,cAAc,KAAK;AAAA,MACnB,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AACF;AAGO,IAAM,iBAAiB;;;AC1F9B,SAAS,oBAAoB,QAAwB,YAAuC;AAC1F,QAAM,cAAc,OAAO;AAC3B,UAAQ,YAAY,MAAM;AAAA,IACxB,KAAK;AACH,aAAO,IAAI;AAAA,QACT,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO,IAAI;AAAA,QACT,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AAAA,EACJ;AACF;AAEA,SAAS,mBAAmB,QAAsC;AAChE,QAAM,aAAa,OAAO;AAC1B,UAAQ,WAAW,MAAM;AAAA,IACvB,KAAK;AACH,aAAO,IAAI;AAAA,QACT,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,EACJ;AACF;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAK1B,YAAY,QAAwB;AAClC,UAAM,UAAU,OAAO,WAAW;AAClC,UAAM,aAAa,IAAI,WAAW,6BAA6B,OAAO;AACtE,SAAK,gBAAgB,oBAAoB,QAAQ,UAAU;AAC3D,SAAK,eAAe,mBAAmB,MAAM;AAC7C,SAAK,SAAS,IAAI,YAAY;AAAA,EAChC;AAAA,EAEA,MAAM,cAAqC;AACzC,WAAO,KAAK,cAAc,YAAY;AAAA,EACxC;AAAA,EAEA,MAAM,cAAmC;AACvC,WAAO,KAAK,cAAc,YAAY;AAAA,EACxC;AAAA,EAEA,MAAM,YAAY,IAA2B;AAC3C,WAAO,KAAK,cAAc,YAAY,EAAE;AAAA,EAC1C;AAAA,EAEA,MAAM,UACJ,cACA,SACwB;AACxB,UAAM,QAAQ,SAAS,SAAS;AAChC,UAAM,SAAS,SAAS,UAAU;AAElC,UAAM,SAAS,MAAM,KAAK,aAAa,SAAS,OAAO,MAAM;AAE7D,UAAM,eAA8B,OAAO,IAAI,CAAC,UAAU;AACxD,YAAM,SAAS,KAAK,OAAO,WAAW,MAAM,GAAG;AAC/C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,IAAI,MAAM;AAAA,QACV,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,SAAS,MAAM;AAAA,QACf,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,MAClB;AAAA,IACF,CAAC;AAED,QAAI,cAAc;AAChB,YAAM,kBAAkB,aAAa,YAAY;AACjD,aAAO,aAAa;AAAA,QAClB,CAAC,UACC,MAAM,YAAY,YAAY,MAAM,mBACpC,MAAM,QAAQ,YAAY,MAAM;AAAA,MACpC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAGO,IAAM,cAAc;","names":["duckAddress"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/cf-api.ts","../src/http.ts","../src/duckduckgo-api.ts","../src/parser.ts","../src/relay-api.ts","../src/client.ts"],"sourcesContent":["export type {\n AliasProvider,\n MailProvider,\n TempMailConfig,\n FirefoxRelayConfig,\n DuckDuckGoEmailConfig,\n DuckDuckGoAliasStore,\n CFTempMailConfig,\n AliasProviderConfig,\n MailProviderConfig,\n RelayAlias,\n Email,\n ParsedEmail,\n ListAliasesOptions,\n GetEmailsOptions,\n CFMailsResponse,\n RelayAddressesResponse,\n CreateAliasResponse,\n RelayConfig,\n} from './types.js';\n\nexport {\n RelayTempMailError,\n NetworkError,\n AuthError,\n NotFoundError,\n ParseError,\n RateLimitError,\n} from './errors.js';\n\nexport { TempMailClient, RelayClient } from './client.js';\n\nexport { FirefoxRelayProvider, RelayAPIClient } from './relay-api.js';\n\nexport { CFTempMailProvider, CFEmailClient } from './cf-api.js';\n\nexport {\n DuckDuckGoEmailProvider,\n InMemoryDuckDuckGoAliasStore,\n} from './duckduckgo-api.js';\n","/**\n * Custom error classes for the relay-temp-mail package.\n *\n * These errors provide structured error information including error codes,\n * HTTP status codes, and response data for better error handling.\n */\n\n/**\n * Base error class for all relay-temp-mail errors.\n *\n * Extends the built-in Error class with additional context about the error,\n * including an error code for programmatic error handling and optional\n * response data from the API.\n */\nexport class RelayTempMailError extends Error {\n /**\n * Machine-readable error code for programmatic error handling.\n * Examples: 'NETWORK_ERROR', 'AUTH_ERROR', 'NOT_FOUND'\n */\n code: string;\n\n /**\n * HTTP status code associated with this error, if applicable.\n */\n statusCode?: number;\n\n /**\n * Raw response data from the API, if available.\n */\n response?: any;\n\n /**\n * Creates a new RelayTempMailError instance.\n *\n * @param message - Human-readable error message describing the error.\n * @param code - Machine-readable error code (e.g., 'UNKNOWN_ERROR').\n * @param statusCode - Optional HTTP status code associated with the error.\n * @param response - Optional raw response data from the API.\n */\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n response?: any\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.statusCode = statusCode;\n this.response = response;\n\n // Maintains proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error for network-related failures.\n *\n * Thrown when there is a problem establishing or maintaining a network\n * connection, such as DNS resolution failures, connection timeouts,\n * or network unreachability.\n */\nexport class NetworkError extends RelayTempMailError {\n code = 'NETWORK_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NETWORK_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for authentication and authorization failures.\n *\n * Thrown when API requests fail due to invalid or missing credentials\n * (401) or when the authenticated user lacks permission for the\n * requested operation (403).\n */\nexport class AuthError extends RelayTempMailError {\n code = 'AUTH_ERROR' as const;\n\n constructor(message: string, statusCode?: number, response?: any) {\n super(message, 'AUTH_ERROR', statusCode, response);\n }\n}\n\n/**\n * Error for resource not found errors.\n *\n * Thrown when the requested resource does not exist (404 response),\n * such as when trying to access a non-existent alias or email.\n */\nexport class NotFoundError extends RelayTempMailError {\n code = 'NOT_FOUND' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NOT_FOUND', 404, response);\n }\n}\n\n/**\n * Error for MIME message parsing failures.\n *\n * Thrown when there is an error parsing email MIME content,\n * such as malformed headers or invalid message structure.\n */\nexport class ParseError extends RelayTempMailError {\n code = 'PARSE_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'PARSE_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for rate limiting responses.\n *\n * Thrown when the API rate limit has been exceeded (429 response).\n * The client should wait and retry the request after the indicated\n * cooldown period.\n */\nexport class RateLimitError extends RelayTempMailError {\n code = 'RATE_LIMIT_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'RATE_LIMIT_ERROR', 429, response);\n }\n}\n","import type { MailProvider, Email } from './types.js';\nimport { AuthError, NetworkError, NotFoundError, RateLimitError, RelayTempMailError } from './errors.js';\n\ninterface CFRawEmail {\n id: number;\n message_id: string;\n source: string;\n address: string;\n raw: string;\n metadata: any | null;\n created_at: string;\n}\n\ninterface CFRawResponse {\n results: CFRawEmail[];\n count: number;\n}\n\nexport class CFTempMailProvider implements MailProvider {\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly httpClient: HttpClient;\n\n constructor(apiUrl: string, token: string, httpClient?: HttpClient) {\n this.apiUrl = apiUrl.replace(/\\/+$/, '');\n this.token = token;\n this.httpClient = httpClient ?? new DefaultHttpClient();\n }\n\n async getMails(limit: number = 20, offset: number = 0): Promise<Email[]> {\n const url = new URL(`${this.apiUrl}/api/mails`);\n url.searchParams.set('limit', String(limit));\n url.searchParams.set('offset', String(offset));\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.token}`,\n };\n\n try {\n const response = await this.httpClient.get(url.toString(), { headers });\n return this.mapCFResponse(response as CFRawResponse);\n } catch (error) {\n throw this.handleError(error);\n }\n }\n\n private mapCFResponse(response: CFRawResponse): Email[] {\n return response.results.map((item): Email => ({\n id: item.id,\n messageId: item.message_id,\n source: item.source,\n address: item.address,\n raw: item.raw,\n metadata: item.metadata,\n createdAt: item.created_at,\n }));\n }\n\n private handleError(error: unknown): RelayTempMailError {\n if (error instanceof RelayTempMailError) {\n const statusCode = error.statusCode;\n\n if (statusCode === 401 || statusCode === 403) {\n return new AuthError(error.message, statusCode, error.response);\n }\n if (statusCode === 404) {\n return new NotFoundError(error.message, error.response);\n }\n if (statusCode === 429) {\n return new RateLimitError(error.message, error.response);\n }\n\n return error;\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError(error.message);\n }\n\n if (error instanceof Error) {\n return new NetworkError(error.message);\n }\n\n return new RelayTempMailError(\n 'Unknown error occurred',\n 'UNKNOWN_ERROR',\n undefined,\n error\n );\n }\n}\n\n/** @deprecated Use CFTempMailProvider instead */\nexport const CFEmailClient = CFTempMailProvider;\n\nexport interface HttpClient {\n get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown>;\n}\n\nexport class DefaultHttpClient implements HttpClient {\n async get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown> {\n const response = await fetch(url, {\n method: 'GET',\n headers: options?.headers,\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw new RelayTempMailError(\n `HTTP ${response.status}: ${errorBody}`,\n 'HTTP_ERROR',\n response.status,\n errorBody\n );\n }\n\n return response.json();\n }\n}\n","/**\n * HTTP client utilities for the relay-temp-mail package.\n *\n * This module provides a configurable HTTP client with timeout support,\n * automatic retry logic, and proper error classification for API responses.\n */\n\nimport {\n RelayTempMailError,\n NetworkError,\n AuthError,\n NotFoundError,\n RateLimitError,\n} from './errors';\n\n/**\n * Options for individual HTTP requests.\n */\nexport interface RequestOptions {\n /** Custom headers to include in the request */\n headers?: Record<string, string>;\n\n /** Request body (will be JSON serialized) */\n body?: unknown;\n\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n\n /** Number of retries on failure (overrides client default) */\n retries?: number;\n}\n\n/**\n * HTTP client for making requests to the relay-temp-mail API.\n *\n * Provides a configurable base URL with timeout, retry, and automatic\n * JSON parsing capabilities.\n */\nexport class HttpClient {\n private baseUrl: string;\n private defaultTimeout: number;\n private defaultRetries: number;\n\n /**\n * Creates a new HttpClient instance.\n *\n * @param baseUrl - Base URL for all requests (e.g., 'https://api.example.com')\n * @param defaultTimeout - Default timeout in milliseconds (default: 30000)\n * @param defaultRetries - Default number of retries on failure (default: 0)\n */\n constructor(\n baseUrl: string,\n defaultTimeout: number = 30000,\n defaultRetries: number = 0\n ) {\n this.baseUrl = baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.defaultTimeout = defaultTimeout;\n this.defaultRetries = defaultRetries;\n }\n\n /**\n * Makes an HTTP request to the specified path.\n *\n * @param method - HTTP method (GET, POST, PUT, DELETE, etc.)\n * @param path - API path (will be appended to baseUrl)\n * @param options - Optional request configuration\n * @returns Promise resolving to the parsed JSON response\n */\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const timeout = options.timeout ?? this.defaultTimeout;\n const retries = options.retries ?? this.defaultRetries;\n\n let lastError: RelayTempMailError | Error | undefined;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const response = await this.executeRequest(method, path, options, timeout);\n return await this.handleResponse<T>(response);\n } catch (error) {\n lastError = error as Error;\n\n // Check if we should retry\n if (attempt < retries && this.shouldRetry(error)) {\n const delay = 1000 * Math.pow(2, attempt);\n await this.sleep(delay);\n continue;\n }\n\n // Don't retry, throw the classified error\n if (error instanceof RelayTempMailError) {\n throw error;\n }\n\n // Classify the error if not already classified\n throw this.classifyError(error);\n }\n }\n\n // This should never be reached, but just in case\n throw lastError || new NetworkError('Request failed');\n }\n\n /**\n * Executes the actual HTTP request with timeout support.\n */\n private async executeRequest(\n method: string,\n path: string,\n options: RequestOptions,\n timeout: number\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n signal: controller.signal,\n };\n\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n const response = await fetch(url, fetchOptions);\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Handles the HTTP response, parsing JSON and checking for errors.\n */\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n throw this.classifyError(new Error(`HTTP ${response.status}`), response);\n }\n\n const text = await response.text();\n\n // Handle empty responses\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n }\n\n /**\n * Classifies an error based on the error type and HTTP response.\n */\n private classifyError(error: unknown, response?: Response): RelayTempMailError {\n // Network errors (fetch failed)\n if (error instanceof Error && error.name === 'AbortError') {\n return new NetworkError('Request timed out');\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError('Network request failed');\n }\n\n if (error instanceof Error && error.message.includes('Failed to fetch')) {\n return new NetworkError('Network request failed');\n }\n\n // HTTP status-based classification\n if (response) {\n const status = response.status;\n\n if (status === 401 || status === 403) {\n return new AuthError(\n `Authentication failed: ${response.statusText}`,\n status\n );\n }\n\n if (status === 404) {\n return new NotFoundError(`Resource not found: ${response.statusText}`);\n }\n\n if (status === 429) {\n return new RateLimitError(\n `Rate limit exceeded: ${response.statusText}`\n );\n }\n\n if (status >= 500) {\n return new NetworkError(\n `Server error: ${response.statusText}`,\n status\n );\n }\n }\n\n // Default error\n if (error instanceof Error) {\n return new RelayTempMailError(\n error.message,\n 'REQUEST_ERROR',\n response?.status\n );\n }\n\n return new RelayTempMailError('Unknown error occurred', 'UNKNOWN_ERROR');\n }\n\n /**\n * Determines if a request should be retried based on the error.\n */\n private shouldRetry(error: unknown): boolean {\n if (error instanceof NetworkError) {\n return true;\n }\n\n if (error instanceof RelayTempMailError && error.statusCode) {\n return error.statusCode >= 500;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n return true;\n }\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Sleep for a specified duration.\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient } from './http';\nimport { RelayTempMailError } from './errors';\nimport type { AliasProvider, RelayAlias, DuckDuckGoAliasStore } from './types';\n\ninterface DuckDuckGoCreateAddressResponse {\n address: string;\n}\n\nexport class InMemoryDuckDuckGoAliasStore implements DuckDuckGoAliasStore {\n private aliases: RelayAlias[] = [];\n\n getAll(): RelayAlias[] {\n return [...this.aliases];\n }\n\n add(alias: RelayAlias): void {\n this.aliases.push(alias);\n }\n\n remove(id: number): void {\n this.aliases = this.aliases.filter((a) => a.id !== id);\n }\n}\n\nexport class DuckDuckGoEmailProvider implements AliasProvider {\n private jwtToken: string;\n private httpClient: HttpClient;\n private store: DuckDuckGoAliasStore;\n private nextId: number;\n\n constructor(\n jwtToken: string,\n store?: DuckDuckGoAliasStore,\n httpClient?: HttpClient\n ) {\n this.jwtToken = jwtToken;\n this.store = store ?? new InMemoryDuckDuckGoAliasStore();\n this.httpClient =\n httpClient ?? new HttpClient('https://quack.duckduckgo.com');\n this.nextId = 1;\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.store.getAll();\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response =\n await this.httpClient.request<DuckDuckGoCreateAddressResponse>(\n 'POST',\n '/api/email/addresses',\n {\n headers: {\n Authorization: `Bearer ${this.jwtToken}`,\n },\n }\n );\n\n const fullAddress = `${response.address}@duck.com`;\n\n const existing = await this.store.getAll();\n if (existing.some((a) => a.fullAddress === fullAddress)) {\n throw new RelayTempMailError(\n `DuckDuckGo returned a duplicate alias: ${fullAddress}`,\n 'DUPLICATE_ALIAS',\n 201\n );\n }\n\n const alias: RelayAlias = {\n id: this.nextId++,\n address: response.address,\n fullAddress,\n enabled: true,\n createdAt: new Date().toISOString(),\n domain: 3,\n maskType: 'random',\n };\n\n await this.store.add(alias);\n return alias;\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.store.remove(id);\n }\n}\n","/**\n * MIME email parser for extracting Firefox Relay alias information.\n */\nimport type { ParsedEmail } from './types.js';\n\nconst EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g;\nconst MOZMAIL_SUFFIX_PATTERN = /@mozmail\\.com$/i;\nconst DUCK_SUFFIX_PATTERN = /@duck\\.com$/i;\n// DuckDuckGo aliases are \"word-word-word@duck.com\"; the From header\n// uses \"sender_at_domain_alias@duck.com\" which EMAIL_PATTERN matches\n// as a single address. This pattern extracts just the alias portion.\nconst DUCK_ALIAS_PATTERN = /([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)+@duck\\.com)/gi;\n// System addresses at @duck.com that are not user aliases\nconst DUCK_SYSTEM_ADDRESSES = new Set(['support@duck.com', 'noreply@duck.com']);\nconst ENCODED_WORD_PATTERN = /=\\?([^?]+)\\?([BbQq])\\?([^?]*)\\?=/g;\n\n/**\n * EmailParser class for parsing MIME email content.\n */\nexport class EmailParser {\n parseEmail(raw: string): ParsedEmail {\n const headers = this.parseHeaders(raw);\n const toHeader = headers.get('to') || '';\n const fromHeader = headers.get('from') || '';\n const messageIdHeader = headers.get('message-id') || '';\n const relayAlias = this.extractRelayAlias(raw);\n \n return {\n id: 0,\n messageId: this.extractMessageId(messageIdHeader),\n source: this.extractEmailAddress(fromHeader),\n address: this.extractEmailAddress(toHeader),\n raw,\n metadata: null,\n createdAt: new Date().toISOString(),\n relayAlias: relayAlias || undefined,\n };\n }\n\n extractRelayAlias(raw: string): string | null {\n try {\n const headers = this.parseHeaders(raw);\n\n // DuckDuckGo Email Protection adds a Duck-Original-To header\n // containing the @duck.com alias the email was forwarded to\n const duckOriginalTo = headers.get('duck-original-to');\n if (duckOriginalTo) {\n const duckAddress = this.extractEmailAddress(duckOriginalTo);\n if (duckAddress && DUCK_SUFFIX_PATTERN.test(duckAddress)) {\n return duckAddress;\n }\n }\n\n // Search the full raw content for @duck.com addresses.\n // Duck-Original-To may be stripped during forwarding,\n // but the alias address often appears in From headers as\n // \"sender_at_domain_alias@duck.com\" or elsewhere in the MIME.\n // First try the precise pattern (hyphenated aliases like word-word-word@duck.com)\n const duckMatches = raw.match(DUCK_ALIAS_PATTERN);\n if (duckMatches && duckMatches.length > 0) {\n return duckMatches[0].toLowerCase();\n }\n // Fallback: search with broader EMAIL_PATTERN and filter for @duck.com,\n // excluding known system addresses like support@duck.com\n const rawEmails = raw.match(EMAIL_PATTERN) ?? [];\n const duckFallback = rawEmails.find(\n (e) => DUCK_SUFFIX_PATTERN.test(e) && !DUCK_SYSTEM_ADDRESSES.has(e.toLowerCase())\n );\n if (duckFallback) return duckFallback.toLowerCase();\n\n const fromAddresses = this.extractHeaderEmails(headers.get('from'));\n const toAddresses = this.extractHeaderEmails(headers.get('to'));\n const allAddresses = [...fromAddresses, ...toAddresses];\n\n const mozmailAddress = allAddresses.find((address) =>\n MOZMAIL_SUFFIX_PATTERN.test(address)\n );\n if (mozmailAddress) return mozmailAddress;\n\n return toAddresses[0] ?? null;\n } catch {\n return null;\n }\n }\n\n private parseHeaders(raw: string): Map<string, string> {\n const headers = new Map<string, string>();\n const headerEnd = raw.indexOf('\\r\\n\\r\\n');\n const headerSection = headerEnd === -1 ? raw : raw.substring(0, headerEnd);\n const lines = headerSection.split(/\\r?\\n/);\n let currentHeader: string | null = null;\n let currentValue = '';\n \n for (const line of lines) {\n if (/^\\s/.test(line)) {\n if (currentHeader) currentValue += ' ' + line.trim();\n } else {\n if (currentHeader) headers.set(currentHeader, currentValue);\n const colonIndex = line.indexOf(':');\n if (colonIndex > 0) {\n currentHeader = line.substring(0, colonIndex).toLowerCase().trim();\n currentValue = line.substring(colonIndex + 1).trim();\n } else {\n currentHeader = null;\n currentValue = '';\n }\n }\n }\n if (currentHeader) headers.set(currentHeader, currentValue);\n return headers;\n }\n\n private decodeHeader(value: string): string {\n return value.replace(ENCODED_WORD_PATTERN, (_, charset, encoding, encoded) => {\n try {\n if (encoding.toUpperCase() === 'Q') {\n return this.decodeQuotedPrintable(encoded);\n } else if (encoding.toUpperCase() === 'B') {\n return this.decodeBase64(encoded);\n }\n return encoded;\n } catch {\n return encoded;\n }\n });\n }\n\n private decodeQuotedPrintable(encoded: string): string {\n // RFC 2047: underscores represent spaces in encoded-word\n let decoded = encoded.replace(/_/g, ' ');\n decoded = decoded.replace(/=([0-9A-Fa-f]{2})/g, (_, hex) => \n String.fromCharCode(parseInt(hex, 16))\n );\n return decoded;\n }\n\n private decodeBase64(encoded: string): string {\n return Buffer.from(encoded, 'base64').toString('utf-8');\n }\n\n private extractEmailAddress(headerValue: string): string {\n if (!headerValue) return '';\n const decoded = this.decodeHeader(headerValue);\n const bracketMatch = decoded.match(/<([^>]+)>/);\n if (bracketMatch) return bracketMatch[1].trim().toLowerCase();\n const emailMatch = decoded.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/);\n return emailMatch ? emailMatch[0].toLowerCase() : decoded.trim().toLowerCase();\n }\n\n private extractHeaderEmails(headerValue?: string): string[] {\n if (!headerValue) return [];\n const decoded = this.decodeHeader(headerValue);\n const matches = decoded.match(EMAIL_PATTERN);\n return matches ? matches.map((match) => match.toLowerCase()) : [];\n }\n\n private extractMessageId(headerValue: string): string {\n if (!headerValue) return `<generated-${Date.now()}@relay-temp-mail>`;\n const cleaned = headerValue.replace(/[<>]/g, '').trim();\n return `<${cleaned}>`;\n }\n}\n","import { HttpClient } from './http';\nimport type { AliasProvider, RelayAlias } from './types';\n\ninterface RawAliasResponse {\n id: number;\n address: string;\n full_address: string;\n enabled: boolean;\n created_at: string;\n domain: number;\n mask_type: string;\n description?: string;\n num_forwarded?: number;\n num_blocked?: number;\n last_modified_at?: string;\n last_used_at?: string | null;\n num_level_one_trackers_blocked?: number;\n num_replied?: number;\n num_spam?: number;\n block_list_emails?: boolean;\n generated_for?: string;\n used_on?: string | null;\n}\n\nexport class FirefoxRelayProvider implements AliasProvider {\n private csrfToken: string;\n private sessionId: string;\n private httpClient: HttpClient;\n\n constructor(\n csrfToken: string,\n sessionId: string,\n httpClient?: HttpClient\n ) {\n this.csrfToken = csrfToken;\n this.sessionId = sessionId;\n this.httpClient = httpClient ?? new HttpClient('https://relay.firefox.com');\n }\n\n private getAuthHeaders(): Record<string, string> {\n return {\n 'Origin': 'https://relay.firefox.com',\n 'Referer': 'https://relay.firefox.com/accounts/profile/?',\n 'Accept': 'application/json',\n 'X-CSRFToken': this.csrfToken,\n 'Cookie': `sessionid=${this.sessionId}; csrftoken=${this.csrfToken}`,\n };\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n const response = await this.httpClient.request<RawAliasResponse[]>(\n 'GET',\n '/api/v1/relayaddresses/',\n { headers: this.getAuthHeaders() }\n );\n\n return response.map((item) => this.mapAliasResponse(item));\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response = await this.httpClient.request<RawAliasResponse>(\n 'POST',\n '/api/v1/relayaddresses/',\n {\n headers: this.getAuthHeaders(),\n body: { enabled: true },\n }\n );\n\n return this.mapAliasResponse(response);\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.httpClient.request<void>(\n 'DELETE',\n `/api/v1/relayaddresses/${id}/`,\n { headers: this.getAuthHeaders() }\n );\n }\n\n private mapAliasResponse(data: RawAliasResponse): RelayAlias {\n return {\n id: data.id,\n address: data.address,\n fullAddress: data.full_address,\n enabled: data.enabled,\n createdAt: data.created_at,\n domain: data.domain,\n maskType: data.mask_type,\n description: data.description,\n numForwarded: data.num_forwarded,\n numBlocked: data.num_blocked,\n lastModifiedAt: data.last_modified_at,\n lastUsedAt: data.last_used_at,\n numLevelOneTrackersBlocked: data.num_level_one_trackers_blocked,\n numReplied: data.num_replied,\n numSpam: data.num_spam,\n blockListEmails: data.block_list_emails,\n generatedFor: data.generated_for,\n usedOn: data.used_on,\n };\n }\n}\n\n/** @deprecated Use FirefoxRelayProvider instead */\nexport const RelayAPIClient = FirefoxRelayProvider;\n","import { CFTempMailProvider, DefaultHttpClient } from './cf-api.js';\nimport { DuckDuckGoEmailProvider } from './duckduckgo-api.js';\nimport { EmailParser } from './parser.js';\nimport { FirefoxRelayProvider } from './relay-api.js';\nimport { HttpClient } from './http.js';\nimport type {\n TempMailConfig,\n RelayConfig,\n AliasProvider,\n MailProvider,\n RelayAlias,\n ParsedEmail,\n GetEmailsOptions,\n} from './types.js';\n\nfunction createAliasProvider(config: TempMailConfig, httpClient: HttpClient): AliasProvider {\n const aliasConfig = config.aliasProvider;\n switch (aliasConfig.type) {\n case 'firefox-relay':\n return new FirefoxRelayProvider(\n aliasConfig.csrfToken,\n aliasConfig.sessionId,\n httpClient\n );\n case 'duckduckgo-email':\n return new DuckDuckGoEmailProvider(\n aliasConfig.jwtToken,\n aliasConfig.store\n );\n }\n}\n\nfunction createMailProvider(config: TempMailConfig): MailProvider {\n const mailConfig = config.mailProvider;\n switch (mailConfig.type) {\n case 'cf-temp-mail':\n return new CFTempMailProvider(\n mailConfig.apiUrl,\n mailConfig.token\n );\n }\n}\n\nexport class TempMailClient {\n private readonly aliasProvider: AliasProvider;\n private readonly mailProvider: MailProvider;\n private readonly parser: EmailParser;\n\n constructor(config: TempMailConfig) {\n const timeout = config.timeout ?? 30000;\n const httpClient = new HttpClient('https://relay.firefox.com', timeout);\n this.aliasProvider = createAliasProvider(config, httpClient);\n this.mailProvider = createMailProvider(config);\n this.parser = new EmailParser();\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.aliasProvider.listAliases();\n }\n\n async createAlias(): Promise<RelayAlias> {\n return this.aliasProvider.createAlias();\n }\n\n async deleteAlias(id: number): Promise<void> {\n return this.aliasProvider.deleteAlias(id);\n }\n\n async getEmails(\n aliasAddress?: string,\n options?: GetEmailsOptions\n ): Promise<ParsedEmail[]> {\n const limit = options?.limit ?? 20;\n const offset = options?.offset ?? 0;\n\n const emails = await this.mailProvider.getMails(limit, offset);\n\n const parsedEmails: ParsedEmail[] = emails.map((email) => {\n const parsed = this.parser.parseEmail(email.raw);\n return {\n ...parsed,\n id: email.id,\n messageId: email.messageId,\n source: email.source,\n address: email.address,\n createdAt: email.createdAt,\n metadata: email.metadata,\n };\n });\n\n if (aliasAddress) {\n const normalizedAlias = aliasAddress.toLowerCase();\n return parsedEmails.filter(\n (email) =>\n email.relayAlias?.toLowerCase() === normalizedAlias ||\n email.address.toLowerCase() === normalizedAlias\n );\n }\n\n return parsedEmails;\n }\n}\n\n/** @deprecated Use TempMailClient instead */\nexport const RelayClient = TempMailClient;\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -351,6 +351,8 @@ var DuckDuckGoEmailProvider = class {
351
351
  var EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
352
352
  var MOZMAIL_SUFFIX_PATTERN = /@mozmail\.com$/i;
353
353
  var DUCK_SUFFIX_PATTERN = /@duck\.com$/i;
354
+ var DUCK_ALIAS_PATTERN = /([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)+@duck\.com)/gi;
355
+ var DUCK_SYSTEM_ADDRESSES = /* @__PURE__ */ new Set(["support@duck.com", "noreply@duck.com"]);
354
356
  var ENCODED_WORD_PATTERN = /=\?([^?]+)\?([BbQq])\?([^?]*)\?=/g;
355
357
  var EmailParser = class {
356
358
  parseEmail(raw) {
@@ -375,11 +377,20 @@ var EmailParser = class {
375
377
  const headers = this.parseHeaders(raw);
376
378
  const duckOriginalTo = headers.get("duck-original-to");
377
379
  if (duckOriginalTo) {
378
- const duckAddress2 = this.extractEmailAddress(duckOriginalTo);
379
- if (duckAddress2 && DUCK_SUFFIX_PATTERN.test(duckAddress2)) {
380
- return duckAddress2;
380
+ const duckAddress = this.extractEmailAddress(duckOriginalTo);
381
+ if (duckAddress && DUCK_SUFFIX_PATTERN.test(duckAddress)) {
382
+ return duckAddress;
381
383
  }
382
384
  }
385
+ const duckMatches = raw.match(DUCK_ALIAS_PATTERN);
386
+ if (duckMatches && duckMatches.length > 0) {
387
+ return duckMatches[0].toLowerCase();
388
+ }
389
+ const rawEmails = raw.match(EMAIL_PATTERN) ?? [];
390
+ const duckFallback = rawEmails.find(
391
+ (e) => DUCK_SUFFIX_PATTERN.test(e) && !DUCK_SYSTEM_ADDRESSES.has(e.toLowerCase())
392
+ );
393
+ if (duckFallback) return duckFallback.toLowerCase();
383
394
  const fromAddresses = this.extractHeaderEmails(headers.get("from"));
384
395
  const toAddresses = this.extractHeaderEmails(headers.get("to"));
385
396
  const allAddresses = [...fromAddresses, ...toAddresses];
@@ -387,10 +398,6 @@ var EmailParser = class {
387
398
  (address) => MOZMAIL_SUFFIX_PATTERN.test(address)
388
399
  );
389
400
  if (mozmailAddress) return mozmailAddress;
390
- const duckAddress = allAddresses.find(
391
- (address) => DUCK_SUFFIX_PATTERN.test(address)
392
- );
393
- if (duckAddress) return duckAddress;
394
401
  return toAddresses[0] ?? null;
395
402
  } catch {
396
403
  return null;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/cf-api.ts","../src/http.ts","../src/duckduckgo-api.ts","../src/parser.ts","../src/relay-api.ts","../src/client.ts"],"sourcesContent":["/**\n * Custom error classes for the relay-temp-mail package.\n *\n * These errors provide structured error information including error codes,\n * HTTP status codes, and response data for better error handling.\n */\n\n/**\n * Base error class for all relay-temp-mail errors.\n *\n * Extends the built-in Error class with additional context about the error,\n * including an error code for programmatic error handling and optional\n * response data from the API.\n */\nexport class RelayTempMailError extends Error {\n /**\n * Machine-readable error code for programmatic error handling.\n * Examples: 'NETWORK_ERROR', 'AUTH_ERROR', 'NOT_FOUND'\n */\n code: string;\n\n /**\n * HTTP status code associated with this error, if applicable.\n */\n statusCode?: number;\n\n /**\n * Raw response data from the API, if available.\n */\n response?: any;\n\n /**\n * Creates a new RelayTempMailError instance.\n *\n * @param message - Human-readable error message describing the error.\n * @param code - Machine-readable error code (e.g., 'UNKNOWN_ERROR').\n * @param statusCode - Optional HTTP status code associated with the error.\n * @param response - Optional raw response data from the API.\n */\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n response?: any\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.statusCode = statusCode;\n this.response = response;\n\n // Maintains proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error for network-related failures.\n *\n * Thrown when there is a problem establishing or maintaining a network\n * connection, such as DNS resolution failures, connection timeouts,\n * or network unreachability.\n */\nexport class NetworkError extends RelayTempMailError {\n code = 'NETWORK_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NETWORK_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for authentication and authorization failures.\n *\n * Thrown when API requests fail due to invalid or missing credentials\n * (401) or when the authenticated user lacks permission for the\n * requested operation (403).\n */\nexport class AuthError extends RelayTempMailError {\n code = 'AUTH_ERROR' as const;\n\n constructor(message: string, statusCode?: number, response?: any) {\n super(message, 'AUTH_ERROR', statusCode, response);\n }\n}\n\n/**\n * Error for resource not found errors.\n *\n * Thrown when the requested resource does not exist (404 response),\n * such as when trying to access a non-existent alias or email.\n */\nexport class NotFoundError extends RelayTempMailError {\n code = 'NOT_FOUND' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NOT_FOUND', 404, response);\n }\n}\n\n/**\n * Error for MIME message parsing failures.\n *\n * Thrown when there is an error parsing email MIME content,\n * such as malformed headers or invalid message structure.\n */\nexport class ParseError extends RelayTempMailError {\n code = 'PARSE_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'PARSE_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for rate limiting responses.\n *\n * Thrown when the API rate limit has been exceeded (429 response).\n * The client should wait and retry the request after the indicated\n * cooldown period.\n */\nexport class RateLimitError extends RelayTempMailError {\n code = 'RATE_LIMIT_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'RATE_LIMIT_ERROR', 429, response);\n }\n}\n","import type { MailProvider, Email } from './types.js';\nimport { AuthError, NetworkError, NotFoundError, RateLimitError, RelayTempMailError } from './errors.js';\n\ninterface CFRawEmail {\n id: number;\n message_id: string;\n source: string;\n address: string;\n raw: string;\n metadata: any | null;\n created_at: string;\n}\n\ninterface CFRawResponse {\n results: CFRawEmail[];\n count: number;\n}\n\nexport class CFTempMailProvider implements MailProvider {\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly httpClient: HttpClient;\n\n constructor(apiUrl: string, token: string, httpClient?: HttpClient) {\n this.apiUrl = apiUrl.replace(/\\/+$/, '');\n this.token = token;\n this.httpClient = httpClient ?? new DefaultHttpClient();\n }\n\n async getMails(limit: number = 20, offset: number = 0): Promise<Email[]> {\n const url = new URL(`${this.apiUrl}/api/mails`);\n url.searchParams.set('limit', String(limit));\n url.searchParams.set('offset', String(offset));\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.token}`,\n };\n\n try {\n const response = await this.httpClient.get(url.toString(), { headers });\n return this.mapCFResponse(response as CFRawResponse);\n } catch (error) {\n throw this.handleError(error);\n }\n }\n\n private mapCFResponse(response: CFRawResponse): Email[] {\n return response.results.map((item): Email => ({\n id: item.id,\n messageId: item.message_id,\n source: item.source,\n address: item.address,\n raw: item.raw,\n metadata: item.metadata,\n createdAt: item.created_at,\n }));\n }\n\n private handleError(error: unknown): RelayTempMailError {\n if (error instanceof RelayTempMailError) {\n const statusCode = error.statusCode;\n\n if (statusCode === 401 || statusCode === 403) {\n return new AuthError(error.message, statusCode, error.response);\n }\n if (statusCode === 404) {\n return new NotFoundError(error.message, error.response);\n }\n if (statusCode === 429) {\n return new RateLimitError(error.message, error.response);\n }\n\n return error;\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError(error.message);\n }\n\n if (error instanceof Error) {\n return new NetworkError(error.message);\n }\n\n return new RelayTempMailError(\n 'Unknown error occurred',\n 'UNKNOWN_ERROR',\n undefined,\n error\n );\n }\n}\n\n/** @deprecated Use CFTempMailProvider instead */\nexport const CFEmailClient = CFTempMailProvider;\n\nexport interface HttpClient {\n get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown>;\n}\n\nexport class DefaultHttpClient implements HttpClient {\n async get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown> {\n const response = await fetch(url, {\n method: 'GET',\n headers: options?.headers,\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw new RelayTempMailError(\n `HTTP ${response.status}: ${errorBody}`,\n 'HTTP_ERROR',\n response.status,\n errorBody\n );\n }\n\n return response.json();\n }\n}\n","/**\n * HTTP client utilities for the relay-temp-mail package.\n *\n * This module provides a configurable HTTP client with timeout support,\n * automatic retry logic, and proper error classification for API responses.\n */\n\nimport {\n RelayTempMailError,\n NetworkError,\n AuthError,\n NotFoundError,\n RateLimitError,\n} from './errors';\n\n/**\n * Options for individual HTTP requests.\n */\nexport interface RequestOptions {\n /** Custom headers to include in the request */\n headers?: Record<string, string>;\n\n /** Request body (will be JSON serialized) */\n body?: unknown;\n\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n\n /** Number of retries on failure (overrides client default) */\n retries?: number;\n}\n\n/**\n * HTTP client for making requests to the relay-temp-mail API.\n *\n * Provides a configurable base URL with timeout, retry, and automatic\n * JSON parsing capabilities.\n */\nexport class HttpClient {\n private baseUrl: string;\n private defaultTimeout: number;\n private defaultRetries: number;\n\n /**\n * Creates a new HttpClient instance.\n *\n * @param baseUrl - Base URL for all requests (e.g., 'https://api.example.com')\n * @param defaultTimeout - Default timeout in milliseconds (default: 30000)\n * @param defaultRetries - Default number of retries on failure (default: 0)\n */\n constructor(\n baseUrl: string,\n defaultTimeout: number = 30000,\n defaultRetries: number = 0\n ) {\n this.baseUrl = baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.defaultTimeout = defaultTimeout;\n this.defaultRetries = defaultRetries;\n }\n\n /**\n * Makes an HTTP request to the specified path.\n *\n * @param method - HTTP method (GET, POST, PUT, DELETE, etc.)\n * @param path - API path (will be appended to baseUrl)\n * @param options - Optional request configuration\n * @returns Promise resolving to the parsed JSON response\n */\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const timeout = options.timeout ?? this.defaultTimeout;\n const retries = options.retries ?? this.defaultRetries;\n\n let lastError: RelayTempMailError | Error | undefined;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const response = await this.executeRequest(method, path, options, timeout);\n return await this.handleResponse<T>(response);\n } catch (error) {\n lastError = error as Error;\n\n // Check if we should retry\n if (attempt < retries && this.shouldRetry(error)) {\n const delay = 1000 * Math.pow(2, attempt);\n await this.sleep(delay);\n continue;\n }\n\n // Don't retry, throw the classified error\n if (error instanceof RelayTempMailError) {\n throw error;\n }\n\n // Classify the error if not already classified\n throw this.classifyError(error);\n }\n }\n\n // This should never be reached, but just in case\n throw lastError || new NetworkError('Request failed');\n }\n\n /**\n * Executes the actual HTTP request with timeout support.\n */\n private async executeRequest(\n method: string,\n path: string,\n options: RequestOptions,\n timeout: number\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n signal: controller.signal,\n };\n\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n const response = await fetch(url, fetchOptions);\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Handles the HTTP response, parsing JSON and checking for errors.\n */\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n throw this.classifyError(new Error(`HTTP ${response.status}`), response);\n }\n\n const text = await response.text();\n\n // Handle empty responses\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n }\n\n /**\n * Classifies an error based on the error type and HTTP response.\n */\n private classifyError(error: unknown, response?: Response): RelayTempMailError {\n // Network errors (fetch failed)\n if (error instanceof Error && error.name === 'AbortError') {\n return new NetworkError('Request timed out');\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError('Network request failed');\n }\n\n if (error instanceof Error && error.message.includes('Failed to fetch')) {\n return new NetworkError('Network request failed');\n }\n\n // HTTP status-based classification\n if (response) {\n const status = response.status;\n\n if (status === 401 || status === 403) {\n return new AuthError(\n `Authentication failed: ${response.statusText}`,\n status\n );\n }\n\n if (status === 404) {\n return new NotFoundError(`Resource not found: ${response.statusText}`);\n }\n\n if (status === 429) {\n return new RateLimitError(\n `Rate limit exceeded: ${response.statusText}`\n );\n }\n\n if (status >= 500) {\n return new NetworkError(\n `Server error: ${response.statusText}`,\n status\n );\n }\n }\n\n // Default error\n if (error instanceof Error) {\n return new RelayTempMailError(\n error.message,\n 'REQUEST_ERROR',\n response?.status\n );\n }\n\n return new RelayTempMailError('Unknown error occurred', 'UNKNOWN_ERROR');\n }\n\n /**\n * Determines if a request should be retried based on the error.\n */\n private shouldRetry(error: unknown): boolean {\n if (error instanceof NetworkError) {\n return true;\n }\n\n if (error instanceof RelayTempMailError && error.statusCode) {\n return error.statusCode >= 500;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n return true;\n }\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Sleep for a specified duration.\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient } from './http';\nimport { RelayTempMailError } from './errors';\nimport type { AliasProvider, RelayAlias, DuckDuckGoAliasStore } from './types';\n\ninterface DuckDuckGoCreateAddressResponse {\n address: string;\n}\n\nexport class InMemoryDuckDuckGoAliasStore implements DuckDuckGoAliasStore {\n private aliases: RelayAlias[] = [];\n\n getAll(): RelayAlias[] {\n return [...this.aliases];\n }\n\n add(alias: RelayAlias): void {\n this.aliases.push(alias);\n }\n\n remove(id: number): void {\n this.aliases = this.aliases.filter((a) => a.id !== id);\n }\n}\n\nexport class DuckDuckGoEmailProvider implements AliasProvider {\n private jwtToken: string;\n private httpClient: HttpClient;\n private store: DuckDuckGoAliasStore;\n private nextId: number;\n\n constructor(\n jwtToken: string,\n store?: DuckDuckGoAliasStore,\n httpClient?: HttpClient\n ) {\n this.jwtToken = jwtToken;\n this.store = store ?? new InMemoryDuckDuckGoAliasStore();\n this.httpClient =\n httpClient ?? new HttpClient('https://quack.duckduckgo.com');\n this.nextId = 1;\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.store.getAll();\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response =\n await this.httpClient.request<DuckDuckGoCreateAddressResponse>(\n 'POST',\n '/api/email/addresses',\n {\n headers: {\n Authorization: `Bearer ${this.jwtToken}`,\n },\n }\n );\n\n const fullAddress = `${response.address}@duck.com`;\n\n const existing = await this.store.getAll();\n if (existing.some((a) => a.fullAddress === fullAddress)) {\n throw new RelayTempMailError(\n `DuckDuckGo returned a duplicate alias: ${fullAddress}`,\n 'DUPLICATE_ALIAS',\n 201\n );\n }\n\n const alias: RelayAlias = {\n id: this.nextId++,\n address: response.address,\n fullAddress,\n enabled: true,\n createdAt: new Date().toISOString(),\n domain: 3,\n maskType: 'random',\n };\n\n await this.store.add(alias);\n return alias;\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.store.remove(id);\n }\n}\n","/**\n * MIME email parser for extracting Firefox Relay alias information.\n */\nimport type { ParsedEmail } from './types.js';\n\nconst EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g;\nconst MOZMAIL_SUFFIX_PATTERN = /@mozmail\\.com$/i;\nconst DUCK_SUFFIX_PATTERN = /@duck\\.com$/i;\nconst ENCODED_WORD_PATTERN = /=\\?([^?]+)\\?([BbQq])\\?([^?]*)\\?=/g;\n\n/**\n * EmailParser class for parsing MIME email content.\n */\nexport class EmailParser {\n parseEmail(raw: string): ParsedEmail {\n const headers = this.parseHeaders(raw);\n const toHeader = headers.get('to') || '';\n const fromHeader = headers.get('from') || '';\n const messageIdHeader = headers.get('message-id') || '';\n const relayAlias = this.extractRelayAlias(raw);\n \n return {\n id: 0,\n messageId: this.extractMessageId(messageIdHeader),\n source: this.extractEmailAddress(fromHeader),\n address: this.extractEmailAddress(toHeader),\n raw,\n metadata: null,\n createdAt: new Date().toISOString(),\n relayAlias: relayAlias || undefined,\n };\n }\n\n extractRelayAlias(raw: string): string | null {\n try {\n const headers = this.parseHeaders(raw);\n\n // DuckDuckGo Email Protection adds a Duck-Original-To header\n // containing the @duck.com alias the email was forwarded to\n const duckOriginalTo = headers.get('duck-original-to');\n if (duckOriginalTo) {\n const duckAddress = this.extractEmailAddress(duckOriginalTo);\n if (duckAddress && DUCK_SUFFIX_PATTERN.test(duckAddress)) {\n return duckAddress;\n }\n }\n\n const fromAddresses = this.extractHeaderEmails(headers.get('from'));\n const toAddresses = this.extractHeaderEmails(headers.get('to'));\n const allAddresses = [...fromAddresses, ...toAddresses];\n\n const mozmailAddress = allAddresses.find((address) =>\n MOZMAIL_SUFFIX_PATTERN.test(address)\n );\n if (mozmailAddress) return mozmailAddress;\n\n const duckAddress = allAddresses.find((address) =>\n DUCK_SUFFIX_PATTERN.test(address)\n );\n if (duckAddress) return duckAddress;\n\n return toAddresses[0] ?? null;\n } catch {\n return null;\n }\n }\n\n private parseHeaders(raw: string): Map<string, string> {\n const headers = new Map<string, string>();\n const headerEnd = raw.indexOf('\\r\\n\\r\\n');\n const headerSection = headerEnd === -1 ? raw : raw.substring(0, headerEnd);\n const lines = headerSection.split(/\\r?\\n/);\n let currentHeader: string | null = null;\n let currentValue = '';\n \n for (const line of lines) {\n if (/^\\s/.test(line)) {\n if (currentHeader) currentValue += ' ' + line.trim();\n } else {\n if (currentHeader) headers.set(currentHeader, currentValue);\n const colonIndex = line.indexOf(':');\n if (colonIndex > 0) {\n currentHeader = line.substring(0, colonIndex).toLowerCase().trim();\n currentValue = line.substring(colonIndex + 1).trim();\n } else {\n currentHeader = null;\n currentValue = '';\n }\n }\n }\n if (currentHeader) headers.set(currentHeader, currentValue);\n return headers;\n }\n\n private decodeHeader(value: string): string {\n return value.replace(ENCODED_WORD_PATTERN, (_, charset, encoding, encoded) => {\n try {\n if (encoding.toUpperCase() === 'Q') {\n return this.decodeQuotedPrintable(encoded);\n } else if (encoding.toUpperCase() === 'B') {\n return this.decodeBase64(encoded);\n }\n return encoded;\n } catch {\n return encoded;\n }\n });\n }\n\n private decodeQuotedPrintable(encoded: string): string {\n // RFC 2047: underscores represent spaces in encoded-word\n let decoded = encoded.replace(/_/g, ' ');\n decoded = decoded.replace(/=([0-9A-Fa-f]{2})/g, (_, hex) => \n String.fromCharCode(parseInt(hex, 16))\n );\n return decoded;\n }\n\n private decodeBase64(encoded: string): string {\n return Buffer.from(encoded, 'base64').toString('utf-8');\n }\n\n private extractEmailAddress(headerValue: string): string {\n if (!headerValue) return '';\n const decoded = this.decodeHeader(headerValue);\n const bracketMatch = decoded.match(/<([^>]+)>/);\n if (bracketMatch) return bracketMatch[1].trim().toLowerCase();\n const emailMatch = decoded.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/);\n return emailMatch ? emailMatch[0].toLowerCase() : decoded.trim().toLowerCase();\n }\n\n private extractHeaderEmails(headerValue?: string): string[] {\n if (!headerValue) return [];\n const decoded = this.decodeHeader(headerValue);\n const matches = decoded.match(EMAIL_PATTERN);\n return matches ? matches.map((match) => match.toLowerCase()) : [];\n }\n\n private extractMessageId(headerValue: string): string {\n if (!headerValue) return `<generated-${Date.now()}@relay-temp-mail>`;\n const cleaned = headerValue.replace(/[<>]/g, '').trim();\n return `<${cleaned}>`;\n }\n}\n","import { HttpClient } from './http';\nimport type { AliasProvider, RelayAlias } from './types';\n\ninterface RawAliasResponse {\n id: number;\n address: string;\n full_address: string;\n enabled: boolean;\n created_at: string;\n domain: number;\n mask_type: string;\n description?: string;\n num_forwarded?: number;\n num_blocked?: number;\n last_modified_at?: string;\n last_used_at?: string | null;\n num_level_one_trackers_blocked?: number;\n num_replied?: number;\n num_spam?: number;\n block_list_emails?: boolean;\n generated_for?: string;\n used_on?: string | null;\n}\n\nexport class FirefoxRelayProvider implements AliasProvider {\n private csrfToken: string;\n private sessionId: string;\n private httpClient: HttpClient;\n\n constructor(\n csrfToken: string,\n sessionId: string,\n httpClient?: HttpClient\n ) {\n this.csrfToken = csrfToken;\n this.sessionId = sessionId;\n this.httpClient = httpClient ?? new HttpClient('https://relay.firefox.com');\n }\n\n private getAuthHeaders(): Record<string, string> {\n return {\n 'Origin': 'https://relay.firefox.com',\n 'Referer': 'https://relay.firefox.com/accounts/profile/?',\n 'Accept': 'application/json',\n 'X-CSRFToken': this.csrfToken,\n 'Cookie': `sessionid=${this.sessionId}; csrftoken=${this.csrfToken}`,\n };\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n const response = await this.httpClient.request<RawAliasResponse[]>(\n 'GET',\n '/api/v1/relayaddresses/',\n { headers: this.getAuthHeaders() }\n );\n\n return response.map((item) => this.mapAliasResponse(item));\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response = await this.httpClient.request<RawAliasResponse>(\n 'POST',\n '/api/v1/relayaddresses/',\n {\n headers: this.getAuthHeaders(),\n body: { enabled: true },\n }\n );\n\n return this.mapAliasResponse(response);\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.httpClient.request<void>(\n 'DELETE',\n `/api/v1/relayaddresses/${id}/`,\n { headers: this.getAuthHeaders() }\n );\n }\n\n private mapAliasResponse(data: RawAliasResponse): RelayAlias {\n return {\n id: data.id,\n address: data.address,\n fullAddress: data.full_address,\n enabled: data.enabled,\n createdAt: data.created_at,\n domain: data.domain,\n maskType: data.mask_type,\n description: data.description,\n numForwarded: data.num_forwarded,\n numBlocked: data.num_blocked,\n lastModifiedAt: data.last_modified_at,\n lastUsedAt: data.last_used_at,\n numLevelOneTrackersBlocked: data.num_level_one_trackers_blocked,\n numReplied: data.num_replied,\n numSpam: data.num_spam,\n blockListEmails: data.block_list_emails,\n generatedFor: data.generated_for,\n usedOn: data.used_on,\n };\n }\n}\n\n/** @deprecated Use FirefoxRelayProvider instead */\nexport const RelayAPIClient = FirefoxRelayProvider;\n","import { CFTempMailProvider, DefaultHttpClient } from './cf-api.js';\nimport { DuckDuckGoEmailProvider } from './duckduckgo-api.js';\nimport { EmailParser } from './parser.js';\nimport { FirefoxRelayProvider } from './relay-api.js';\nimport { HttpClient } from './http.js';\nimport type {\n TempMailConfig,\n RelayConfig,\n AliasProvider,\n MailProvider,\n RelayAlias,\n ParsedEmail,\n GetEmailsOptions,\n} from './types.js';\n\nfunction createAliasProvider(config: TempMailConfig, httpClient: HttpClient): AliasProvider {\n const aliasConfig = config.aliasProvider;\n switch (aliasConfig.type) {\n case 'firefox-relay':\n return new FirefoxRelayProvider(\n aliasConfig.csrfToken,\n aliasConfig.sessionId,\n httpClient\n );\n case 'duckduckgo-email':\n return new DuckDuckGoEmailProvider(\n aliasConfig.jwtToken,\n aliasConfig.store\n );\n }\n}\n\nfunction createMailProvider(config: TempMailConfig): MailProvider {\n const mailConfig = config.mailProvider;\n switch (mailConfig.type) {\n case 'cf-temp-mail':\n return new CFTempMailProvider(\n mailConfig.apiUrl,\n mailConfig.token\n );\n }\n}\n\nexport class TempMailClient {\n private readonly aliasProvider: AliasProvider;\n private readonly mailProvider: MailProvider;\n private readonly parser: EmailParser;\n\n constructor(config: TempMailConfig) {\n const timeout = config.timeout ?? 30000;\n const httpClient = new HttpClient('https://relay.firefox.com', timeout);\n this.aliasProvider = createAliasProvider(config, httpClient);\n this.mailProvider = createMailProvider(config);\n this.parser = new EmailParser();\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.aliasProvider.listAliases();\n }\n\n async createAlias(): Promise<RelayAlias> {\n return this.aliasProvider.createAlias();\n }\n\n async deleteAlias(id: number): Promise<void> {\n return this.aliasProvider.deleteAlias(id);\n }\n\n async getEmails(\n aliasAddress?: string,\n options?: GetEmailsOptions\n ): Promise<ParsedEmail[]> {\n const limit = options?.limit ?? 20;\n const offset = options?.offset ?? 0;\n\n const emails = await this.mailProvider.getMails(limit, offset);\n\n const parsedEmails: ParsedEmail[] = emails.map((email) => {\n const parsed = this.parser.parseEmail(email.raw);\n return {\n ...parsed,\n id: email.id,\n messageId: email.messageId,\n source: email.source,\n address: email.address,\n createdAt: email.createdAt,\n metadata: email.metadata,\n };\n });\n\n if (aliasAddress) {\n const normalizedAlias = aliasAddress.toLowerCase();\n return parsedEmails.filter(\n (email) =>\n email.relayAlias?.toLowerCase() === normalizedAlias ||\n email.address.toLowerCase() === normalizedAlias\n );\n }\n\n return parsedEmails;\n }\n}\n\n/** @deprecated Use TempMailClient instead */\nexport const RelayClient = TempMailClient;\n"],"mappings":"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","names":["duckAddress"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/cf-api.ts","../src/http.ts","../src/duckduckgo-api.ts","../src/parser.ts","../src/relay-api.ts","../src/client.ts"],"sourcesContent":["/**\n * Custom error classes for the relay-temp-mail package.\n *\n * These errors provide structured error information including error codes,\n * HTTP status codes, and response data for better error handling.\n */\n\n/**\n * Base error class for all relay-temp-mail errors.\n *\n * Extends the built-in Error class with additional context about the error,\n * including an error code for programmatic error handling and optional\n * response data from the API.\n */\nexport class RelayTempMailError extends Error {\n /**\n * Machine-readable error code for programmatic error handling.\n * Examples: 'NETWORK_ERROR', 'AUTH_ERROR', 'NOT_FOUND'\n */\n code: string;\n\n /**\n * HTTP status code associated with this error, if applicable.\n */\n statusCode?: number;\n\n /**\n * Raw response data from the API, if available.\n */\n response?: any;\n\n /**\n * Creates a new RelayTempMailError instance.\n *\n * @param message - Human-readable error message describing the error.\n * @param code - Machine-readable error code (e.g., 'UNKNOWN_ERROR').\n * @param statusCode - Optional HTTP status code associated with the error.\n * @param response - Optional raw response data from the API.\n */\n constructor(\n message: string,\n code: string,\n statusCode?: number,\n response?: any\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.statusCode = statusCode;\n this.response = response;\n\n // Maintains proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error for network-related failures.\n *\n * Thrown when there is a problem establishing or maintaining a network\n * connection, such as DNS resolution failures, connection timeouts,\n * or network unreachability.\n */\nexport class NetworkError extends RelayTempMailError {\n code = 'NETWORK_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NETWORK_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for authentication and authorization failures.\n *\n * Thrown when API requests fail due to invalid or missing credentials\n * (401) or when the authenticated user lacks permission for the\n * requested operation (403).\n */\nexport class AuthError extends RelayTempMailError {\n code = 'AUTH_ERROR' as const;\n\n constructor(message: string, statusCode?: number, response?: any) {\n super(message, 'AUTH_ERROR', statusCode, response);\n }\n}\n\n/**\n * Error for resource not found errors.\n *\n * Thrown when the requested resource does not exist (404 response),\n * such as when trying to access a non-existent alias or email.\n */\nexport class NotFoundError extends RelayTempMailError {\n code = 'NOT_FOUND' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'NOT_FOUND', 404, response);\n }\n}\n\n/**\n * Error for MIME message parsing failures.\n *\n * Thrown when there is an error parsing email MIME content,\n * such as malformed headers or invalid message structure.\n */\nexport class ParseError extends RelayTempMailError {\n code = 'PARSE_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'PARSE_ERROR', undefined, response);\n }\n}\n\n/**\n * Error for rate limiting responses.\n *\n * Thrown when the API rate limit has been exceeded (429 response).\n * The client should wait and retry the request after the indicated\n * cooldown period.\n */\nexport class RateLimitError extends RelayTempMailError {\n code = 'RATE_LIMIT_ERROR' as const;\n\n constructor(message: string, response?: any) {\n super(message, 'RATE_LIMIT_ERROR', 429, response);\n }\n}\n","import type { MailProvider, Email } from './types.js';\nimport { AuthError, NetworkError, NotFoundError, RateLimitError, RelayTempMailError } from './errors.js';\n\ninterface CFRawEmail {\n id: number;\n message_id: string;\n source: string;\n address: string;\n raw: string;\n metadata: any | null;\n created_at: string;\n}\n\ninterface CFRawResponse {\n results: CFRawEmail[];\n count: number;\n}\n\nexport class CFTempMailProvider implements MailProvider {\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly httpClient: HttpClient;\n\n constructor(apiUrl: string, token: string, httpClient?: HttpClient) {\n this.apiUrl = apiUrl.replace(/\\/+$/, '');\n this.token = token;\n this.httpClient = httpClient ?? new DefaultHttpClient();\n }\n\n async getMails(limit: number = 20, offset: number = 0): Promise<Email[]> {\n const url = new URL(`${this.apiUrl}/api/mails`);\n url.searchParams.set('limit', String(limit));\n url.searchParams.set('offset', String(offset));\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.token}`,\n };\n\n try {\n const response = await this.httpClient.get(url.toString(), { headers });\n return this.mapCFResponse(response as CFRawResponse);\n } catch (error) {\n throw this.handleError(error);\n }\n }\n\n private mapCFResponse(response: CFRawResponse): Email[] {\n return response.results.map((item): Email => ({\n id: item.id,\n messageId: item.message_id,\n source: item.source,\n address: item.address,\n raw: item.raw,\n metadata: item.metadata,\n createdAt: item.created_at,\n }));\n }\n\n private handleError(error: unknown): RelayTempMailError {\n if (error instanceof RelayTempMailError) {\n const statusCode = error.statusCode;\n\n if (statusCode === 401 || statusCode === 403) {\n return new AuthError(error.message, statusCode, error.response);\n }\n if (statusCode === 404) {\n return new NotFoundError(error.message, error.response);\n }\n if (statusCode === 429) {\n return new RateLimitError(error.message, error.response);\n }\n\n return error;\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError(error.message);\n }\n\n if (error instanceof Error) {\n return new NetworkError(error.message);\n }\n\n return new RelayTempMailError(\n 'Unknown error occurred',\n 'UNKNOWN_ERROR',\n undefined,\n error\n );\n }\n}\n\n/** @deprecated Use CFTempMailProvider instead */\nexport const CFEmailClient = CFTempMailProvider;\n\nexport interface HttpClient {\n get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown>;\n}\n\nexport class DefaultHttpClient implements HttpClient {\n async get(url: string, options?: { headers?: Record<string, string> }): Promise<unknown> {\n const response = await fetch(url, {\n method: 'GET',\n headers: options?.headers,\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw new RelayTempMailError(\n `HTTP ${response.status}: ${errorBody}`,\n 'HTTP_ERROR',\n response.status,\n errorBody\n );\n }\n\n return response.json();\n }\n}\n","/**\n * HTTP client utilities for the relay-temp-mail package.\n *\n * This module provides a configurable HTTP client with timeout support,\n * automatic retry logic, and proper error classification for API responses.\n */\n\nimport {\n RelayTempMailError,\n NetworkError,\n AuthError,\n NotFoundError,\n RateLimitError,\n} from './errors';\n\n/**\n * Options for individual HTTP requests.\n */\nexport interface RequestOptions {\n /** Custom headers to include in the request */\n headers?: Record<string, string>;\n\n /** Request body (will be JSON serialized) */\n body?: unknown;\n\n /** Request timeout in milliseconds (overrides client default) */\n timeout?: number;\n\n /** Number of retries on failure (overrides client default) */\n retries?: number;\n}\n\n/**\n * HTTP client for making requests to the relay-temp-mail API.\n *\n * Provides a configurable base URL with timeout, retry, and automatic\n * JSON parsing capabilities.\n */\nexport class HttpClient {\n private baseUrl: string;\n private defaultTimeout: number;\n private defaultRetries: number;\n\n /**\n * Creates a new HttpClient instance.\n *\n * @param baseUrl - Base URL for all requests (e.g., 'https://api.example.com')\n * @param defaultTimeout - Default timeout in milliseconds (default: 30000)\n * @param defaultRetries - Default number of retries on failure (default: 0)\n */\n constructor(\n baseUrl: string,\n defaultTimeout: number = 30000,\n defaultRetries: number = 0\n ) {\n this.baseUrl = baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.defaultTimeout = defaultTimeout;\n this.defaultRetries = defaultRetries;\n }\n\n /**\n * Makes an HTTP request to the specified path.\n *\n * @param method - HTTP method (GET, POST, PUT, DELETE, etc.)\n * @param path - API path (will be appended to baseUrl)\n * @param options - Optional request configuration\n * @returns Promise resolving to the parsed JSON response\n */\n async request<T>(\n method: string,\n path: string,\n options: RequestOptions = {}\n ): Promise<T> {\n const timeout = options.timeout ?? this.defaultTimeout;\n const retries = options.retries ?? this.defaultRetries;\n\n let lastError: RelayTempMailError | Error | undefined;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const response = await this.executeRequest(method, path, options, timeout);\n return await this.handleResponse<T>(response);\n } catch (error) {\n lastError = error as Error;\n\n // Check if we should retry\n if (attempt < retries && this.shouldRetry(error)) {\n const delay = 1000 * Math.pow(2, attempt);\n await this.sleep(delay);\n continue;\n }\n\n // Don't retry, throw the classified error\n if (error instanceof RelayTempMailError) {\n throw error;\n }\n\n // Classify the error if not already classified\n throw this.classifyError(error);\n }\n }\n\n // This should never be reached, but just in case\n throw lastError || new NetworkError('Request failed');\n }\n\n /**\n * Executes the actual HTTP request with timeout support.\n */\n private async executeRequest(\n method: string,\n path: string,\n options: RequestOptions,\n timeout: number\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const fetchOptions: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n signal: controller.signal,\n };\n\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body);\n }\n\n const response = await fetch(url, fetchOptions);\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Handles the HTTP response, parsing JSON and checking for errors.\n */\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n throw this.classifyError(new Error(`HTTP ${response.status}`), response);\n }\n\n const text = await response.text();\n\n // Handle empty responses\n if (!text) {\n return {} as T;\n }\n\n return JSON.parse(text) as T;\n }\n\n /**\n * Classifies an error based on the error type and HTTP response.\n */\n private classifyError(error: unknown, response?: Response): RelayTempMailError {\n // Network errors (fetch failed)\n if (error instanceof Error && error.name === 'AbortError') {\n return new NetworkError('Request timed out');\n }\n\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return new NetworkError('Network request failed');\n }\n\n if (error instanceof Error && error.message.includes('Failed to fetch')) {\n return new NetworkError('Network request failed');\n }\n\n // HTTP status-based classification\n if (response) {\n const status = response.status;\n\n if (status === 401 || status === 403) {\n return new AuthError(\n `Authentication failed: ${response.statusText}`,\n status\n );\n }\n\n if (status === 404) {\n return new NotFoundError(`Resource not found: ${response.statusText}`);\n }\n\n if (status === 429) {\n return new RateLimitError(\n `Rate limit exceeded: ${response.statusText}`\n );\n }\n\n if (status >= 500) {\n return new NetworkError(\n `Server error: ${response.statusText}`,\n status\n );\n }\n }\n\n // Default error\n if (error instanceof Error) {\n return new RelayTempMailError(\n error.message,\n 'REQUEST_ERROR',\n response?.status\n );\n }\n\n return new RelayTempMailError('Unknown error occurred', 'UNKNOWN_ERROR');\n }\n\n /**\n * Determines if a request should be retried based on the error.\n */\n private shouldRetry(error: unknown): boolean {\n if (error instanceof NetworkError) {\n return true;\n }\n\n if (error instanceof RelayTempMailError && error.statusCode) {\n return error.statusCode >= 500;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n return true;\n }\n if (error instanceof TypeError && error.message.includes('fetch')) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Sleep for a specified duration.\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { HttpClient } from './http';\nimport { RelayTempMailError } from './errors';\nimport type { AliasProvider, RelayAlias, DuckDuckGoAliasStore } from './types';\n\ninterface DuckDuckGoCreateAddressResponse {\n address: string;\n}\n\nexport class InMemoryDuckDuckGoAliasStore implements DuckDuckGoAliasStore {\n private aliases: RelayAlias[] = [];\n\n getAll(): RelayAlias[] {\n return [...this.aliases];\n }\n\n add(alias: RelayAlias): void {\n this.aliases.push(alias);\n }\n\n remove(id: number): void {\n this.aliases = this.aliases.filter((a) => a.id !== id);\n }\n}\n\nexport class DuckDuckGoEmailProvider implements AliasProvider {\n private jwtToken: string;\n private httpClient: HttpClient;\n private store: DuckDuckGoAliasStore;\n private nextId: number;\n\n constructor(\n jwtToken: string,\n store?: DuckDuckGoAliasStore,\n httpClient?: HttpClient\n ) {\n this.jwtToken = jwtToken;\n this.store = store ?? new InMemoryDuckDuckGoAliasStore();\n this.httpClient =\n httpClient ?? new HttpClient('https://quack.duckduckgo.com');\n this.nextId = 1;\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.store.getAll();\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response =\n await this.httpClient.request<DuckDuckGoCreateAddressResponse>(\n 'POST',\n '/api/email/addresses',\n {\n headers: {\n Authorization: `Bearer ${this.jwtToken}`,\n },\n }\n );\n\n const fullAddress = `${response.address}@duck.com`;\n\n const existing = await this.store.getAll();\n if (existing.some((a) => a.fullAddress === fullAddress)) {\n throw new RelayTempMailError(\n `DuckDuckGo returned a duplicate alias: ${fullAddress}`,\n 'DUPLICATE_ALIAS',\n 201\n );\n }\n\n const alias: RelayAlias = {\n id: this.nextId++,\n address: response.address,\n fullAddress,\n enabled: true,\n createdAt: new Date().toISOString(),\n domain: 3,\n maskType: 'random',\n };\n\n await this.store.add(alias);\n return alias;\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.store.remove(id);\n }\n}\n","/**\n * MIME email parser for extracting Firefox Relay alias information.\n */\nimport type { ParsedEmail } from './types.js';\n\nconst EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g;\nconst MOZMAIL_SUFFIX_PATTERN = /@mozmail\\.com$/i;\nconst DUCK_SUFFIX_PATTERN = /@duck\\.com$/i;\n// DuckDuckGo aliases are \"word-word-word@duck.com\"; the From header\n// uses \"sender_at_domain_alias@duck.com\" which EMAIL_PATTERN matches\n// as a single address. This pattern extracts just the alias portion.\nconst DUCK_ALIAS_PATTERN = /([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)+@duck\\.com)/gi;\n// System addresses at @duck.com that are not user aliases\nconst DUCK_SYSTEM_ADDRESSES = new Set(['support@duck.com', 'noreply@duck.com']);\nconst ENCODED_WORD_PATTERN = /=\\?([^?]+)\\?([BbQq])\\?([^?]*)\\?=/g;\n\n/**\n * EmailParser class for parsing MIME email content.\n */\nexport class EmailParser {\n parseEmail(raw: string): ParsedEmail {\n const headers = this.parseHeaders(raw);\n const toHeader = headers.get('to') || '';\n const fromHeader = headers.get('from') || '';\n const messageIdHeader = headers.get('message-id') || '';\n const relayAlias = this.extractRelayAlias(raw);\n \n return {\n id: 0,\n messageId: this.extractMessageId(messageIdHeader),\n source: this.extractEmailAddress(fromHeader),\n address: this.extractEmailAddress(toHeader),\n raw,\n metadata: null,\n createdAt: new Date().toISOString(),\n relayAlias: relayAlias || undefined,\n };\n }\n\n extractRelayAlias(raw: string): string | null {\n try {\n const headers = this.parseHeaders(raw);\n\n // DuckDuckGo Email Protection adds a Duck-Original-To header\n // containing the @duck.com alias the email was forwarded to\n const duckOriginalTo = headers.get('duck-original-to');\n if (duckOriginalTo) {\n const duckAddress = this.extractEmailAddress(duckOriginalTo);\n if (duckAddress && DUCK_SUFFIX_PATTERN.test(duckAddress)) {\n return duckAddress;\n }\n }\n\n // Search the full raw content for @duck.com addresses.\n // Duck-Original-To may be stripped during forwarding,\n // but the alias address often appears in From headers as\n // \"sender_at_domain_alias@duck.com\" or elsewhere in the MIME.\n // First try the precise pattern (hyphenated aliases like word-word-word@duck.com)\n const duckMatches = raw.match(DUCK_ALIAS_PATTERN);\n if (duckMatches && duckMatches.length > 0) {\n return duckMatches[0].toLowerCase();\n }\n // Fallback: search with broader EMAIL_PATTERN and filter for @duck.com,\n // excluding known system addresses like support@duck.com\n const rawEmails = raw.match(EMAIL_PATTERN) ?? [];\n const duckFallback = rawEmails.find(\n (e) => DUCK_SUFFIX_PATTERN.test(e) && !DUCK_SYSTEM_ADDRESSES.has(e.toLowerCase())\n );\n if (duckFallback) return duckFallback.toLowerCase();\n\n const fromAddresses = this.extractHeaderEmails(headers.get('from'));\n const toAddresses = this.extractHeaderEmails(headers.get('to'));\n const allAddresses = [...fromAddresses, ...toAddresses];\n\n const mozmailAddress = allAddresses.find((address) =>\n MOZMAIL_SUFFIX_PATTERN.test(address)\n );\n if (mozmailAddress) return mozmailAddress;\n\n return toAddresses[0] ?? null;\n } catch {\n return null;\n }\n }\n\n private parseHeaders(raw: string): Map<string, string> {\n const headers = new Map<string, string>();\n const headerEnd = raw.indexOf('\\r\\n\\r\\n');\n const headerSection = headerEnd === -1 ? raw : raw.substring(0, headerEnd);\n const lines = headerSection.split(/\\r?\\n/);\n let currentHeader: string | null = null;\n let currentValue = '';\n \n for (const line of lines) {\n if (/^\\s/.test(line)) {\n if (currentHeader) currentValue += ' ' + line.trim();\n } else {\n if (currentHeader) headers.set(currentHeader, currentValue);\n const colonIndex = line.indexOf(':');\n if (colonIndex > 0) {\n currentHeader = line.substring(0, colonIndex).toLowerCase().trim();\n currentValue = line.substring(colonIndex + 1).trim();\n } else {\n currentHeader = null;\n currentValue = '';\n }\n }\n }\n if (currentHeader) headers.set(currentHeader, currentValue);\n return headers;\n }\n\n private decodeHeader(value: string): string {\n return value.replace(ENCODED_WORD_PATTERN, (_, charset, encoding, encoded) => {\n try {\n if (encoding.toUpperCase() === 'Q') {\n return this.decodeQuotedPrintable(encoded);\n } else if (encoding.toUpperCase() === 'B') {\n return this.decodeBase64(encoded);\n }\n return encoded;\n } catch {\n return encoded;\n }\n });\n }\n\n private decodeQuotedPrintable(encoded: string): string {\n // RFC 2047: underscores represent spaces in encoded-word\n let decoded = encoded.replace(/_/g, ' ');\n decoded = decoded.replace(/=([0-9A-Fa-f]{2})/g, (_, hex) => \n String.fromCharCode(parseInt(hex, 16))\n );\n return decoded;\n }\n\n private decodeBase64(encoded: string): string {\n return Buffer.from(encoded, 'base64').toString('utf-8');\n }\n\n private extractEmailAddress(headerValue: string): string {\n if (!headerValue) return '';\n const decoded = this.decodeHeader(headerValue);\n const bracketMatch = decoded.match(/<([^>]+)>/);\n if (bracketMatch) return bracketMatch[1].trim().toLowerCase();\n const emailMatch = decoded.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/);\n return emailMatch ? emailMatch[0].toLowerCase() : decoded.trim().toLowerCase();\n }\n\n private extractHeaderEmails(headerValue?: string): string[] {\n if (!headerValue) return [];\n const decoded = this.decodeHeader(headerValue);\n const matches = decoded.match(EMAIL_PATTERN);\n return matches ? matches.map((match) => match.toLowerCase()) : [];\n }\n\n private extractMessageId(headerValue: string): string {\n if (!headerValue) return `<generated-${Date.now()}@relay-temp-mail>`;\n const cleaned = headerValue.replace(/[<>]/g, '').trim();\n return `<${cleaned}>`;\n }\n}\n","import { HttpClient } from './http';\nimport type { AliasProvider, RelayAlias } from './types';\n\ninterface RawAliasResponse {\n id: number;\n address: string;\n full_address: string;\n enabled: boolean;\n created_at: string;\n domain: number;\n mask_type: string;\n description?: string;\n num_forwarded?: number;\n num_blocked?: number;\n last_modified_at?: string;\n last_used_at?: string | null;\n num_level_one_trackers_blocked?: number;\n num_replied?: number;\n num_spam?: number;\n block_list_emails?: boolean;\n generated_for?: string;\n used_on?: string | null;\n}\n\nexport class FirefoxRelayProvider implements AliasProvider {\n private csrfToken: string;\n private sessionId: string;\n private httpClient: HttpClient;\n\n constructor(\n csrfToken: string,\n sessionId: string,\n httpClient?: HttpClient\n ) {\n this.csrfToken = csrfToken;\n this.sessionId = sessionId;\n this.httpClient = httpClient ?? new HttpClient('https://relay.firefox.com');\n }\n\n private getAuthHeaders(): Record<string, string> {\n return {\n 'Origin': 'https://relay.firefox.com',\n 'Referer': 'https://relay.firefox.com/accounts/profile/?',\n 'Accept': 'application/json',\n 'X-CSRFToken': this.csrfToken,\n 'Cookie': `sessionid=${this.sessionId}; csrftoken=${this.csrfToken}`,\n };\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n const response = await this.httpClient.request<RawAliasResponse[]>(\n 'GET',\n '/api/v1/relayaddresses/',\n { headers: this.getAuthHeaders() }\n );\n\n return response.map((item) => this.mapAliasResponse(item));\n }\n\n async createAlias(): Promise<RelayAlias> {\n const response = await this.httpClient.request<RawAliasResponse>(\n 'POST',\n '/api/v1/relayaddresses/',\n {\n headers: this.getAuthHeaders(),\n body: { enabled: true },\n }\n );\n\n return this.mapAliasResponse(response);\n }\n\n async deleteAlias(id: number): Promise<void> {\n await this.httpClient.request<void>(\n 'DELETE',\n `/api/v1/relayaddresses/${id}/`,\n { headers: this.getAuthHeaders() }\n );\n }\n\n private mapAliasResponse(data: RawAliasResponse): RelayAlias {\n return {\n id: data.id,\n address: data.address,\n fullAddress: data.full_address,\n enabled: data.enabled,\n createdAt: data.created_at,\n domain: data.domain,\n maskType: data.mask_type,\n description: data.description,\n numForwarded: data.num_forwarded,\n numBlocked: data.num_blocked,\n lastModifiedAt: data.last_modified_at,\n lastUsedAt: data.last_used_at,\n numLevelOneTrackersBlocked: data.num_level_one_trackers_blocked,\n numReplied: data.num_replied,\n numSpam: data.num_spam,\n blockListEmails: data.block_list_emails,\n generatedFor: data.generated_for,\n usedOn: data.used_on,\n };\n }\n}\n\n/** @deprecated Use FirefoxRelayProvider instead */\nexport const RelayAPIClient = FirefoxRelayProvider;\n","import { CFTempMailProvider, DefaultHttpClient } from './cf-api.js';\nimport { DuckDuckGoEmailProvider } from './duckduckgo-api.js';\nimport { EmailParser } from './parser.js';\nimport { FirefoxRelayProvider } from './relay-api.js';\nimport { HttpClient } from './http.js';\nimport type {\n TempMailConfig,\n RelayConfig,\n AliasProvider,\n MailProvider,\n RelayAlias,\n ParsedEmail,\n GetEmailsOptions,\n} from './types.js';\n\nfunction createAliasProvider(config: TempMailConfig, httpClient: HttpClient): AliasProvider {\n const aliasConfig = config.aliasProvider;\n switch (aliasConfig.type) {\n case 'firefox-relay':\n return new FirefoxRelayProvider(\n aliasConfig.csrfToken,\n aliasConfig.sessionId,\n httpClient\n );\n case 'duckduckgo-email':\n return new DuckDuckGoEmailProvider(\n aliasConfig.jwtToken,\n aliasConfig.store\n );\n }\n}\n\nfunction createMailProvider(config: TempMailConfig): MailProvider {\n const mailConfig = config.mailProvider;\n switch (mailConfig.type) {\n case 'cf-temp-mail':\n return new CFTempMailProvider(\n mailConfig.apiUrl,\n mailConfig.token\n );\n }\n}\n\nexport class TempMailClient {\n private readonly aliasProvider: AliasProvider;\n private readonly mailProvider: MailProvider;\n private readonly parser: EmailParser;\n\n constructor(config: TempMailConfig) {\n const timeout = config.timeout ?? 30000;\n const httpClient = new HttpClient('https://relay.firefox.com', timeout);\n this.aliasProvider = createAliasProvider(config, httpClient);\n this.mailProvider = createMailProvider(config);\n this.parser = new EmailParser();\n }\n\n async listAliases(): Promise<RelayAlias[]> {\n return this.aliasProvider.listAliases();\n }\n\n async createAlias(): Promise<RelayAlias> {\n return this.aliasProvider.createAlias();\n }\n\n async deleteAlias(id: number): Promise<void> {\n return this.aliasProvider.deleteAlias(id);\n }\n\n async getEmails(\n aliasAddress?: string,\n options?: GetEmailsOptions\n ): Promise<ParsedEmail[]> {\n const limit = options?.limit ?? 20;\n const offset = options?.offset ?? 0;\n\n const emails = await this.mailProvider.getMails(limit, offset);\n\n const parsedEmails: ParsedEmail[] = emails.map((email) => {\n const parsed = this.parser.parseEmail(email.raw);\n return {\n ...parsed,\n id: email.id,\n messageId: email.messageId,\n source: email.source,\n address: email.address,\n createdAt: email.createdAt,\n metadata: email.metadata,\n };\n });\n\n if (aliasAddress) {\n const normalizedAlias = aliasAddress.toLowerCase();\n return parsedEmails.filter(\n (email) =>\n email.relayAlias?.toLowerCase() === normalizedAlias ||\n email.address.toLowerCase() === normalizedAlias\n );\n }\n\n return parsedEmails;\n }\n}\n\n/** @deprecated Use TempMailClient instead */\nexport const RelayClient = TempMailClient;\n"],"mappings":";AAcO,IAAM,qBAAN,cAAiC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyB5C,YACE,SACA,MACA,YACA,UACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO,KAAK,YAAY;AAC7B,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,WAAW;AAGhB,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,IAChD;AAAA,EACF;AACF;AASO,IAAM,eAAN,cAA2B,mBAAmB;AAAA,EAGnD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,iBAAiB,QAAW,QAAQ;AAHrD,gBAAO;AAAA,EAIP;AACF;AASO,IAAM,YAAN,cAAwB,mBAAmB;AAAA,EAGhD,YAAY,SAAiB,YAAqB,UAAgB;AAChE,UAAM,SAAS,cAAc,YAAY,QAAQ;AAHnD,gBAAO;AAAA,EAIP;AACF;AAQO,IAAM,gBAAN,cAA4B,mBAAmB;AAAA,EAGpD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,aAAa,KAAK,QAAQ;AAH3C,gBAAO;AAAA,EAIP;AACF;AAQO,IAAM,aAAN,cAAyB,mBAAmB;AAAA,EAGjD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,eAAe,QAAW,QAAQ;AAHnD,gBAAO;AAAA,EAIP;AACF;AASO,IAAM,iBAAN,cAA6B,mBAAmB;AAAA,EAGrD,YAAY,SAAiB,UAAgB;AAC3C,UAAM,SAAS,oBAAoB,KAAK,QAAQ;AAHlD,gBAAO;AAAA,EAIP;AACF;;;AC/GO,IAAM,qBAAN,MAAiD;AAAA,EAKtD,YAAY,QAAgB,OAAe,YAAyB;AAClE,SAAK,SAAS,OAAO,QAAQ,QAAQ,EAAE;AACvC,SAAK,QAAQ;AACb,SAAK,aAAa,cAAc,IAAI,kBAAkB;AAAA,EACxD;AAAA,EAEA,MAAM,SAAS,QAAgB,IAAI,SAAiB,GAAqB;AACvE,UAAM,MAAM,IAAI,IAAI,GAAG,KAAK,MAAM,YAAY;AAC9C,QAAI,aAAa,IAAI,SAAS,OAAO,KAAK,CAAC;AAC3C,QAAI,aAAa,IAAI,UAAU,OAAO,MAAM,CAAC;AAE7C,UAAM,UAAkC;AAAA,MACtC,iBAAiB,UAAU,KAAK,KAAK;AAAA,IACvC;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW,IAAI,IAAI,SAAS,GAAG,EAAE,QAAQ,CAAC;AACtE,aAAO,KAAK,cAAc,QAAyB;AAAA,IACrD,SAAS,OAAO;AACd,YAAM,KAAK,YAAY,KAAK;AAAA,IAC9B;AAAA,EACF;AAAA,EAEQ,cAAc,UAAkC;AACtD,WAAO,SAAS,QAAQ,IAAI,CAAC,UAAiB;AAAA,MAC5C,IAAI,KAAK;AAAA,MACT,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,KAAK,KAAK;AAAA,MACV,UAAU,KAAK;AAAA,MACf,WAAW,KAAK;AAAA,IAClB,EAAE;AAAA,EACJ;AAAA,EAEQ,YAAY,OAAoC;AACtD,QAAI,iBAAiB,oBAAoB;AACvC,YAAM,aAAa,MAAM;AAEzB,UAAI,eAAe,OAAO,eAAe,KAAK;AAC5C,eAAO,IAAI,UAAU,MAAM,SAAS,YAAY,MAAM,QAAQ;AAAA,MAChE;AACA,UAAI,eAAe,KAAK;AACtB,eAAO,IAAI,cAAc,MAAM,SAAS,MAAM,QAAQ;AAAA,MACxD;AACA,UAAI,eAAe,KAAK;AACtB,eAAO,IAAI,eAAe,MAAM,SAAS,MAAM,QAAQ;AAAA,MACzD;AAEA,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,aAAa,MAAM,QAAQ,SAAS,OAAO,GAAG;AACjE,aAAO,IAAI,aAAa,MAAM,OAAO;AAAA,IACvC;AAEA,QAAI,iBAAiB,OAAO;AAC1B,aAAO,IAAI,aAAa,MAAM,OAAO;AAAA,IACvC;AAEA,WAAO,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,gBAAgB;AAMtB,IAAM,oBAAN,MAA8C;AAAA,EACnD,MAAM,IAAI,KAAa,SAAkE;AACvF,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,SAAS;AAAA,IACpB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,YAAM,IAAI;AAAA,QACR,QAAQ,SAAS,MAAM,KAAK,SAAS;AAAA,QACrC;AAAA,QACA,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AACF;;;AChFO,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYtB,YACE,SACA,iBAAyB,KACzB,iBAAyB,GACzB;AACA,SAAK,UAAU,QAAQ,QAAQ,OAAO,EAAE;AACxC,SAAK,iBAAiB;AACtB,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QACJ,QACA,MACA,UAA0B,CAAC,GACf;AACZ,UAAM,UAAU,QAAQ,WAAW,KAAK;AACxC,UAAM,UAAU,QAAQ,WAAW,KAAK;AAExC,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,SAAS,WAAW;AACnD,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,eAAe,QAAQ,MAAM,SAAS,OAAO;AACzE,eAAO,MAAM,KAAK,eAAkB,QAAQ;AAAA,MAC9C,SAAS,OAAO;AACd,oBAAY;AAGZ,YAAI,UAAU,WAAW,KAAK,YAAY,KAAK,GAAG;AAChD,gBAAM,QAAQ,MAAO,KAAK,IAAI,GAAG,OAAO;AACxC,gBAAM,KAAK,MAAM,KAAK;AACtB;AAAA,QACF;AAGA,YAAI,iBAAiB,oBAAoB;AACvC,gBAAM;AAAA,QACR;AAGA,cAAM,KAAK,cAAc,KAAK;AAAA,MAChC;AAAA,IACF;AAGA,UAAM,aAAa,IAAI,aAAa,gBAAgB;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,QACA,MACA,SACA,SACmB;AACnB,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAElC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,OAAO;AAE9D,QAAI;AACF,YAAM,eAA4B;AAAA,QAChC;AAAA,QACA,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,GAAG,QAAQ;AAAA,QACb;AAAA,QACA,QAAQ,WAAW;AAAA,MACrB;AAEA,UAAI,QAAQ,SAAS,QAAW;AAC9B,qBAAa,OAAO,KAAK,UAAU,QAAQ,IAAI;AAAA,MACjD;AAEA,YAAM,WAAW,MAAM,MAAM,KAAK,YAAY;AAC9C,aAAO;AAAA,IACT,UAAE;AACA,mBAAa,SAAS;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAkB,UAAgC;AAC9D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,KAAK,cAAc,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE,GAAG,QAAQ;AAAA,IACzE;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,QAAI,CAAC,MAAM;AACT,aAAO,CAAC;AAAA,IACV;AAEA,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,OAAgB,UAAyC;AAE7E,QAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,aAAO,IAAI,aAAa,mBAAmB;AAAA,IAC7C;AAEA,QAAI,iBAAiB,aAAa,MAAM,QAAQ,SAAS,OAAO,GAAG;AACjE,aAAO,IAAI,aAAa,wBAAwB;AAAA,IAClD;AAEA,QAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,iBAAiB,GAAG;AACvE,aAAO,IAAI,aAAa,wBAAwB;AAAA,IAClD;AAGA,QAAI,UAAU;AACZ,YAAM,SAAS,SAAS;AAExB,UAAI,WAAW,OAAO,WAAW,KAAK;AACpC,eAAO,IAAI;AAAA,UACT,0BAA0B,SAAS,UAAU;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAEA,UAAI,WAAW,KAAK;AAClB,eAAO,IAAI,cAAc,uBAAuB,SAAS,UAAU,EAAE;AAAA,MACvE;AAEA,UAAI,WAAW,KAAK;AAClB,eAAO,IAAI;AAAA,UACT,wBAAwB,SAAS,UAAU;AAAA,QAC7C;AAAA,MACF;AAEA,UAAI,UAAU,KAAK;AACjB,eAAO,IAAI;AAAA,UACT,iBAAiB,SAAS,UAAU;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,iBAAiB,OAAO;AAC1B,aAAO,IAAI;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,IAAI,mBAAmB,0BAA0B,eAAe;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,OAAyB;AAC3C,QAAI,iBAAiB,cAAc;AACjC,aAAO;AAAA,IACT;AAEA,QAAI,iBAAiB,sBAAsB,MAAM,YAAY;AAC3D,aAAO,MAAM,cAAc;AAAA,IAC7B;AAEA,QAAI,iBAAiB,OAAO;AAC1B,UAAI,MAAM,SAAS,cAAc;AAC/B,eAAO;AAAA,MACT;AACA,UAAI,iBAAiB,aAAa,MAAM,QAAQ,SAAS,OAAO,GAAG;AACjE,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AACF;;;AC/OO,IAAM,+BAAN,MAAmE;AAAA,EAAnE;AACL,SAAQ,UAAwB,CAAC;AAAA;AAAA,EAEjC,SAAuB;AACrB,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB;AAAA,EAEA,IAAI,OAAyB;AAC3B,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,UAAU,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,EACvD;AACF;AAEO,IAAM,0BAAN,MAAuD;AAAA,EAM5D,YACE,UACA,OACA,YACA;AACA,SAAK,WAAW;AAChB,SAAK,QAAQ,SAAS,IAAI,6BAA6B;AACvD,SAAK,aACH,cAAc,IAAI,WAAW,8BAA8B;AAC7D,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,cAAqC;AACzC,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B;AAAA,EAEA,MAAM,cAAmC;AACvC,UAAM,WACJ,MAAM,KAAK,WAAW;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS;AAAA,UACP,eAAe,UAAU,KAAK,QAAQ;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAEF,UAAM,cAAc,GAAG,SAAS,OAAO;AAEvC,UAAM,WAAW,MAAM,KAAK,MAAM,OAAO;AACzC,QAAI,SAAS,KAAK,CAAC,MAAM,EAAE,gBAAgB,WAAW,GAAG;AACvD,YAAM,IAAI;AAAA,QACR,0CAA0C,WAAW;AAAA,QACrD;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAoB;AAAA,MACxB,IAAI,KAAK;AAAA,MACT,SAAS,SAAS;AAAA,MAClB;AAAA,MACA,SAAS;AAAA,MACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAEA,UAAM,KAAK,MAAM,IAAI,KAAK;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,IAA2B;AAC3C,UAAM,KAAK,MAAM,OAAO,EAAE;AAAA,EAC5B;AACF;;;ACjFA,IAAM,gBAAgB;AACtB,IAAM,yBAAyB;AAC/B,IAAM,sBAAsB;AAI5B,IAAM,qBAAqB;AAE3B,IAAM,wBAAwB,oBAAI,IAAI,CAAC,oBAAoB,kBAAkB,CAAC;AAC9E,IAAM,uBAAuB;AAKtB,IAAM,cAAN,MAAkB;AAAA,EACvB,WAAW,KAA0B;AACnC,UAAM,UAAU,KAAK,aAAa,GAAG;AACrC,UAAM,WAAW,QAAQ,IAAI,IAAI,KAAK;AACtC,UAAM,aAAa,QAAQ,IAAI,MAAM,KAAK;AAC1C,UAAM,kBAAkB,QAAQ,IAAI,YAAY,KAAK;AACrD,UAAM,aAAa,KAAK,kBAAkB,GAAG;AAE7C,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,WAAW,KAAK,iBAAiB,eAAe;AAAA,MAChD,QAAQ,KAAK,oBAAoB,UAAU;AAAA,MAC3C,SAAS,KAAK,oBAAoB,QAAQ;AAAA,MAC1C;AAAA,MACA,UAAU;AAAA,MACV,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,YAAY,cAAc;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,kBAAkB,KAA4B;AAC5C,QAAI;AACF,YAAM,UAAU,KAAK,aAAa,GAAG;AAIrC,YAAM,iBAAiB,QAAQ,IAAI,kBAAkB;AACrD,UAAI,gBAAgB;AAClB,cAAM,cAAc,KAAK,oBAAoB,cAAc;AAC3D,YAAI,eAAe,oBAAoB,KAAK,WAAW,GAAG;AACxD,iBAAO;AAAA,QACT;AAAA,MACF;AAOA,YAAM,cAAc,IAAI,MAAM,kBAAkB;AAChD,UAAI,eAAe,YAAY,SAAS,GAAG;AACzC,eAAO,YAAY,CAAC,EAAE,YAAY;AAAA,MACpC;AAGA,YAAM,YAAY,IAAI,MAAM,aAAa,KAAK,CAAC;AAC/C,YAAM,eAAe,UAAU;AAAA,QAC7B,CAAC,MAAM,oBAAoB,KAAK,CAAC,KAAK,CAAC,sBAAsB,IAAI,EAAE,YAAY,CAAC;AAAA,MAClF;AACA,UAAI,aAAc,QAAO,aAAa,YAAY;AAElD,YAAM,gBAAgB,KAAK,oBAAoB,QAAQ,IAAI,MAAM,CAAC;AAClE,YAAM,cAAc,KAAK,oBAAoB,QAAQ,IAAI,IAAI,CAAC;AAC9D,YAAM,eAAe,CAAC,GAAG,eAAe,GAAG,WAAW;AAEtD,YAAM,iBAAiB,aAAa;AAAA,QAAK,CAAC,YACxC,uBAAuB,KAAK,OAAO;AAAA,MACrC;AACA,UAAI,eAAgB,QAAO;AAE3B,aAAO,YAAY,CAAC,KAAK;AAAA,IAC3B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,aAAa,KAAkC;AACrD,UAAM,UAAU,oBAAI,IAAoB;AACxC,UAAM,YAAY,IAAI,QAAQ,UAAU;AACxC,UAAM,gBAAgB,cAAc,KAAK,MAAM,IAAI,UAAU,GAAG,SAAS;AACzE,UAAM,QAAQ,cAAc,MAAM,OAAO;AACzC,QAAI,gBAA+B;AACnC,QAAI,eAAe;AAEnB,eAAW,QAAQ,OAAO;AACxB,UAAI,MAAM,KAAK,IAAI,GAAG;AACpB,YAAI,cAAe,iBAAgB,MAAM,KAAK,KAAK;AAAA,MACrD,OAAO;AACL,YAAI,cAAe,SAAQ,IAAI,eAAe,YAAY;AAC1D,cAAM,aAAa,KAAK,QAAQ,GAAG;AACnC,YAAI,aAAa,GAAG;AAClB,0BAAgB,KAAK,UAAU,GAAG,UAAU,EAAE,YAAY,EAAE,KAAK;AACjE,yBAAe,KAAK,UAAU,aAAa,CAAC,EAAE,KAAK;AAAA,QACrD,OAAO;AACL,0BAAgB;AAChB,yBAAe;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,QAAI,cAAe,SAAQ,IAAI,eAAe,YAAY;AAC1D,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,OAAuB;AAC1C,WAAO,MAAM,QAAQ,sBAAsB,CAAC,GAAG,SAAS,UAAU,YAAY;AAC5E,UAAI;AACF,YAAI,SAAS,YAAY,MAAM,KAAK;AAClC,iBAAO,KAAK,sBAAsB,OAAO;AAAA,QAC3C,WAAW,SAAS,YAAY,MAAM,KAAK;AACzC,iBAAO,KAAK,aAAa,OAAO;AAAA,QAClC;AACA,eAAO;AAAA,MACT,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,sBAAsB,SAAyB;AAErD,QAAI,UAAU,QAAQ,QAAQ,MAAM,GAAG;AACvC,cAAU,QAAQ;AAAA,MAAQ;AAAA,MAAsB,CAAC,GAAG,QAClD,OAAO,aAAa,SAAS,KAAK,EAAE,CAAC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,SAAyB;AAC5C,WAAO,OAAO,KAAK,SAAS,QAAQ,EAAE,SAAS,OAAO;AAAA,EACxD;AAAA,EAEQ,oBAAoB,aAA6B;AACvD,QAAI,CAAC,YAAa,QAAO;AACzB,UAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,UAAM,eAAe,QAAQ,MAAM,WAAW;AAC9C,QAAI,aAAc,QAAO,aAAa,CAAC,EAAE,KAAK,EAAE,YAAY;AAC5D,UAAM,aAAa,QAAQ,MAAM,gDAAgD;AACjF,WAAO,aAAa,WAAW,CAAC,EAAE,YAAY,IAAI,QAAQ,KAAK,EAAE,YAAY;AAAA,EAC/E;AAAA,EAEQ,oBAAoB,aAAgC;AAC1D,QAAI,CAAC,YAAa,QAAO,CAAC;AAC1B,UAAM,UAAU,KAAK,aAAa,WAAW;AAC7C,UAAM,UAAU,QAAQ,MAAM,aAAa;AAC3C,WAAO,UAAU,QAAQ,IAAI,CAAC,UAAU,MAAM,YAAY,CAAC,IAAI,CAAC;AAAA,EAClE;AAAA,EAEQ,iBAAiB,aAA6B;AACpD,QAAI,CAAC,YAAa,QAAO,cAAc,KAAK,IAAI,CAAC;AACjD,UAAM,UAAU,YAAY,QAAQ,SAAS,EAAE,EAAE,KAAK;AACtD,WAAO,IAAI,OAAO;AAAA,EACpB;AACF;;;ACzIO,IAAM,uBAAN,MAAoD;AAAA,EAKzD,YACE,WACA,WACA,YACA;AACA,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,aAAa,cAAc,IAAI,WAAW,2BAA2B;AAAA,EAC5E;AAAA,EAEQ,iBAAyC;AAC/C,WAAO;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,MACV,eAAe,KAAK;AAAA,MACpB,UAAU,aAAa,KAAK,SAAS,eAAe,KAAK,SAAS;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAM,cAAqC;AACzC,UAAM,WAAW,MAAM,KAAK,WAAW;AAAA,MACrC;AAAA,MACA;AAAA,MACA,EAAE,SAAS,KAAK,eAAe,EAAE;AAAA,IACnC;AAEA,WAAO,SAAS,IAAI,CAAC,SAAS,KAAK,iBAAiB,IAAI,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,cAAmC;AACvC,UAAM,WAAW,MAAM,KAAK,WAAW;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS,KAAK,eAAe;AAAA,QAC7B,MAAM,EAAE,SAAS,KAAK;AAAA,MACxB;AAAA,IACF;AAEA,WAAO,KAAK,iBAAiB,QAAQ;AAAA,EACvC;AAAA,EAEA,MAAM,YAAY,IAA2B;AAC3C,UAAM,KAAK,WAAW;AAAA,MACpB;AAAA,MACA,0BAA0B,EAAE;AAAA,MAC5B,EAAE,SAAS,KAAK,eAAe,EAAE;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,iBAAiB,MAAoC;AAC3D,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,SAAS,KAAK;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,aAAa,KAAK;AAAA,MAClB,cAAc,KAAK;AAAA,MACnB,YAAY,KAAK;AAAA,MACjB,gBAAgB,KAAK;AAAA,MACrB,YAAY,KAAK;AAAA,MACjB,4BAA4B,KAAK;AAAA,MACjC,YAAY,KAAK;AAAA,MACjB,SAAS,KAAK;AAAA,MACd,iBAAiB,KAAK;AAAA,MACtB,cAAc,KAAK;AAAA,MACnB,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AACF;AAGO,IAAM,iBAAiB;;;AC1F9B,SAAS,oBAAoB,QAAwB,YAAuC;AAC1F,QAAM,cAAc,OAAO;AAC3B,UAAQ,YAAY,MAAM;AAAA,IACxB,KAAK;AACH,aAAO,IAAI;AAAA,QACT,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF;AAAA,IACF,KAAK;AACH,aAAO,IAAI;AAAA,QACT,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AAAA,EACJ;AACF;AAEA,SAAS,mBAAmB,QAAsC;AAChE,QAAM,aAAa,OAAO;AAC1B,UAAQ,WAAW,MAAM;AAAA,IACvB,KAAK;AACH,aAAO,IAAI;AAAA,QACT,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,EACJ;AACF;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAK1B,YAAY,QAAwB;AAClC,UAAM,UAAU,OAAO,WAAW;AAClC,UAAM,aAAa,IAAI,WAAW,6BAA6B,OAAO;AACtE,SAAK,gBAAgB,oBAAoB,QAAQ,UAAU;AAC3D,SAAK,eAAe,mBAAmB,MAAM;AAC7C,SAAK,SAAS,IAAI,YAAY;AAAA,EAChC;AAAA,EAEA,MAAM,cAAqC;AACzC,WAAO,KAAK,cAAc,YAAY;AAAA,EACxC;AAAA,EAEA,MAAM,cAAmC;AACvC,WAAO,KAAK,cAAc,YAAY;AAAA,EACxC;AAAA,EAEA,MAAM,YAAY,IAA2B;AAC3C,WAAO,KAAK,cAAc,YAAY,EAAE;AAAA,EAC1C;AAAA,EAEA,MAAM,UACJ,cACA,SACwB;AACxB,UAAM,QAAQ,SAAS,SAAS;AAChC,UAAM,SAAS,SAAS,UAAU;AAElC,UAAM,SAAS,MAAM,KAAK,aAAa,SAAS,OAAO,MAAM;AAE7D,UAAM,eAA8B,OAAO,IAAI,CAAC,UAAU;AACxD,YAAM,SAAS,KAAK,OAAO,WAAW,MAAM,GAAG;AAC/C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,IAAI,MAAM;AAAA,QACV,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,SAAS,MAAM;AAAA,QACf,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,MAClB;AAAA,IACF,CAAC;AAED,QAAI,cAAc;AAChB,YAAM,kBAAkB,aAAa,YAAY;AACjD,aAAO,aAAa;AAAA,QAClB,CAAC,UACC,MAAM,YAAY,YAAY,MAAM,mBACpC,MAAM,QAAQ,YAAY,MAAM;AAAA,MACpC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAGO,IAAM,cAAc;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@z_06/relay-temp-mail",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "type": "module",
5
5
  "description": "TypeScript npm package for Firefox Relay + CF temp email API",
6
6
  "main": "./dist/index.cjs",