@stablyai/email 0.1.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 +138 -0
- package/dist/index.cjs +456 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +272 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +272 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.d.ts +272 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +452 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +44 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import * as z4 from 'zod/v4/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Schema type for structured extraction. Supports Zod v4 schemas.
|
|
5
|
+
*/
|
|
6
|
+
type ExtractSchema = {
|
|
7
|
+
safeParseAsync(data: unknown, params?: z4.ParseContext<z4.$ZodIssue>): Promise<z4.util.SafeParseResult<z4.output<any>>>;
|
|
8
|
+
} & z4.$ZodType;
|
|
9
|
+
/** Output type inferred from a schema. */
|
|
10
|
+
type SchemaOutput<T extends ExtractSchema> = z4.output<T>;
|
|
11
|
+
/** Result from email extraction. */
|
|
12
|
+
type ExtractResult<T> = {
|
|
13
|
+
data: T;
|
|
14
|
+
reason: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Error thrown when email extraction fails.
|
|
18
|
+
*/
|
|
19
|
+
declare class EmailExtractionError extends Error {
|
|
20
|
+
/** The reason extraction failed. */
|
|
21
|
+
readonly reason: string;
|
|
22
|
+
constructor(message: string, reason: string);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** An email address with optional display name. */
|
|
26
|
+
type EmailAddress = {
|
|
27
|
+
/** The email address (e.g., "user@example.com"). */
|
|
28
|
+
address: string;
|
|
29
|
+
/** Optional display name (e.g., "John Doe"). */
|
|
30
|
+
name?: string;
|
|
31
|
+
};
|
|
32
|
+
/** An email message. */
|
|
33
|
+
type Email = {
|
|
34
|
+
/** Unique identifier for the email. */
|
|
35
|
+
id: string;
|
|
36
|
+
/** The mailbox containing this email (e.g., "INBOX"). */
|
|
37
|
+
mailbox: string;
|
|
38
|
+
/** The sender's email address. */
|
|
39
|
+
from: EmailAddress;
|
|
40
|
+
/** The recipient email addresses. */
|
|
41
|
+
to: EmailAddress[];
|
|
42
|
+
/** The email subject line. */
|
|
43
|
+
subject: string;
|
|
44
|
+
/** When the email was received. */
|
|
45
|
+
receivedAt: Date;
|
|
46
|
+
/** HTML content of the email body, if available. */
|
|
47
|
+
html?: string[];
|
|
48
|
+
/** Plain text content of the email body, if available. */
|
|
49
|
+
text?: string;
|
|
50
|
+
};
|
|
51
|
+
/** Options for listing emails in an inbox. */
|
|
52
|
+
type ListEmailsOptions = {
|
|
53
|
+
/** Filter by sender email address. */
|
|
54
|
+
from?: string;
|
|
55
|
+
/** Filter by subject line. */
|
|
56
|
+
subject?: string;
|
|
57
|
+
/** How to match the subject: "contains" (default) or "exact". */
|
|
58
|
+
subjectMatch?: "contains" | "exact";
|
|
59
|
+
/** Maximum number of emails to return. */
|
|
60
|
+
limit?: number;
|
|
61
|
+
/** Pagination cursor from a previous response. */
|
|
62
|
+
cursor?: string;
|
|
63
|
+
/** Only return emails received after this date. Overrides the default createdAt filter. */
|
|
64
|
+
since?: Date;
|
|
65
|
+
/** Set to true to include emails received before the inbox was created. */
|
|
66
|
+
includeOlder?: boolean;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Options for waiting for an email to arrive. */
|
|
70
|
+
type WaitForEmailOptions = {
|
|
71
|
+
/** Filter by sender email address. */
|
|
72
|
+
from?: string;
|
|
73
|
+
/** Filter by subject line. */
|
|
74
|
+
subject?: string;
|
|
75
|
+
/** How to match the subject: "contains" (default) or "exact". */
|
|
76
|
+
subjectMatch?: "contains" | "exact";
|
|
77
|
+
/** Maximum time to wait. @default 120000 (2 minutes) */
|
|
78
|
+
timeoutMs?: number;
|
|
79
|
+
/** Time between poll attempts. Minimum 1000ms. @default 3000 (3 seconds) */
|
|
80
|
+
pollIntervalMs?: number;
|
|
81
|
+
};
|
|
82
|
+
/** Error thrown when waitForEmail() times out without finding a matching email. */
|
|
83
|
+
declare class EmailTimeoutError extends Error {
|
|
84
|
+
constructor(message: string);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Options for creating an inbox instance. */
|
|
88
|
+
type GetInboxOptions = {
|
|
89
|
+
/** Optional suffix for test isolation (e.g., "test-123" creates "org+test-123@mail.stably.ai"). */
|
|
90
|
+
suffix?: string;
|
|
91
|
+
/** Stably API key. Defaults to STABLY_API_KEY environment variable. */
|
|
92
|
+
apiKey?: string;
|
|
93
|
+
/** Stably project ID. Defaults to STABLY_PROJECT_ID environment variable. */
|
|
94
|
+
projectId?: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* An email inbox scoped to a specific address.
|
|
98
|
+
*
|
|
99
|
+
* Use {@link Inbox.build} to create an instance. All operations are automatically
|
|
100
|
+
* scoped to this inbox's address and creation time for test isolation.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const inbox = await Inbox.build({ suffix: `test-${Date.now()}` });
|
|
105
|
+
* console.log(inbox.address); // "org+test-123@mail.stably.ai"
|
|
106
|
+
*
|
|
107
|
+
* const { emails } = await inbox.listEmails({ subject: 'verification' });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare class Inbox {
|
|
111
|
+
/** The full email address for this inbox (includes suffix if provided). */
|
|
112
|
+
readonly address: string;
|
|
113
|
+
/** The suffix used when creating this inbox, if any. */
|
|
114
|
+
readonly suffix?: string;
|
|
115
|
+
/** When this inbox instance was created. Used for filtering out older emails. */
|
|
116
|
+
readonly createdAt: Date;
|
|
117
|
+
private readonly baseAddress;
|
|
118
|
+
private readonly client;
|
|
119
|
+
private readonly projectId;
|
|
120
|
+
/** @internal Use {@link Inbox.build} to create an Inbox instance. */
|
|
121
|
+
private constructor();
|
|
122
|
+
/**
|
|
123
|
+
* Creates an inbox instance for receiving and managing test emails.
|
|
124
|
+
*
|
|
125
|
+
* @param options - Configuration options including optional suffix for test isolation.
|
|
126
|
+
* @returns An inbox instance scoped to your organization's email address.
|
|
127
|
+
* @throws Error if API key or project ID is missing and not set in environment.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* // Use environment variables (STABLY_API_KEY, STABLY_PROJECT_ID)
|
|
132
|
+
* const inbox = await Inbox.build();
|
|
133
|
+
*
|
|
134
|
+
* // With suffix for test isolation
|
|
135
|
+
* const inbox = await Inbox.build({ suffix: `test-${Date.now()}` });
|
|
136
|
+
* console.log(inbox.address); // "my-org+test-1234567890@mail.stably.ai"
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
static build(options?: GetInboxOptions): Promise<Inbox>;
|
|
140
|
+
/**
|
|
141
|
+
* Lists emails in this inbox.
|
|
142
|
+
*
|
|
143
|
+
* By default, only returns emails received **after this `Inbox` was created**
|
|
144
|
+
* (via `Inbox.build()`). This prevents stale emails from previous test runs
|
|
145
|
+
* from appearing in results. Use `includeOlder: true` to include older emails.
|
|
146
|
+
*
|
|
147
|
+
* @param options - Filter and pagination options.
|
|
148
|
+
* @returns The matching emails and an optional cursor for pagination.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* const { emails } = await inbox.listEmails();
|
|
153
|
+
* const { emails } = await inbox.listEmails({ includeOlder: true });
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
listEmails(options?: ListEmailsOptions): Promise<{
|
|
157
|
+
emails: Email[];
|
|
158
|
+
nextCursor?: string;
|
|
159
|
+
}>;
|
|
160
|
+
/**
|
|
161
|
+
* Gets a specific email by ID.
|
|
162
|
+
*
|
|
163
|
+
* @param id - The email ID to retrieve (from {@link Inbox.listEmails}).
|
|
164
|
+
* @returns The email with the given ID.
|
|
165
|
+
* @throws Error if the email is not found or API call fails.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* const { emails } = await inbox.listEmails();
|
|
170
|
+
* const email = await inbox.getEmail(emails[0].id);
|
|
171
|
+
* console.log(email.subject);
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
getEmail(id: string): Promise<Email>;
|
|
175
|
+
/**
|
|
176
|
+
* Deletes an email from this inbox.
|
|
177
|
+
*
|
|
178
|
+
* @param id - The unique identifier of the email to delete.
|
|
179
|
+
* @throws Error if the email doesn't exist or deletion fails.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* const { emails } = await inbox.listEmails({ subject: 'old notification' });
|
|
184
|
+
* if (emails.length > 0) {
|
|
185
|
+
* await inbox.deleteEmail(emails[0].id);
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
deleteEmail(id: string): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Deletes all emails sent to this inbox's address.
|
|
192
|
+
*
|
|
193
|
+
* If the inbox was created with a suffix, only emails sent to that specific
|
|
194
|
+
* suffixed address are deleted (e.g., "org+test-123@mail.stably.ai"), not
|
|
195
|
+
* the entire org mailbox.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* const inbox = await Inbox.build({ suffix: `test-${Date.now()}` });
|
|
200
|
+
* // ... receive and process emails ...
|
|
201
|
+
* await inbox.deleteAllEmails(); // Only deletes emails sent to this suffix
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
deleteAllEmails(): Promise<void>;
|
|
205
|
+
/**
|
|
206
|
+
* Waits for an email matching the filters to arrive.
|
|
207
|
+
*
|
|
208
|
+
* Only returns emails received after the inbox was created, preventing
|
|
209
|
+
* stale emails from previous test runs from being matched.
|
|
210
|
+
*
|
|
211
|
+
* @param options - Filter and timeout options.
|
|
212
|
+
* @returns The first matching email.
|
|
213
|
+
* @throws {EmailTimeoutError} If no matching email arrives within the timeout.
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```ts
|
|
217
|
+
* const email = await inbox.waitForEmail({ subject: 'Welcome' });
|
|
218
|
+
*
|
|
219
|
+
* const email = await inbox.waitForEmail({
|
|
220
|
+
* from: 'noreply@example.com',
|
|
221
|
+
* subject: 'verification',
|
|
222
|
+
* timeoutMs: 60000,
|
|
223
|
+
* pollIntervalMs: 5000,
|
|
224
|
+
* });
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
waitForEmail(options?: WaitForEmailOptions): Promise<Email>;
|
|
228
|
+
/**
|
|
229
|
+
* Extracts data from an email using AI.
|
|
230
|
+
*
|
|
231
|
+
* @param args - The email ID and prompt describing what to extract.
|
|
232
|
+
* @returns The extracted string.
|
|
233
|
+
* @throws {@link EmailExtractionError} if extraction fails.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* const otp = await inbox.extractFromEmail({ id: email.id, prompt: 'Extract the OTP code' });
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
extractFromEmail(args: {
|
|
241
|
+
id: string;
|
|
242
|
+
prompt: string;
|
|
243
|
+
}): Promise<string>;
|
|
244
|
+
/**
|
|
245
|
+
* Extracts structured data from an email using AI with a Zod schema.
|
|
246
|
+
*
|
|
247
|
+
* @param args - The email ID, prompt, and Zod v4 schema for structured output.
|
|
248
|
+
* @returns The extracted data matching the schema type.
|
|
249
|
+
* @throws {@link EmailExtractionError} if extraction fails.
|
|
250
|
+
* @throws Error if schema validation fails or Zod v4 is not installed.
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* import { z } from 'zod/v4';
|
|
255
|
+
*
|
|
256
|
+
* const { code, expiresAt } = await inbox.extractFromEmail({
|
|
257
|
+
* id: email.id,
|
|
258
|
+
* prompt: 'Extract the verification code and expiry',
|
|
259
|
+
* schema: z.object({ code: z.string(), expiresAt: z.string() }),
|
|
260
|
+
* });
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
extractFromEmail<T extends ExtractSchema>(args: {
|
|
264
|
+
id: string;
|
|
265
|
+
prompt: string;
|
|
266
|
+
schema: T;
|
|
267
|
+
}): Promise<SchemaOutput<T>>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export { EmailExtractionError, EmailTimeoutError, Inbox };
|
|
271
|
+
export type { Email, EmailAddress, ExtractResult, ExtractSchema, GetInboxOptions, ListEmailsOptions, SchemaOutput, WaitForEmailOptions };
|
|
272
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../src/extract.ts","../src/list.ts","../src/wait-for-email.ts","../src/inbox.ts"],"mappings":";;AAkBA;;;AAGM,KAAM,aAAa;2CAGZ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,IAEpC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM;IAC1C,EAAE,CAAC,QAAQ;AAEf;AACM,KAAM,YAAY,WAAW,aAAa,IAAI,EAAE,CAAC,MAAM;AAE7D;AACM,KAAM,aAAa;;;;AAKzB;;;AAGA,cAAa,oBAAqB,SAAQ,KAAK;;;;;;AClC/C;AACM,KAAM,YAAY;;;;;;AAOxB;AACM,KAAM,KAAK;;;;;;UAMT,YAAY;;QAEd,YAAY;;;;gBAIJ,IAAI;;;;;;AAOlB;AACM,KAAM,iBAAiB;;;;;;;;;;;;YAYnB,IAAI;;;;;ACxCd;AACM,KAAM,mBAAmB;;;;;;;;;;;;AAa/B;AACA,cAAa,iBAAkB,SAAQ,KAAK;;;;ACH5C;AACM,KAAM,eAAe;;;;;;;;AAS3B;;;;;;;;;;;;;;AAcA,cAAa,KAAK;;;;;;wBAMI,IAAI;;;;;;;;;;;;;;;;;;;;;;;2BAqDK,eAAe,GAAG,OAAO,CAAC,KAAK;;;;;;;;;;;;;;;;;yBAqDhD,iBAAiB,GAC1B,OAAO;gBAAW,KAAK;;;;;;;;;;;;;;;;;0BAwBE,OAAO,CAAC,KAAK;;;;;;;;;;;;;;;6BAkCV,OAAO;;;;;;;;;;;;;;;uBAkCb,OAAO;;;;;;;;;;;;;;;;;;;;;;;2BAoCH,mBAAmB,GAAG,OAAO,CAAC,KAAK;;;;;;;;;;;;;;;;QAsBR,OAAO;;;;;;;;;;;;;;;;;;;;+BAoBpC,aAAa;;;;QAIpC,OAAO,CAAC,YAAY","names":[]}
|