@z_06/relay-temp-mail 2.1.2 → 2.2.0

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/README.md CHANGED
@@ -59,104 +59,12 @@ const emails = await client.getEmails(alias.fullAddress, { limit: 10 });
59
59
 
60
60
  The library uses two types of providers that can be combined independently:
61
61
 
62
- | Provider Type | Interface | Current Implementations |
62
+ | Provider Type | Interface | Available Providers |
63
63
  |---|---|---|
64
64
  | **Alias Provider** | `AliasProvider` | `firefox-relay`, `duckduckgo-email` |
65
65
  | **Mail Provider** | `MailProvider` | `cf-temp-mail` |
66
66
 
67
- ### Alias Providers
68
-
69
- #### `firefox-relay`
70
-
71
- Manages email aliases through [Firefox Relay](https://relay.firefox.com).
72
-
73
- **Configuration:**
74
-
75
- ```typescript
76
- {
77
- type: 'firefox-relay',
78
- csrfToken: string; // CSRF token from relay.firefox.com cookies
79
- sessionId: string; // Session ID from relay.firefox.com cookies
80
- }
81
- ```
82
-
83
- **Getting your tokens:**
84
-
85
- 1. Login to [relay.firefox.com](https://relay.firefox.com)
86
- 2. Open your browser's developer tools (F12)
87
- 3. Go to the Application/Storage tab
88
- 4. Find Cookies for `relay.firefox.com`
89
- 5. Copy the values for `csrftoken` and `sessionid`
90
-
91
- #### `duckduckgo-email`
92
-
93
- Manages email aliases through [DuckDuckGo Email Protection](https://duckduckgo.com/email/).
94
-
95
- Since the DuckDuckGo API does not provide endpoints for listing or deleting aliases, this provider uses a local store. A default in-memory store is included; implement `DuckDuckGoAliasStore` for custom persistence (e.g., file-based, database).
96
-
97
- **Configuration:**
98
-
99
- ```typescript
100
- {
101
- type: 'duckduckgo-email',
102
- jwtToken: string; // JWT token from DuckDuckGo Email Protection
103
- store?: DuckDuckGoAliasStore; // Optional custom store (default: in-memory)
104
- }
105
- ```
106
-
107
- **Getting your JWT token:**
108
-
109
- 1. Visit [duckduckgo.com/email](https://duckduckgo.com/email/) and register an account
110
- 2. Open your browser's developer tools (F12)
111
- 3. Click "Generate New Address" in the DuckDuckGo Email UI
112
- 4. In the Network tab, find the request to `quack.duckduckgo.com`
113
- 5. Copy the Bearer token from the `Authorization` header
114
-
115
- **Custom persistence:**
116
-
117
- ```typescript
118
- import type { DuckDuckGoAliasStore, RelayAlias } from '@z_06/relay-temp-mail';
119
-
120
- class MyFileStore implements DuckDuckGoAliasStore {
121
- getAll(): RelayAlias[] { /* read from file */ }
122
- add(alias: RelayAlias): void { /* append to file */ }
123
- remove(id: number): void { /* remove from file */ }
124
- }
125
-
126
- const client = new TempMailClient({
127
- aliasProvider: {
128
- type: 'duckduckgo-email',
129
- jwtToken: 'your-jwt-token',
130
- store: new MyFileStore(),
131
- },
132
- mailProvider: { /* ... */ },
133
- });
134
- ```
135
-
136
- **Duplicate detection:** The DuckDuckGo API may occasionally return a previously-generated address with a 201 response. The provider detects this and throws a `RelayTempMailError` with code `DUPLICATE_ALIAS`.
137
-
138
- ### Mail Providers
139
-
140
- #### `cf-temp-mail`
141
-
142
- Retrieves emails from a [cloudflare_temp_email](https://github.com/dreamhunter2333/cloudflare_temp_email) instance.
143
-
144
- **Configuration:**
145
-
146
- ```typescript
147
- {
148
- type: 'cf-temp-mail',
149
- apiUrl: string; // Base URL of your CF temp email API
150
- token: string; // Bearer token for API authentication
151
- }
152
- ```
153
-
154
- **Deploying the backend:**
155
-
156
- 1. Fork [cloudflare_temp_email](https://github.com/dreamhunter2333/cloudflare_temp_email)
157
- 2. Deploy to Cloudflare Workers (one-click or manual via [docs](https://temp-mail-docs.awsl.uk))
158
- 3. Configure Email Routing and catch-all rules in Cloudflare Dashboard
159
- 4. Generate an API Token from the admin panel or user settings
67
+ For detailed configuration parameters and credential acquisition guides, see **[Provider Setup Guide](PROVIDERS.md)**.
160
68
 
161
69
  ## API Documentation
162
70
 
package/README.zh-CN.md CHANGED
@@ -59,104 +59,12 @@ const emails = await client.getEmails(alias.fullAddress, { limit: 10 });
59
59
 
60
60
  本库使用两种可独立组合的 Provider:
61
61
 
62
- | Provider 类型 | 接口 | 当前实现 |
62
+ | Provider 类型 | 接口 | 可用提供商 |
63
63
  |---|---|---|
64
64
  | **别名提供商** | `AliasProvider` | `firefox-relay`, `duckduckgo-email` |
65
65
  | **邮件提供商** | `MailProvider` | `cf-temp-mail` |
66
66
 
67
- ### 别名提供商
68
-
69
- #### `firefox-relay`
70
-
71
- 通过 [Firefox Relay](https://relay.firefox.com) 管理邮箱别名。
72
-
73
- **配置:**
74
-
75
- ```typescript
76
- {
77
- type: 'firefox-relay',
78
- csrfToken: string; // relay.firefox.com 的 CSRF token
79
- sessionId: string; // relay.firefox.com 的 Session ID
80
- }
81
- ```
82
-
83
- **获取 Token:**
84
-
85
- 1. 登录 [relay.firefox.com](https://relay.firefox.com)
86
- 2. 打开浏览器开发者工具(F12)
87
- 3. 切换到 Application/Storage 标签页
88
- 4. 找到 `relay.firefox.com` 的 Cookies
89
- 5. 复制 `csrftoken` 和 `sessionid` 的值
90
-
91
- #### `duckduckgo-email`
92
-
93
- 通过 [DuckDuckGo 邮件保护](https://duckduckgo.com/email/) 管理邮箱别名。
94
-
95
- 由于 DuckDuckGo API 不提供列出或删除别名的接口,该提供商使用本地存储。内置内存存储;可通过实现 `DuckDuckGoAliasStore` 接口自定义持久化(如文件、数据库)。
96
-
97
- **配置:**
98
-
99
- ```typescript
100
- {
101
- type: 'duckduckgo-email',
102
- jwtToken: string; // DuckDuckGo 邮件保护的 JWT token
103
- store?: DuckDuckGoAliasStore; // 可选自定义存储(默认: 内存存储)
104
- }
105
- ```
106
-
107
- **获取 JWT Token:**
108
-
109
- 1. 访问 [duckduckgo.com/email](https://duckduckgo.com/email/) 并注册账户
110
- 2. 打开浏览器开发者工具(F12)
111
- 3. 在 DuckDuckGo 邮件界面点击"生成新地址"
112
- 4. 在网络请求栏中找到发往 `quack.duckduckgo.com` 的请求
113
- 5. 从 `Authorization` 请求头中复制 Bearer token
114
-
115
- **自定义持久化:**
116
-
117
- ```typescript
118
- import type { DuckDuckGoAliasStore, RelayAlias } from '@z_06/relay-temp-mail';
119
-
120
- class MyFileStore implements DuckDuckGoAliasStore {
121
- getAll(): RelayAlias[] { /* 从文件读取 */ }
122
- add(alias: RelayAlias): void { /* 追加到文件 */ }
123
- remove(id: number): void { /* 从文件中删除 */ }
124
- }
125
-
126
- const client = new TempMailClient({
127
- aliasProvider: {
128
- type: 'duckduckgo-email',
129
- jwtToken: 'your-jwt-token',
130
- store: new MyFileStore(),
131
- },
132
- mailProvider: { /* ... */ },
133
- });
134
- ```
135
-
136
- **重复检测:** DuckDuckGo API 偶尔会返回之前已生成过的地址(仍返回 201)。该提供商会检测这种情况并抛出 `RelayTempMailError`,错误代码为 `DUPLICATE_ALIAS`。
137
-
138
- ### 邮件提供商
139
-
140
- #### `cf-temp-mail`
141
-
142
- 从 [cloudflare_temp_email](https://github.com/dreamhunter2333/cloudflare_temp_email) 实例获取邮件。
143
-
144
- **配置:**
145
-
146
- ```typescript
147
- {
148
- type: 'cf-temp-mail',
149
- apiUrl: string; // CF 临时邮箱 API 的基础 URL
150
- token: string; // API Bearer Token
151
- }
152
- ```
153
-
154
- **部署后端:**
155
-
156
- 1. Fork [cloudflare_temp_email](https://github.com/dreamhunter2333/cloudflare_temp_email)
157
- 2. 部署到 Cloudflare Workers(一键部署或参考[部署文档](https://temp-mail-docs.awsl.uk)手动部署)
158
- 3. 在 Cloudflare Dashboard 中配置域名和 Email Routing 的 catch-all 规则
159
- 4. 从管理后台或用户设置中生成 API Token
67
+ 详细的配置参数和凭证获取指南,请参阅 **[提供商配置指南](PROVIDERS.zh-CN.md)**。
160
68
 
161
69
  ## API 文档
162
70
 
package/dist/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  CFTempMailProvider: () => CFTempMailProvider,
26
26
  DuckDuckGoEmailProvider: () => DuckDuckGoEmailProvider,
27
27
  FirefoxRelayProvider: () => FirefoxRelayProvider,
28
+ GmailProvider: () => GmailProvider,
28
29
  InMemoryDuckDuckGoAliasStore: () => InMemoryDuckDuckGoAliasStore,
29
30
  NetworkError: () => NetworkError,
30
31
  NotFoundError: () => NotFoundError,
@@ -386,6 +387,167 @@ var DuckDuckGoEmailProvider = class {
386
387
  }
387
388
  };
388
389
 
390
+ // src/gmail-api.ts
391
+ var GmailProvider = class {
392
+ constructor(config) {
393
+ this.tokenExpiresAt = 0;
394
+ this.userId = config.userId ?? "me";
395
+ if (config.accessToken) {
396
+ this.accessToken = config.accessToken;
397
+ } else if (config.refreshToken && config.clientId && config.clientSecret) {
398
+ this.accessToken = "";
399
+ this.refreshToken = config.refreshToken;
400
+ this.clientId = config.clientId;
401
+ this.clientSecret = config.clientSecret;
402
+ } else {
403
+ throw new RelayTempMailError(
404
+ "Gmail provider requires either accessToken or (refreshToken + clientId + clientSecret)",
405
+ "INVALID_CONFIG"
406
+ );
407
+ }
408
+ }
409
+ async getMails(limit = 20, offset = 0) {
410
+ const token = await this.getAccessToken();
411
+ const messageIds = await this.listMessageIds(token, limit, offset);
412
+ if (messageIds.length === 0) {
413
+ return [];
414
+ }
415
+ const emails = await Promise.all(
416
+ messageIds.map((id) => this.getMessage(token, id))
417
+ );
418
+ return emails.filter((e) => e !== null);
419
+ }
420
+ async getAccessToken() {
421
+ if (this.accessToken && Date.now() < this.tokenExpiresAt) {
422
+ return this.accessToken;
423
+ }
424
+ if (!this.refreshToken || !this.clientId || !this.clientSecret) {
425
+ return this.accessToken;
426
+ }
427
+ const response = await fetch("https://oauth2.googleapis.com/token", {
428
+ method: "POST",
429
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
430
+ body: new URLSearchParams({
431
+ client_id: this.clientId,
432
+ client_secret: this.clientSecret,
433
+ refresh_token: this.refreshToken,
434
+ grant_type: "refresh_token"
435
+ })
436
+ });
437
+ if (!response.ok) {
438
+ const body = await response.text();
439
+ throw new AuthError(
440
+ `Failed to refresh Gmail access token: ${body}`,
441
+ response.status
442
+ );
443
+ }
444
+ const data = await response.json();
445
+ this.accessToken = data.access_token;
446
+ this.tokenExpiresAt = Date.now() + (data.expires_in ?? 3600) * 1e3 - 6e4;
447
+ return this.accessToken;
448
+ }
449
+ async listMessageIds(token, limit, offset) {
450
+ const totalCount = limit + offset;
451
+ const allIds = [];
452
+ let pageToken;
453
+ while (allIds.length < totalCount) {
454
+ const url = new URL(
455
+ `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages`
456
+ );
457
+ url.searchParams.set("maxResults", String(Math.min(500, totalCount - allIds.length)));
458
+ if (pageToken) {
459
+ url.searchParams.set("pageToken", pageToken);
460
+ }
461
+ const response = await this.authedFetch(token, url.toString());
462
+ const data = await response.json();
463
+ if (data.messages) {
464
+ allIds.push(...data.messages.map((m) => m.id));
465
+ }
466
+ if (!data.nextPageToken) break;
467
+ pageToken = data.nextPageToken;
468
+ }
469
+ return allIds.slice(offset, offset + limit);
470
+ }
471
+ async getMessage(token, messageId) {
472
+ const url = `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages/${messageId}?format=raw`;
473
+ const response = await this.authedFetch(token, url);
474
+ const data = await response.json();
475
+ const headers = data.payload?.headers ?? [];
476
+ const fromHeader = headers.find((h) => h.name.toLowerCase() === "from")?.value ?? "";
477
+ const toHeader = headers.find((h) => h.name.toLowerCase() === "to")?.value ?? "";
478
+ const messageIdHeader = headers.find((h) => h.name.toLowerCase() === "message-id")?.value ?? "";
479
+ const rawBase64 = data.payload?.body?.data ?? "";
480
+ let rawMime = "";
481
+ if (rawBase64) {
482
+ rawMime = this.decodeBase64Url(rawBase64);
483
+ }
484
+ return {
485
+ id: this.hashStringToInt(data.id),
486
+ messageId: messageIdHeader || data.id,
487
+ source: fromHeader,
488
+ address: toHeader,
489
+ raw: rawMime,
490
+ metadata: {
491
+ threadId: data.threadId,
492
+ snippet: data.snippet,
493
+ internalDate: data.internalDate
494
+ },
495
+ createdAt: data.internalDate ? new Date(Number(data.internalDate)).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
496
+ };
497
+ }
498
+ async authedFetch(token, url) {
499
+ const response = await fetch(url, {
500
+ headers: { Authorization: `Bearer ${token}` }
501
+ });
502
+ if (response.status === 401 || response.status === 403) {
503
+ const body = await response.text();
504
+ throw new AuthError(
505
+ `Gmail API authentication failed: ${body}`,
506
+ response.status
507
+ );
508
+ }
509
+ if (response.status === 404) {
510
+ throw new RelayTempMailError(
511
+ "Gmail message not found",
512
+ "NOT_FOUND",
513
+ 404
514
+ );
515
+ }
516
+ if (response.status === 429) {
517
+ const retryAfter = response.headers.get("Retry-After");
518
+ throw new RateLimitError(
519
+ `Gmail API rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ""}`
520
+ );
521
+ }
522
+ if (!response.ok) {
523
+ const body = await response.text();
524
+ throw new NetworkError(
525
+ `Gmail API error (${response.status}): ${body}`,
526
+ response.status
527
+ );
528
+ }
529
+ return response;
530
+ }
531
+ decodeBase64Url(input) {
532
+ const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
533
+ const padding = "=".repeat((4 - base64.length % 4) % 4);
534
+ const binary = atob(base64 + padding);
535
+ const bytes = new Uint8Array(binary.length);
536
+ for (let i = 0; i < binary.length; i++) {
537
+ bytes[i] = binary.charCodeAt(i);
538
+ }
539
+ return new TextDecoder("utf-8").decode(bytes);
540
+ }
541
+ hashStringToInt(str) {
542
+ let hash = 0;
543
+ for (let i = 0; i < str.length; i++) {
544
+ const char = str.charCodeAt(i);
545
+ hash = (hash << 5) - hash + char | 0;
546
+ }
547
+ return Math.abs(hash);
548
+ }
549
+ };
550
+
389
551
  // src/parser.ts
390
552
  var EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
391
553
  var MOZMAIL_SUFFIX_PATTERN = /@mozmail\.com$/i;
@@ -586,6 +748,14 @@ function createMailProvider(config) {
586
748
  mailConfig.apiUrl,
587
749
  mailConfig.token
588
750
  );
751
+ case "gmail":
752
+ return new GmailProvider({
753
+ userId: mailConfig.userId,
754
+ accessToken: mailConfig.accessToken,
755
+ clientId: mailConfig.clientId,
756
+ clientSecret: mailConfig.clientSecret,
757
+ refreshToken: mailConfig.refreshToken
758
+ });
589
759
  }
590
760
  }
591
761
  var TempMailClient = class {
@@ -638,6 +808,7 @@ var RelayClient = TempMailClient;
638
808
  CFTempMailProvider,
639
809
  DuckDuckGoEmailProvider,
640
810
  FirefoxRelayProvider,
811
+ GmailProvider,
641
812
  InMemoryDuckDuckGoAliasStore,
642
813
  NetworkError,
643
814
  NotFoundError,
@@ -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 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 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 email.raw.toLowerCase().includes(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":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/cf-api.ts","../src/http.ts","../src/duckduckgo-api.ts","../src/gmail-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 GmailConfig,\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\nexport { GmailProvider } from './gmail-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","import type { MailProvider, Email } from './types.js';\nimport {\n AuthError,\n NetworkError,\n RateLimitError,\n RelayTempMailError,\n} from './errors.js';\n\ninterface GmailMessageListResponse {\n messages?: Array<{ id: string }>;\n nextPageToken?: string;\n resultSizeEstimate?: number;\n}\n\ninterface GmailMessagePart {\n partId?: string;\n mimeType?: string;\n filename?: string;\n headers?: Array<{ name: string; value: string }>;\n body?: { data?: string; size?: number };\n parts?: GmailMessagePart[];\n}\n\ninterface GmailMessageResponse {\n id: string;\n threadId?: string;\n snippet?: string;\n payload?: GmailMessagePart;\n internalDate?: string;\n sizeEstimate?: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n expires_in?: number;\n token_type?: string;\n scope?: string;\n}\n\nexport class GmailProvider implements MailProvider {\n private readonly userId: string;\n private readonly clientId?: string;\n private readonly clientSecret?: string;\n private readonly refreshToken?: string;\n private accessToken: string;\n private tokenExpiresAt = 0;\n\n constructor(config: {\n userId?: string;\n accessToken?: string;\n clientId?: string;\n clientSecret?: string;\n refreshToken?: string;\n }) {\n this.userId = config.userId ?? 'me';\n\n if (config.accessToken) {\n this.accessToken = config.accessToken;\n } else if (config.refreshToken && config.clientId && config.clientSecret) {\n this.accessToken = '';\n this.refreshToken = config.refreshToken;\n this.clientId = config.clientId;\n this.clientSecret = config.clientSecret;\n } else {\n throw new RelayTempMailError(\n 'Gmail provider requires either accessToken or (refreshToken + clientId + clientSecret)',\n 'INVALID_CONFIG',\n );\n }\n }\n\n async getMails(limit: number = 20, offset: number = 0): Promise<Email[]> {\n const token = await this.getAccessToken();\n\n const messageIds = await this.listMessageIds(token, limit, offset);\n if (messageIds.length === 0) {\n return [];\n }\n\n const emails = await Promise.all(\n messageIds.map((id) => this.getMessage(token, id)),\n );\n\n return emails.filter((e): e is Email => e !== null);\n }\n\n private async getAccessToken(): Promise<string> {\n if (this.accessToken && Date.now() < this.tokenExpiresAt) {\n return this.accessToken;\n }\n\n if (!this.refreshToken || !this.clientId || !this.clientSecret) {\n return this.accessToken;\n }\n\n const response = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n client_id: this.clientId,\n client_secret: this.clientSecret,\n refresh_token: this.refreshToken,\n grant_type: 'refresh_token',\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new AuthError(\n `Failed to refresh Gmail access token: ${body}`,\n response.status,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n this.accessToken = data.access_token;\n this.tokenExpiresAt = Date.now() + (data.expires_in ?? 3600) * 1000 - 60_000;\n\n return this.accessToken;\n }\n\n private async listMessageIds(\n token: string,\n limit: number,\n offset: number,\n ): Promise<string[]> {\n const totalCount = limit + offset;\n const allIds: string[] = [];\n let pageToken: string | undefined;\n\n while (allIds.length < totalCount) {\n const url = new URL(\n `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages`,\n );\n url.searchParams.set('maxResults', String(Math.min(500, totalCount - allIds.length)));\n if (pageToken) {\n url.searchParams.set('pageToken', pageToken);\n }\n\n const response = await this.authedFetch(token, url.toString());\n\n const data = (await response.json()) as GmailMessageListResponse;\n if (data.messages) {\n allIds.push(...data.messages.map((m) => m.id));\n }\n\n if (!data.nextPageToken) break;\n pageToken = data.nextPageToken;\n }\n\n return allIds.slice(offset, offset + limit);\n }\n\n private async getMessage(\n token: string,\n messageId: string,\n ): Promise<Email | null> {\n const url = `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages/${messageId}?format=raw`;\n\n const response = await this.authedFetch(token, url);\n\n const data = (await response.json()) as GmailMessageResponse;\n\n const headers = data.payload?.headers ?? [];\n const fromHeader =\n headers.find((h) => h.name.toLowerCase() === 'from')?.value ?? '';\n const toHeader =\n headers.find((h) => h.name.toLowerCase() === 'to')?.value ?? '';\n const messageIdHeader =\n headers.find((h) => h.name.toLowerCase() === 'message-id')?.value ?? '';\n\n const rawBase64 = data.payload?.body?.data ?? '';\n\n let rawMime = '';\n if (rawBase64) {\n rawMime = this.decodeBase64Url(rawBase64);\n }\n\n return {\n id: this.hashStringToInt(data.id),\n messageId: messageIdHeader || data.id,\n source: fromHeader,\n address: toHeader,\n raw: rawMime,\n metadata: {\n threadId: data.threadId,\n snippet: data.snippet,\n internalDate: data.internalDate,\n },\n createdAt: data.internalDate\n ? new Date(Number(data.internalDate)).toISOString()\n : new Date().toISOString(),\n };\n }\n\n private async authedFetch(token: string, url: string): Promise<Response> {\n const response = await fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (response.status === 401 || response.status === 403) {\n const body = await response.text();\n throw new AuthError(\n `Gmail API authentication failed: ${body}`,\n response.status,\n );\n }\n\n if (response.status === 404) {\n throw new RelayTempMailError(\n 'Gmail message not found',\n 'NOT_FOUND',\n 404,\n );\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n throw new RateLimitError(\n `Gmail API rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ''}`,\n );\n }\n\n if (!response.ok) {\n const body = await response.text();\n throw new NetworkError(\n `Gmail API error (${response.status}): ${body}`,\n response.status,\n );\n }\n\n return response;\n }\n\n private decodeBase64Url(input: string): string {\n const base64 = input.replace(/-/g, '+').replace(/_/g, '/');\n const padding = '='.repeat((4 - (base64.length % 4)) % 4);\n const binary = atob(base64 + padding);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder('utf-8').decode(bytes);\n }\n\n private hashStringToInt(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash + char) | 0;\n }\n return Math.abs(hash);\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 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 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 { GmailProvider } from './gmail-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 case 'gmail':\n return new GmailProvider({\n userId: mailConfig.userId,\n accessToken: mailConfig.accessToken,\n clientId: mailConfig.clientId,\n clientSecret: mailConfig.clientSecret,\n refreshToken: mailConfig.refreshToken,\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 email.raw.toLowerCase().includes(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.d.cts CHANGED
@@ -135,13 +135,52 @@ interface CFTempMailConfig {
135
135
  /** Bearer token for CloudFlare temp email API authentication */
136
136
  token: string;
137
137
  }
138
+ /**
139
+ * Configuration for the Gmail mail provider.
140
+ *
141
+ * Supports two authentication modes:
142
+ * 1. **Access token** — provide `accessToken` directly if you manage
143
+ * OAuth2 token refresh yourself.
144
+ * 2. **OAuth2 refresh token** — provide `clientId`, `clientSecret`, and
145
+ * `refreshToken` and the provider will automatically refresh the
146
+ * access token when it expires.
147
+ */
148
+ interface GmailConfig {
149
+ /** Discriminant identifying this provider type */
150
+ type: 'gmail';
151
+ /**
152
+ * Gmail address used as the userId in API calls.
153
+ * Defaults to 'me' (the authenticated user) if not provided.
154
+ */
155
+ userId?: string;
156
+ /**
157
+ * OAuth2 access token for the Gmail API.
158
+ * Required if not using `refreshToken`-based auth.
159
+ */
160
+ accessToken?: string;
161
+ /**
162
+ * Google OAuth2 client ID.
163
+ * Required when using refresh-token-based authentication.
164
+ */
165
+ clientId?: string;
166
+ /**
167
+ * Google OAuth2 client secret.
168
+ * Required when using refresh-token-based authentication.
169
+ */
170
+ clientSecret?: string;
171
+ /**
172
+ * Google OAuth2 refresh token.
173
+ * Required when not providing `accessToken` directly.
174
+ */
175
+ refreshToken?: string;
176
+ }
138
177
  /**
139
178
  * Union type for all supported mail provider configurations.
140
179
  *
141
- * Currently only supports 'cf-temp-mail'. More providers (imap, pop3, etc.)
142
- * can be added here in the future.
180
+ * Currently supports 'cf-temp-mail' and 'gmail'.
181
+ * More providers (imap, pop3, etc.) can be added here in the future.
143
182
  */
144
- type MailProviderConfig = CFTempMailConfig;
183
+ type MailProviderConfig = CFTempMailConfig | GmailConfig;
145
184
  /**
146
185
  * Configuration interface for initializing the TempMailClient.
147
186
  *
@@ -535,4 +574,27 @@ declare class DuckDuckGoEmailProvider implements AliasProvider {
535
574
  deleteAlias(id: number): Promise<void>;
536
575
  }
537
576
 
538
- export { type AliasProvider, type AliasProviderConfig, AuthError, CFEmailClient, type CFMailsResponse, type CFTempMailConfig, CFTempMailProvider, type CreateAliasResponse, type DuckDuckGoAliasStore, type DuckDuckGoEmailConfig, DuckDuckGoEmailProvider, type Email, type FirefoxRelayConfig, FirefoxRelayProvider, type GetEmailsOptions, InMemoryDuckDuckGoAliasStore, type ListAliasesOptions, type MailProvider, type MailProviderConfig, NetworkError, NotFoundError, ParseError, type ParsedEmail, RateLimitError, RelayAPIClient, type RelayAddressesResponse, type RelayAlias, RelayClient, type RelayConfig, RelayTempMailError, TempMailClient, type TempMailConfig };
577
+ declare class GmailProvider implements MailProvider {
578
+ private readonly userId;
579
+ private readonly clientId?;
580
+ private readonly clientSecret?;
581
+ private readonly refreshToken?;
582
+ private accessToken;
583
+ private tokenExpiresAt;
584
+ constructor(config: {
585
+ userId?: string;
586
+ accessToken?: string;
587
+ clientId?: string;
588
+ clientSecret?: string;
589
+ refreshToken?: string;
590
+ });
591
+ getMails(limit?: number, offset?: number): Promise<Email[]>;
592
+ private getAccessToken;
593
+ private listMessageIds;
594
+ private getMessage;
595
+ private authedFetch;
596
+ private decodeBase64Url;
597
+ private hashStringToInt;
598
+ }
599
+
600
+ export { type AliasProvider, type AliasProviderConfig, AuthError, CFEmailClient, type CFMailsResponse, type CFTempMailConfig, CFTempMailProvider, type CreateAliasResponse, type DuckDuckGoAliasStore, type DuckDuckGoEmailConfig, DuckDuckGoEmailProvider, type Email, type FirefoxRelayConfig, FirefoxRelayProvider, type GetEmailsOptions, type GmailConfig, GmailProvider, InMemoryDuckDuckGoAliasStore, type ListAliasesOptions, type MailProvider, type MailProviderConfig, NetworkError, NotFoundError, ParseError, type ParsedEmail, RateLimitError, RelayAPIClient, type RelayAddressesResponse, type RelayAlias, RelayClient, type RelayConfig, RelayTempMailError, TempMailClient, type TempMailConfig };
package/dist/index.d.ts CHANGED
@@ -135,13 +135,52 @@ interface CFTempMailConfig {
135
135
  /** Bearer token for CloudFlare temp email API authentication */
136
136
  token: string;
137
137
  }
138
+ /**
139
+ * Configuration for the Gmail mail provider.
140
+ *
141
+ * Supports two authentication modes:
142
+ * 1. **Access token** — provide `accessToken` directly if you manage
143
+ * OAuth2 token refresh yourself.
144
+ * 2. **OAuth2 refresh token** — provide `clientId`, `clientSecret`, and
145
+ * `refreshToken` and the provider will automatically refresh the
146
+ * access token when it expires.
147
+ */
148
+ interface GmailConfig {
149
+ /** Discriminant identifying this provider type */
150
+ type: 'gmail';
151
+ /**
152
+ * Gmail address used as the userId in API calls.
153
+ * Defaults to 'me' (the authenticated user) if not provided.
154
+ */
155
+ userId?: string;
156
+ /**
157
+ * OAuth2 access token for the Gmail API.
158
+ * Required if not using `refreshToken`-based auth.
159
+ */
160
+ accessToken?: string;
161
+ /**
162
+ * Google OAuth2 client ID.
163
+ * Required when using refresh-token-based authentication.
164
+ */
165
+ clientId?: string;
166
+ /**
167
+ * Google OAuth2 client secret.
168
+ * Required when using refresh-token-based authentication.
169
+ */
170
+ clientSecret?: string;
171
+ /**
172
+ * Google OAuth2 refresh token.
173
+ * Required when not providing `accessToken` directly.
174
+ */
175
+ refreshToken?: string;
176
+ }
138
177
  /**
139
178
  * Union type for all supported mail provider configurations.
140
179
  *
141
- * Currently only supports 'cf-temp-mail'. More providers (imap, pop3, etc.)
142
- * can be added here in the future.
180
+ * Currently supports 'cf-temp-mail' and 'gmail'.
181
+ * More providers (imap, pop3, etc.) can be added here in the future.
143
182
  */
144
- type MailProviderConfig = CFTempMailConfig;
183
+ type MailProviderConfig = CFTempMailConfig | GmailConfig;
145
184
  /**
146
185
  * Configuration interface for initializing the TempMailClient.
147
186
  *
@@ -535,4 +574,27 @@ declare class DuckDuckGoEmailProvider implements AliasProvider {
535
574
  deleteAlias(id: number): Promise<void>;
536
575
  }
537
576
 
538
- export { type AliasProvider, type AliasProviderConfig, AuthError, CFEmailClient, type CFMailsResponse, type CFTempMailConfig, CFTempMailProvider, type CreateAliasResponse, type DuckDuckGoAliasStore, type DuckDuckGoEmailConfig, DuckDuckGoEmailProvider, type Email, type FirefoxRelayConfig, FirefoxRelayProvider, type GetEmailsOptions, InMemoryDuckDuckGoAliasStore, type ListAliasesOptions, type MailProvider, type MailProviderConfig, NetworkError, NotFoundError, ParseError, type ParsedEmail, RateLimitError, RelayAPIClient, type RelayAddressesResponse, type RelayAlias, RelayClient, type RelayConfig, RelayTempMailError, TempMailClient, type TempMailConfig };
577
+ declare class GmailProvider implements MailProvider {
578
+ private readonly userId;
579
+ private readonly clientId?;
580
+ private readonly clientSecret?;
581
+ private readonly refreshToken?;
582
+ private accessToken;
583
+ private tokenExpiresAt;
584
+ constructor(config: {
585
+ userId?: string;
586
+ accessToken?: string;
587
+ clientId?: string;
588
+ clientSecret?: string;
589
+ refreshToken?: string;
590
+ });
591
+ getMails(limit?: number, offset?: number): Promise<Email[]>;
592
+ private getAccessToken;
593
+ private listMessageIds;
594
+ private getMessage;
595
+ private authedFetch;
596
+ private decodeBase64Url;
597
+ private hashStringToInt;
598
+ }
599
+
600
+ export { type AliasProvider, type AliasProviderConfig, AuthError, CFEmailClient, type CFMailsResponse, type CFTempMailConfig, CFTempMailProvider, type CreateAliasResponse, type DuckDuckGoAliasStore, type DuckDuckGoEmailConfig, DuckDuckGoEmailProvider, type Email, type FirefoxRelayConfig, FirefoxRelayProvider, type GetEmailsOptions, type GmailConfig, GmailProvider, InMemoryDuckDuckGoAliasStore, type ListAliasesOptions, type MailProvider, type MailProviderConfig, NetworkError, NotFoundError, ParseError, type ParsedEmail, RateLimitError, RelayAPIClient, type RelayAddressesResponse, type RelayAlias, RelayClient, type RelayConfig, RelayTempMailError, TempMailClient, type TempMailConfig };
package/dist/index.js CHANGED
@@ -347,6 +347,167 @@ var DuckDuckGoEmailProvider = class {
347
347
  }
348
348
  };
349
349
 
350
+ // src/gmail-api.ts
351
+ var GmailProvider = class {
352
+ constructor(config) {
353
+ this.tokenExpiresAt = 0;
354
+ this.userId = config.userId ?? "me";
355
+ if (config.accessToken) {
356
+ this.accessToken = config.accessToken;
357
+ } else if (config.refreshToken && config.clientId && config.clientSecret) {
358
+ this.accessToken = "";
359
+ this.refreshToken = config.refreshToken;
360
+ this.clientId = config.clientId;
361
+ this.clientSecret = config.clientSecret;
362
+ } else {
363
+ throw new RelayTempMailError(
364
+ "Gmail provider requires either accessToken or (refreshToken + clientId + clientSecret)",
365
+ "INVALID_CONFIG"
366
+ );
367
+ }
368
+ }
369
+ async getMails(limit = 20, offset = 0) {
370
+ const token = await this.getAccessToken();
371
+ const messageIds = await this.listMessageIds(token, limit, offset);
372
+ if (messageIds.length === 0) {
373
+ return [];
374
+ }
375
+ const emails = await Promise.all(
376
+ messageIds.map((id) => this.getMessage(token, id))
377
+ );
378
+ return emails.filter((e) => e !== null);
379
+ }
380
+ async getAccessToken() {
381
+ if (this.accessToken && Date.now() < this.tokenExpiresAt) {
382
+ return this.accessToken;
383
+ }
384
+ if (!this.refreshToken || !this.clientId || !this.clientSecret) {
385
+ return this.accessToken;
386
+ }
387
+ const response = await fetch("https://oauth2.googleapis.com/token", {
388
+ method: "POST",
389
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
390
+ body: new URLSearchParams({
391
+ client_id: this.clientId,
392
+ client_secret: this.clientSecret,
393
+ refresh_token: this.refreshToken,
394
+ grant_type: "refresh_token"
395
+ })
396
+ });
397
+ if (!response.ok) {
398
+ const body = await response.text();
399
+ throw new AuthError(
400
+ `Failed to refresh Gmail access token: ${body}`,
401
+ response.status
402
+ );
403
+ }
404
+ const data = await response.json();
405
+ this.accessToken = data.access_token;
406
+ this.tokenExpiresAt = Date.now() + (data.expires_in ?? 3600) * 1e3 - 6e4;
407
+ return this.accessToken;
408
+ }
409
+ async listMessageIds(token, limit, offset) {
410
+ const totalCount = limit + offset;
411
+ const allIds = [];
412
+ let pageToken;
413
+ while (allIds.length < totalCount) {
414
+ const url = new URL(
415
+ `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages`
416
+ );
417
+ url.searchParams.set("maxResults", String(Math.min(500, totalCount - allIds.length)));
418
+ if (pageToken) {
419
+ url.searchParams.set("pageToken", pageToken);
420
+ }
421
+ const response = await this.authedFetch(token, url.toString());
422
+ const data = await response.json();
423
+ if (data.messages) {
424
+ allIds.push(...data.messages.map((m) => m.id));
425
+ }
426
+ if (!data.nextPageToken) break;
427
+ pageToken = data.nextPageToken;
428
+ }
429
+ return allIds.slice(offset, offset + limit);
430
+ }
431
+ async getMessage(token, messageId) {
432
+ const url = `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages/${messageId}?format=raw`;
433
+ const response = await this.authedFetch(token, url);
434
+ const data = await response.json();
435
+ const headers = data.payload?.headers ?? [];
436
+ const fromHeader = headers.find((h) => h.name.toLowerCase() === "from")?.value ?? "";
437
+ const toHeader = headers.find((h) => h.name.toLowerCase() === "to")?.value ?? "";
438
+ const messageIdHeader = headers.find((h) => h.name.toLowerCase() === "message-id")?.value ?? "";
439
+ const rawBase64 = data.payload?.body?.data ?? "";
440
+ let rawMime = "";
441
+ if (rawBase64) {
442
+ rawMime = this.decodeBase64Url(rawBase64);
443
+ }
444
+ return {
445
+ id: this.hashStringToInt(data.id),
446
+ messageId: messageIdHeader || data.id,
447
+ source: fromHeader,
448
+ address: toHeader,
449
+ raw: rawMime,
450
+ metadata: {
451
+ threadId: data.threadId,
452
+ snippet: data.snippet,
453
+ internalDate: data.internalDate
454
+ },
455
+ createdAt: data.internalDate ? new Date(Number(data.internalDate)).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
456
+ };
457
+ }
458
+ async authedFetch(token, url) {
459
+ const response = await fetch(url, {
460
+ headers: { Authorization: `Bearer ${token}` }
461
+ });
462
+ if (response.status === 401 || response.status === 403) {
463
+ const body = await response.text();
464
+ throw new AuthError(
465
+ `Gmail API authentication failed: ${body}`,
466
+ response.status
467
+ );
468
+ }
469
+ if (response.status === 404) {
470
+ throw new RelayTempMailError(
471
+ "Gmail message not found",
472
+ "NOT_FOUND",
473
+ 404
474
+ );
475
+ }
476
+ if (response.status === 429) {
477
+ const retryAfter = response.headers.get("Retry-After");
478
+ throw new RateLimitError(
479
+ `Gmail API rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ""}`
480
+ );
481
+ }
482
+ if (!response.ok) {
483
+ const body = await response.text();
484
+ throw new NetworkError(
485
+ `Gmail API error (${response.status}): ${body}`,
486
+ response.status
487
+ );
488
+ }
489
+ return response;
490
+ }
491
+ decodeBase64Url(input) {
492
+ const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
493
+ const padding = "=".repeat((4 - base64.length % 4) % 4);
494
+ const binary = atob(base64 + padding);
495
+ const bytes = new Uint8Array(binary.length);
496
+ for (let i = 0; i < binary.length; i++) {
497
+ bytes[i] = binary.charCodeAt(i);
498
+ }
499
+ return new TextDecoder("utf-8").decode(bytes);
500
+ }
501
+ hashStringToInt(str) {
502
+ let hash = 0;
503
+ for (let i = 0; i < str.length; i++) {
504
+ const char = str.charCodeAt(i);
505
+ hash = (hash << 5) - hash + char | 0;
506
+ }
507
+ return Math.abs(hash);
508
+ }
509
+ };
510
+
350
511
  // src/parser.ts
351
512
  var EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
352
513
  var MOZMAIL_SUFFIX_PATTERN = /@mozmail\.com$/i;
@@ -547,6 +708,14 @@ function createMailProvider(config) {
547
708
  mailConfig.apiUrl,
548
709
  mailConfig.token
549
710
  );
711
+ case "gmail":
712
+ return new GmailProvider({
713
+ userId: mailConfig.userId,
714
+ accessToken: mailConfig.accessToken,
715
+ clientId: mailConfig.clientId,
716
+ clientSecret: mailConfig.clientSecret,
717
+ refreshToken: mailConfig.refreshToken
718
+ });
550
719
  }
551
720
  }
552
721
  var TempMailClient = class {
@@ -598,6 +767,7 @@ export {
598
767
  CFTempMailProvider,
599
768
  DuckDuckGoEmailProvider,
600
769
  FirefoxRelayProvider,
770
+ GmailProvider,
601
771
  InMemoryDuckDuckGoAliasStore,
602
772
  NetworkError,
603
773
  NotFoundError,
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 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 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 email.raw.toLowerCase().includes(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":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/cf-api.ts","../src/http.ts","../src/duckduckgo-api.ts","../src/gmail-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","import type { MailProvider, Email } from './types.js';\nimport {\n AuthError,\n NetworkError,\n RateLimitError,\n RelayTempMailError,\n} from './errors.js';\n\ninterface GmailMessageListResponse {\n messages?: Array<{ id: string }>;\n nextPageToken?: string;\n resultSizeEstimate?: number;\n}\n\ninterface GmailMessagePart {\n partId?: string;\n mimeType?: string;\n filename?: string;\n headers?: Array<{ name: string; value: string }>;\n body?: { data?: string; size?: number };\n parts?: GmailMessagePart[];\n}\n\ninterface GmailMessageResponse {\n id: string;\n threadId?: string;\n snippet?: string;\n payload?: GmailMessagePart;\n internalDate?: string;\n sizeEstimate?: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n expires_in?: number;\n token_type?: string;\n scope?: string;\n}\n\nexport class GmailProvider implements MailProvider {\n private readonly userId: string;\n private readonly clientId?: string;\n private readonly clientSecret?: string;\n private readonly refreshToken?: string;\n private accessToken: string;\n private tokenExpiresAt = 0;\n\n constructor(config: {\n userId?: string;\n accessToken?: string;\n clientId?: string;\n clientSecret?: string;\n refreshToken?: string;\n }) {\n this.userId = config.userId ?? 'me';\n\n if (config.accessToken) {\n this.accessToken = config.accessToken;\n } else if (config.refreshToken && config.clientId && config.clientSecret) {\n this.accessToken = '';\n this.refreshToken = config.refreshToken;\n this.clientId = config.clientId;\n this.clientSecret = config.clientSecret;\n } else {\n throw new RelayTempMailError(\n 'Gmail provider requires either accessToken or (refreshToken + clientId + clientSecret)',\n 'INVALID_CONFIG',\n );\n }\n }\n\n async getMails(limit: number = 20, offset: number = 0): Promise<Email[]> {\n const token = await this.getAccessToken();\n\n const messageIds = await this.listMessageIds(token, limit, offset);\n if (messageIds.length === 0) {\n return [];\n }\n\n const emails = await Promise.all(\n messageIds.map((id) => this.getMessage(token, id)),\n );\n\n return emails.filter((e): e is Email => e !== null);\n }\n\n private async getAccessToken(): Promise<string> {\n if (this.accessToken && Date.now() < this.tokenExpiresAt) {\n return this.accessToken;\n }\n\n if (!this.refreshToken || !this.clientId || !this.clientSecret) {\n return this.accessToken;\n }\n\n const response = await fetch('https://oauth2.googleapis.com/token', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n client_id: this.clientId,\n client_secret: this.clientSecret,\n refresh_token: this.refreshToken,\n grant_type: 'refresh_token',\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new AuthError(\n `Failed to refresh Gmail access token: ${body}`,\n response.status,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n this.accessToken = data.access_token;\n this.tokenExpiresAt = Date.now() + (data.expires_in ?? 3600) * 1000 - 60_000;\n\n return this.accessToken;\n }\n\n private async listMessageIds(\n token: string,\n limit: number,\n offset: number,\n ): Promise<string[]> {\n const totalCount = limit + offset;\n const allIds: string[] = [];\n let pageToken: string | undefined;\n\n while (allIds.length < totalCount) {\n const url = new URL(\n `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages`,\n );\n url.searchParams.set('maxResults', String(Math.min(500, totalCount - allIds.length)));\n if (pageToken) {\n url.searchParams.set('pageToken', pageToken);\n }\n\n const response = await this.authedFetch(token, url.toString());\n\n const data = (await response.json()) as GmailMessageListResponse;\n if (data.messages) {\n allIds.push(...data.messages.map((m) => m.id));\n }\n\n if (!data.nextPageToken) break;\n pageToken = data.nextPageToken;\n }\n\n return allIds.slice(offset, offset + limit);\n }\n\n private async getMessage(\n token: string,\n messageId: string,\n ): Promise<Email | null> {\n const url = `https://gmail.googleapis.com/gmail/v1/users/${this.userId}/messages/${messageId}?format=raw`;\n\n const response = await this.authedFetch(token, url);\n\n const data = (await response.json()) as GmailMessageResponse;\n\n const headers = data.payload?.headers ?? [];\n const fromHeader =\n headers.find((h) => h.name.toLowerCase() === 'from')?.value ?? '';\n const toHeader =\n headers.find((h) => h.name.toLowerCase() === 'to')?.value ?? '';\n const messageIdHeader =\n headers.find((h) => h.name.toLowerCase() === 'message-id')?.value ?? '';\n\n const rawBase64 = data.payload?.body?.data ?? '';\n\n let rawMime = '';\n if (rawBase64) {\n rawMime = this.decodeBase64Url(rawBase64);\n }\n\n return {\n id: this.hashStringToInt(data.id),\n messageId: messageIdHeader || data.id,\n source: fromHeader,\n address: toHeader,\n raw: rawMime,\n metadata: {\n threadId: data.threadId,\n snippet: data.snippet,\n internalDate: data.internalDate,\n },\n createdAt: data.internalDate\n ? new Date(Number(data.internalDate)).toISOString()\n : new Date().toISOString(),\n };\n }\n\n private async authedFetch(token: string, url: string): Promise<Response> {\n const response = await fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (response.status === 401 || response.status === 403) {\n const body = await response.text();\n throw new AuthError(\n `Gmail API authentication failed: ${body}`,\n response.status,\n );\n }\n\n if (response.status === 404) {\n throw new RelayTempMailError(\n 'Gmail message not found',\n 'NOT_FOUND',\n 404,\n );\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n throw new RateLimitError(\n `Gmail API rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ''}`,\n );\n }\n\n if (!response.ok) {\n const body = await response.text();\n throw new NetworkError(\n `Gmail API error (${response.status}): ${body}`,\n response.status,\n );\n }\n\n return response;\n }\n\n private decodeBase64Url(input: string): string {\n const base64 = input.replace(/-/g, '+').replace(/_/g, '/');\n const padding = '='.repeat((4 - (base64.length % 4)) % 4);\n const binary = atob(base64 + padding);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder('utf-8').decode(bytes);\n }\n\n private hashStringToInt(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash + char) | 0;\n }\n return Math.abs(hash);\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 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 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 { GmailProvider } from './gmail-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 case 'gmail':\n return new GmailProvider({\n userId: mailConfig.userId,\n accessToken: mailConfig.accessToken,\n clientId: mailConfig.clientId,\n clientSecret: mailConfig.clientSecret,\n refreshToken: mailConfig.refreshToken,\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 email.raw.toLowerCase().includes(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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@z_06/relay-temp-mail",
3
- "version": "2.1.2",
3
+ "version": "2.2.0",
4
4
  "type": "module",
5
5
  "description": "TypeScript npm package for Firefox Relay + CF temp email API",
6
6
  "main": "./dist/index.cjs",