@vaultsandbox/client 0.5.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +612 -0
  3. package/dist/client.d.ts +231 -0
  4. package/dist/client.js +432 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/crypto/constants.d.ts +13 -0
  7. package/dist/crypto/constants.js +14 -0
  8. package/dist/crypto/constants.js.map +1 -0
  9. package/dist/crypto/decrypt.d.ts +41 -0
  10. package/dist/crypto/decrypt.js +112 -0
  11. package/dist/crypto/decrypt.js.map +1 -0
  12. package/dist/crypto/keypair.d.ts +39 -0
  13. package/dist/crypto/keypair.js +109 -0
  14. package/dist/crypto/keypair.js.map +1 -0
  15. package/dist/crypto/signature.d.ts +28 -0
  16. package/dist/crypto/signature.js +89 -0
  17. package/dist/crypto/signature.js.map +1 -0
  18. package/dist/crypto/utils.d.ts +28 -0
  19. package/dist/crypto/utils.js +60 -0
  20. package/dist/crypto/utils.js.map +1 -0
  21. package/dist/email.d.ts +63 -0
  22. package/dist/email.js +186 -0
  23. package/dist/email.js.map +1 -0
  24. package/dist/http/api-client.d.ts +145 -0
  25. package/dist/http/api-client.js +242 -0
  26. package/dist/http/api-client.js.map +1 -0
  27. package/dist/inbox.d.ts +120 -0
  28. package/dist/inbox.js +243 -0
  29. package/dist/inbox.js.map +1 -0
  30. package/dist/index.d.ts +14 -0
  31. package/dist/index.js +17 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/strategies/delivery-strategy.d.ts +29 -0
  34. package/dist/strategies/delivery-strategy.js +2 -0
  35. package/dist/strategies/delivery-strategy.js.map +1 -0
  36. package/dist/strategies/polling-strategy.d.ts +36 -0
  37. package/dist/strategies/polling-strategy.js +146 -0
  38. package/dist/strategies/polling-strategy.js.map +1 -0
  39. package/dist/strategies/sse-strategy.d.ts +49 -0
  40. package/dist/strategies/sse-strategy.js +266 -0
  41. package/dist/strategies/sse-strategy.js.map +1 -0
  42. package/dist/types/index.d.ts +434 -0
  43. package/dist/types/index.js +127 -0
  44. package/dist/types/index.js.map +1 -0
  45. package/dist/utils/email-utils.d.ts +19 -0
  46. package/dist/utils/email-utils.js +92 -0
  47. package/dist/utils/email-utils.js.map +1 -0
  48. package/dist/utils/sleep.d.ts +6 -0
  49. package/dist/utils/sleep.js +9 -0
  50. package/dist/utils/sleep.js.map +1 -0
  51. package/package.json +85 -0
package/dist/email.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Email model - represents a decrypted email with convenient accessors
3
+ */
4
+ /**
5
+ * Represents a decrypted email with convenient accessors for its content and metadata.
6
+ */
7
+ import createDebug from 'debug';
8
+ import { decryptRaw } from './crypto/decrypt.js';
9
+ const debug = createDebug('vaultsandbox:email');
10
+ /**
11
+ * Provides a summary of email authentication results (SPF, DKIM, DMARC).
12
+ */
13
+ class AuthResults {
14
+ /** The SPF (Sender Policy Framework) validation result. */
15
+ spf;
16
+ /** An array of DKIM (DomainKeys Identified Mail) validation results. */
17
+ dkim;
18
+ /** The DMARC (Domain-based Message Authentication, Reporting, and Conformance) validation result. */
19
+ dmarc;
20
+ /** The reverse DNS validation result. */
21
+ reverseDns;
22
+ /**
23
+ * @internal
24
+ */
25
+ constructor(data) {
26
+ this.spf = data.spf;
27
+ this.dkim = data.dkim;
28
+ this.dmarc = data.dmarc;
29
+ this.reverseDns = data.reverseDns;
30
+ debug('Created AuthResults with SPF: %O, DKIM: %O, DMARC: %O, ReverseDNS: %O', this.spf, this.dkim, this.dmarc, this.reverseDns);
31
+ }
32
+ /**
33
+ * Validates the authentication results and provides a summary.
34
+ *
35
+ * @returns An `AuthValidation` object with the overall status and a list of failures.
36
+ */
37
+ validate() {
38
+ debug('Validating email authentication results');
39
+ const failures = [];
40
+ // Check SPF
41
+ const spfPassed = this.spf?.status === 'pass';
42
+ if (this.spf && !spfPassed) {
43
+ failures.push(`SPF check failed: ${this.spf.status}${this.spf.domain ? ` (domain: ${this.spf.domain})` : ''}`);
44
+ }
45
+ // Check DKIM (at least one signature must pass)
46
+ const dkimPassed = this.dkim?.some((d) => d.status === 'pass') ?? false;
47
+ if (this.dkim && this.dkim.length > 0 && !dkimPassed) {
48
+ const failedDomains = this.dkim
49
+ .filter((d) => d.status !== 'pass')
50
+ .map((d) => d.domain)
51
+ .filter(Boolean)
52
+ .join(', ');
53
+ failures.push(`DKIM signature failed${failedDomains ? `: ${failedDomains}` : ''}`);
54
+ }
55
+ // Check DMARC
56
+ const dmarcPassed = this.dmarc?.status === 'pass';
57
+ if (this.dmarc && !dmarcPassed) {
58
+ failures.push(`DMARC policy: ${this.dmarc.status}${this.dmarc.policy ? ` (policy: ${this.dmarc.policy})` : ''}`);
59
+ }
60
+ // Check Reverse DNS
61
+ const reverseDnsPassed = this.reverseDns?.status === 'pass';
62
+ if (this.reverseDns && !reverseDnsPassed) {
63
+ failures.push(`Reverse DNS check failed: ${this.reverseDns.status}${this.reverseDns.hostname ? ` (hostname: ${this.reverseDns.hostname})` : ''}`);
64
+ }
65
+ const validation = {
66
+ passed: spfPassed && dkimPassed && dmarcPassed,
67
+ spfPassed,
68
+ dkimPassed,
69
+ dmarcPassed,
70
+ reverseDnsPassed,
71
+ failures,
72
+ };
73
+ debug('Authentication validation result: %O', validation);
74
+ return validation;
75
+ }
76
+ }
77
+ /**
78
+ * Represents a fully decrypted email, providing access to its content,
79
+ * attachments, and metadata.
80
+ */
81
+ export class Email {
82
+ /** The unique identifier for the email. */
83
+ id;
84
+ /** The sender's email address. */
85
+ from;
86
+ /** An array of recipient email addresses. */
87
+ to;
88
+ /** The subject of the email. */
89
+ subject;
90
+ /** The date and time the email was received. */
91
+ receivedAt;
92
+ /** A boolean indicating whether the email has been read. */
93
+ isRead;
94
+ /** The plain text content of the email, or `null` if not available. */
95
+ text;
96
+ /** The HTML content of the email, or `null` if not available. */
97
+ html;
98
+ /** An array of attachments found in the email. */
99
+ attachments;
100
+ /** An array of URLs extracted from the email's content. */
101
+ links;
102
+ /** An object containing the email's headers. */
103
+ headers;
104
+ /** The email's authentication results (SPF, DKIM, DMARC). */
105
+ authResults;
106
+ /** Any other metadata associated with the email. */
107
+ metadata;
108
+ emailAddress;
109
+ apiClient;
110
+ keypair;
111
+ /**
112
+ * @internal
113
+ * Do not construct this class directly.
114
+ */
115
+ constructor(emailData, metadata, parsed, emailAddress, apiClient, keypair) {
116
+ this.id = emailData.id;
117
+ this.from = metadata.from;
118
+ this.to = Array.isArray(metadata.to) ? metadata.to : [metadata.to].filter(Boolean);
119
+ this.subject = metadata.subject;
120
+ const receivedAtValue = metadata.receivedAt ?? emailData.receivedAt ?? Date.now();
121
+ this.receivedAt = new Date(receivedAtValue);
122
+ this.isRead = emailData.isRead;
123
+ this.emailAddress = emailAddress;
124
+ this.apiClient = apiClient;
125
+ this.keypair = keypair;
126
+ debug('Creating email %s from %s to %s', this.id, this.from, Array.isArray(this.to) ? this.to.join(', ') : this.to);
127
+ // If parsed content is available, use it
128
+ if (parsed) {
129
+ this.text = parsed.text;
130
+ this.html = parsed.html;
131
+ this.headers = parsed.headers;
132
+ this.attachments = parsed.attachments || [];
133
+ this.links = parsed.links || [];
134
+ this.authResults = new AuthResults(parsed.authResults || {});
135
+ debug('Email %s created with full parsed content (%d attachments, %d links)', this.id, this.attachments.length, this.links.length);
136
+ }
137
+ else {
138
+ // Metadata only (SSE notification without full fetch)
139
+ this.text = null;
140
+ this.html = null;
141
+ this.headers = {};
142
+ this.attachments = [];
143
+ this.links = [];
144
+ this.authResults = new AuthResults({});
145
+ debug('Email %s created with metadata only', this.id);
146
+ }
147
+ this.metadata = {};
148
+ }
149
+ /**
150
+ * Marks this email as read.
151
+ *
152
+ * @returns A promise that resolves when the email is marked as read.
153
+ */
154
+ async markAsRead() {
155
+ debug('Marking email %s as read', this.id);
156
+ await this.apiClient.markEmailAsRead(this.emailAddress, this.id);
157
+ // The isRead property is readonly for external consumers to prevent accidental modification,
158
+ // but we need to update it after the API call succeeds. This mapped type temporarily removes
159
+ // the readonly modifier to allow the internal update while maintaining the public API contract.
160
+ this.isRead = true;
161
+ debug('Successfully marked email %s as read', this.id);
162
+ }
163
+ /**
164
+ * Deletes this email from the inbox.
165
+ *
166
+ * @returns A promise that resolves when the email is deleted.
167
+ */
168
+ async delete() {
169
+ debug('Deleting email %s', this.id);
170
+ await this.apiClient.deleteEmail(this.emailAddress, this.id);
171
+ debug('Successfully deleted email %s', this.id);
172
+ }
173
+ /**
174
+ * Fetches the raw, decrypted source of the email.
175
+ *
176
+ * @returns A promise that resolves to the raw email data.
177
+ */
178
+ async getRaw() {
179
+ debug('Fetching raw content for email %s', this.id);
180
+ const rawEmailData = await this.apiClient.getRawEmail(this.emailAddress, this.id);
181
+ const raw = await decryptRaw(rawEmailData.encryptedRaw, this.keypair);
182
+ debug('Successfully fetched and decrypted raw content for email %s (%d characters)', this.id, raw.length);
183
+ return { id: rawEmailData.id, raw };
184
+ }
185
+ }
186
+ //# sourceMappingURL=email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * HTTP API client for VaultSandbox Gateway
3
+ */
4
+ import type { ClientConfig, InboxData, EmailData, ServerInfo, SyncStatus, RawEmailData } from '../types/index.js';
5
+ /**
6
+ * HTTP API client for interacting with the VaultSandbox Gateway server.
7
+ * Handles all API communication including inbox management, email operations,
8
+ * and server information retrieval with built-in retry logic.
9
+ */
10
+ export declare class ApiClient {
11
+ private client;
12
+ private config;
13
+ /**
14
+ * Creates a new API client instance.
15
+ * @param config - Configuration object containing URL, API key, and retry settings
16
+ */
17
+ constructor(config: ClientConfig);
18
+ /**
19
+ * Configures automatic retry logic for failed HTTP requests.
20
+ * Retries are performed with exponential backoff for specific HTTP status codes.
21
+ * @private
22
+ */
23
+ private setupRetry;
24
+ /**
25
+ * Converts Axios errors into domain-specific error types.
26
+ * @param error - The Axios error to handle
27
+ * @returns A domain-specific error (NetworkError, InboxNotFoundError, EmailNotFoundError, or ApiError)
28
+ * @private
29
+ */
30
+ private handleError;
31
+ /**
32
+ * Retrieves information about the VaultSandbox Gateway server.
33
+ * @returns Promise resolving to server information including version and capabilities
34
+ * @throws {NetworkError} If network communication fails
35
+ * @throws {ApiError} If the server returns an error response
36
+ */
37
+ getServerInfo(): Promise<ServerInfo>;
38
+ /**
39
+ * Validates that the configured API key is valid.
40
+ * @returns Promise resolving to an object indicating if the key is valid
41
+ * @throws {NetworkError} If network communication fails
42
+ * @throws {ApiError} If the server returns an error response
43
+ */
44
+ checkKey(): Promise<boolean>;
45
+ /**
46
+ * Creates a new temporary inbox on the server.
47
+ * @param publicKey - The client's KEM public key for encrypted communication
48
+ * @param ttl - Optional time-to-live in seconds for the inbox
49
+ * @param emailAddress - Optional desired email address or domain
50
+ * @returns Promise resolving to the created inbox data including email address
51
+ * @throws {NetworkError} If network communication fails
52
+ * @throws {ApiError} If the server returns an error response
53
+ */
54
+ createInbox(publicKey: string, ttl?: number, emailAddress?: string): Promise<InboxData>;
55
+ /**
56
+ * Deletes a specific inbox and all its emails.
57
+ * @param emailAddress - The email address of the inbox to delete
58
+ * @returns Promise that resolves when the inbox is deleted
59
+ * @throws {NetworkError} If network communication fails
60
+ * @throws {InboxNotFoundError} If the inbox does not exist
61
+ * @throws {ApiError} If the server returns an error response
62
+ */
63
+ deleteInbox(emailAddress: string): Promise<void>;
64
+ /**
65
+ * Deletes all inboxes associated with the API key.
66
+ * @returns Promise resolving to the number of inboxes deleted
67
+ * @throws {NetworkError} If network communication fails
68
+ * @throws {ApiError} If the server returns an error response
69
+ */
70
+ deleteAllInboxes(): Promise<{
71
+ deleted: number;
72
+ }>;
73
+ /**
74
+ * Gets the email synchronization status for an inbox.
75
+ * @param emailAddress - The email address of the inbox
76
+ * @returns Promise resolving to the sync status including last sync time and email count
77
+ * @throws {NetworkError} If network communication fails
78
+ * @throws {InboxNotFoundError} If the inbox does not exist
79
+ * @throws {ApiError} If the server returns an error response
80
+ */
81
+ getSyncStatus(emailAddress: string): Promise<SyncStatus>;
82
+ /**
83
+ * Lists all emails in an inbox.
84
+ * @param emailAddress - The email address of the inbox
85
+ * @returns Promise resolving to an array of emails
86
+ * @throws {NetworkError} If network communication fails
87
+ * @throws {InboxNotFoundError} If the inbox does not exist
88
+ * @throws {ApiError} If the server returns an error response
89
+ */
90
+ listEmails(emailAddress: string): Promise<EmailData[]>;
91
+ /**
92
+ * Retrieves a specific email by ID.
93
+ * @param emailAddress - The email address of the inbox
94
+ * @param emailId - The unique identifier of the email
95
+ * @returns Promise resolving to the email data
96
+ * @throws {NetworkError} If network communication fails
97
+ * @throws {InboxNotFoundError} If the inbox does not exist
98
+ * @throws {EmailNotFoundError} If the email does not exist
99
+ * @throws {ApiError} If the server returns an error response
100
+ */
101
+ getEmail(emailAddress: string, emailId: string): Promise<EmailData>;
102
+ /**
103
+ * Retrieves the raw email data including full headers and body.
104
+ * @param emailAddress - The email address of the inbox
105
+ * @param emailId - The unique identifier of the email
106
+ * @returns Promise resolving to the raw email data
107
+ * @throws {NetworkError} If network communication fails
108
+ * @throws {InboxNotFoundError} If the inbox does not exist
109
+ * @throws {EmailNotFoundError} If the email does not exist
110
+ * @throws {ApiError} If the server returns an error response
111
+ */
112
+ getRawEmail(emailAddress: string, emailId: string): Promise<RawEmailData>;
113
+ /**
114
+ * Marks an email as read.
115
+ * @param emailAddress - The email address of the inbox
116
+ * @param emailId - The unique identifier of the email
117
+ * @returns Promise that resolves when the email is marked as read
118
+ * @throws {NetworkError} If network communication fails
119
+ * @throws {InboxNotFoundError} If the inbox does not exist
120
+ * @throws {EmailNotFoundError} If the email does not exist
121
+ * @throws {ApiError} If the server returns an error response
122
+ */
123
+ markEmailAsRead(emailAddress: string, emailId: string): Promise<void>;
124
+ /**
125
+ * Deletes a specific email from an inbox.
126
+ * @param emailAddress - The email address of the inbox
127
+ * @param emailId - The unique identifier of the email
128
+ * @returns Promise that resolves when the email is deleted
129
+ * @throws {NetworkError} If network communication fails
130
+ * @throws {InboxNotFoundError} If the inbox does not exist
131
+ * @throws {EmailNotFoundError} If the email does not exist
132
+ * @throws {ApiError} If the server returns an error response
133
+ */
134
+ deleteEmail(emailAddress: string, emailId: string): Promise<void>;
135
+ /**
136
+ * Gets the base URL of the VaultSandbox Gateway server.
137
+ * @returns The configured base URL
138
+ */
139
+ getBaseUrl(): string;
140
+ /**
141
+ * Gets the configured API key.
142
+ * @returns The API key being used for authentication
143
+ */
144
+ getApiKey(): string;
145
+ }
@@ -0,0 +1,242 @@
1
+ /**
2
+ * HTTP API client for VaultSandbox Gateway
3
+ */
4
+ import axios from 'axios';
5
+ import { ApiError, NetworkError, InboxNotFoundError, EmailNotFoundError } from '../types/index.js';
6
+ import { sleep } from '../utils/sleep.js';
7
+ /**
8
+ * HTTP API client for interacting with the VaultSandbox Gateway server.
9
+ * Handles all API communication including inbox management, email operations,
10
+ * and server information retrieval with built-in retry logic.
11
+ */
12
+ export class ApiClient {
13
+ client;
14
+ config;
15
+ /**
16
+ * Creates a new API client instance.
17
+ * @param config - Configuration object containing URL, API key, and retry settings
18
+ */
19
+ constructor(config) {
20
+ this.config = config;
21
+ this.client = axios.create({
22
+ baseURL: config.url,
23
+ headers: {
24
+ 'X-API-Key': config.apiKey,
25
+ 'Content-Type': 'application/json',
26
+ },
27
+ timeout: 30000,
28
+ });
29
+ // Setup retry logic
30
+ this.setupRetry();
31
+ }
32
+ /**
33
+ * Configures automatic retry logic for failed HTTP requests.
34
+ * Retries are performed with exponential backoff for specific HTTP status codes.
35
+ * @private
36
+ */
37
+ setupRetry() {
38
+ this.client.interceptors.response.use((response) => response, async (error) => {
39
+ const config = error.config;
40
+ const maxRetries = this.config.maxRetries ?? 3;
41
+ const retryDelay = this.config.retryDelay ?? 1000;
42
+ const retryOn = this.config.retryOn ?? [408, 429, 500, 502, 503, 504];
43
+ // Early return if no config
44
+ if (!config) {
45
+ throw error;
46
+ }
47
+ // Use a custom property on the config object to track retries
48
+ const requestConfig = config;
49
+ if (!requestConfig.__retryCount) {
50
+ requestConfig.__retryCount = 0;
51
+ }
52
+ const retryCount = requestConfig.__retryCount;
53
+ const shouldRetry = retryCount < maxRetries && error.response && retryOn.includes(error.response.status);
54
+ if (shouldRetry && config) {
55
+ requestConfig.__retryCount = retryCount + 1;
56
+ await sleep(retryDelay * Math.pow(2, retryCount));
57
+ return this.client.request(config);
58
+ }
59
+ throw this.handleError(error);
60
+ });
61
+ }
62
+ /**
63
+ * Converts Axios errors into domain-specific error types.
64
+ * @param error - The Axios error to handle
65
+ * @returns A domain-specific error (NetworkError, InboxNotFoundError, EmailNotFoundError, or ApiError)
66
+ * @private
67
+ */
68
+ handleError(error) {
69
+ if (!error.response) {
70
+ return new NetworkError(error.message || 'Network error occurred');
71
+ }
72
+ const status = error.response.status;
73
+ const message = error.response.data?.error || error.message;
74
+ if (status === 404) {
75
+ if (message.toLowerCase().includes('inbox')) {
76
+ return new InboxNotFoundError(message);
77
+ }
78
+ if (message.toLowerCase().includes('email')) {
79
+ return new EmailNotFoundError(message);
80
+ }
81
+ }
82
+ return new ApiError(status, message);
83
+ }
84
+ // ===== Server Info =====
85
+ /**
86
+ * Retrieves information about the VaultSandbox Gateway server.
87
+ * @returns Promise resolving to server information including version and capabilities
88
+ * @throws {NetworkError} If network communication fails
89
+ * @throws {ApiError} If the server returns an error response
90
+ */
91
+ async getServerInfo() {
92
+ const response = await this.client.get('/api/server-info');
93
+ return response.data;
94
+ }
95
+ /**
96
+ * Validates that the configured API key is valid.
97
+ * @returns Promise resolving to an object indicating if the key is valid
98
+ * @throws {NetworkError} If network communication fails
99
+ * @throws {ApiError} If the server returns an error response
100
+ */
101
+ async checkKey() {
102
+ const response = await this.client.get('/api/check-key');
103
+ return response.data.ok;
104
+ }
105
+ // ===== Inbox Management =====
106
+ /**
107
+ * Creates a new temporary inbox on the server.
108
+ * @param publicKey - The client's KEM public key for encrypted communication
109
+ * @param ttl - Optional time-to-live in seconds for the inbox
110
+ * @param emailAddress - Optional desired email address or domain
111
+ * @returns Promise resolving to the created inbox data including email address
112
+ * @throws {NetworkError} If network communication fails
113
+ * @throws {ApiError} If the server returns an error response
114
+ */
115
+ async createInbox(publicKey, ttl, emailAddress) {
116
+ const payload = { clientKemPk: publicKey };
117
+ if (ttl !== undefined && ttl !== null) {
118
+ payload.ttl = ttl;
119
+ }
120
+ if (emailAddress !== undefined && emailAddress !== null) {
121
+ payload.emailAddress = emailAddress;
122
+ }
123
+ const response = await this.client.post('/api/inboxes', payload);
124
+ return response.data;
125
+ }
126
+ /**
127
+ * Deletes a specific inbox and all its emails.
128
+ * @param emailAddress - The email address of the inbox to delete
129
+ * @returns Promise that resolves when the inbox is deleted
130
+ * @throws {NetworkError} If network communication fails
131
+ * @throws {InboxNotFoundError} If the inbox does not exist
132
+ * @throws {ApiError} If the server returns an error response
133
+ */
134
+ async deleteInbox(emailAddress) {
135
+ await this.client.delete(`/api/inboxes/${encodeURIComponent(emailAddress)}`);
136
+ }
137
+ /**
138
+ * Deletes all inboxes associated with the API key.
139
+ * @returns Promise resolving to the number of inboxes deleted
140
+ * @throws {NetworkError} If network communication fails
141
+ * @throws {ApiError} If the server returns an error response
142
+ */
143
+ async deleteAllInboxes() {
144
+ const response = await this.client.delete('/api/inboxes');
145
+ return response.data;
146
+ }
147
+ /**
148
+ * Gets the email synchronization status for an inbox.
149
+ * @param emailAddress - The email address of the inbox
150
+ * @returns Promise resolving to the sync status including last sync time and email count
151
+ * @throws {NetworkError} If network communication fails
152
+ * @throws {InboxNotFoundError} If the inbox does not exist
153
+ * @throws {ApiError} If the server returns an error response
154
+ */
155
+ async getSyncStatus(emailAddress) {
156
+ const response = await this.client.get(`/api/inboxes/${encodeURIComponent(emailAddress)}/sync`);
157
+ return response.data;
158
+ }
159
+ // ===== Email Management =====
160
+ /**
161
+ * Lists all emails in an inbox.
162
+ * @param emailAddress - The email address of the inbox
163
+ * @returns Promise resolving to an array of emails
164
+ * @throws {NetworkError} If network communication fails
165
+ * @throws {InboxNotFoundError} If the inbox does not exist
166
+ * @throws {ApiError} If the server returns an error response
167
+ */
168
+ async listEmails(emailAddress) {
169
+ const response = await this.client.get(`/api/inboxes/${encodeURIComponent(emailAddress)}/emails`);
170
+ return response.data;
171
+ }
172
+ /**
173
+ * Retrieves a specific email by ID.
174
+ * @param emailAddress - The email address of the inbox
175
+ * @param emailId - The unique identifier of the email
176
+ * @returns Promise resolving to the email data
177
+ * @throws {NetworkError} If network communication fails
178
+ * @throws {InboxNotFoundError} If the inbox does not exist
179
+ * @throws {EmailNotFoundError} If the email does not exist
180
+ * @throws {ApiError} If the server returns an error response
181
+ */
182
+ async getEmail(emailAddress, emailId) {
183
+ const response = await this.client.get(`/api/inboxes/${encodeURIComponent(emailAddress)}/emails/${emailId}`);
184
+ return response.data;
185
+ }
186
+ /**
187
+ * Retrieves the raw email data including full headers and body.
188
+ * @param emailAddress - The email address of the inbox
189
+ * @param emailId - The unique identifier of the email
190
+ * @returns Promise resolving to the raw email data
191
+ * @throws {NetworkError} If network communication fails
192
+ * @throws {InboxNotFoundError} If the inbox does not exist
193
+ * @throws {EmailNotFoundError} If the email does not exist
194
+ * @throws {ApiError} If the server returns an error response
195
+ */
196
+ async getRawEmail(emailAddress, emailId) {
197
+ const response = await this.client.get(`/api/inboxes/${encodeURIComponent(emailAddress)}/emails/${emailId}/raw`);
198
+ return response.data;
199
+ }
200
+ /**
201
+ * Marks an email as read.
202
+ * @param emailAddress - The email address of the inbox
203
+ * @param emailId - The unique identifier of the email
204
+ * @returns Promise that resolves when the email is marked as read
205
+ * @throws {NetworkError} If network communication fails
206
+ * @throws {InboxNotFoundError} If the inbox does not exist
207
+ * @throws {EmailNotFoundError} If the email does not exist
208
+ * @throws {ApiError} If the server returns an error response
209
+ */
210
+ async markEmailAsRead(emailAddress, emailId) {
211
+ await this.client.patch(`/api/inboxes/${encodeURIComponent(emailAddress)}/emails/${emailId}/read`);
212
+ }
213
+ /**
214
+ * Deletes a specific email from an inbox.
215
+ * @param emailAddress - The email address of the inbox
216
+ * @param emailId - The unique identifier of the email
217
+ * @returns Promise that resolves when the email is deleted
218
+ * @throws {NetworkError} If network communication fails
219
+ * @throws {InboxNotFoundError} If the inbox does not exist
220
+ * @throws {EmailNotFoundError} If the email does not exist
221
+ * @throws {ApiError} If the server returns an error response
222
+ */
223
+ async deleteEmail(emailAddress, emailId) {
224
+ await this.client.delete(`/api/inboxes/${encodeURIComponent(emailAddress)}/emails/${emailId}`);
225
+ }
226
+ // ===== Utility =====
227
+ /**
228
+ * Gets the base URL of the VaultSandbox Gateway server.
229
+ * @returns The configured base URL
230
+ */
231
+ getBaseUrl() {
232
+ return this.config.url;
233
+ }
234
+ /**
235
+ * Gets the configured API key.
236
+ * @returns The API key being used for authentication
237
+ */
238
+ getApiKey() {
239
+ return this.config.apiKey;
240
+ }
241
+ }
242
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/http/api-client.ts"],"names":[],"mappings":"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"}