groundmail 0.15.1 → 0.17.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 +22 -0
- package/dist/authjs.d.ts +1 -1
- package/dist/authjs.js +1 -1
- package/dist/better-auth.d.ts +1 -1
- package/dist/better-auth.js +1 -1
- package/dist/{chunk-N2LD34ND.js → chunk-MJKAVFFN.js} +30 -1
- package/dist/clerk.d.ts +1 -1
- package/dist/clerk.js +1 -1
- package/dist/{client-DYUh2ub4.d.ts → client-DLz4rpD9.d.ts} +82 -1
- package/dist/index.d.ts +37 -3
- package/dist/index.js +27 -1
- package/dist/payload.d.ts +1 -1
- package/dist/payload.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -25,6 +25,27 @@ const email = await tx.emails.send({
|
|
|
25
25
|
console.log(email.id, email.status)
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
## Testing
|
|
29
|
+
|
|
30
|
+
Use a test key (`gm_test_…`, create one with `tx.apiKeys.create({ test: true })` or in the
|
|
31
|
+
dashboard) to run sends through validation, templates and webhooks without delivering anything.
|
|
32
|
+
Simulator addresses produce a specific outcome with any key and never leave Groundmail:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { simulatorAddress } from 'groundmail'
|
|
36
|
+
|
|
37
|
+
await tx.emails.send({
|
|
38
|
+
from: 'ops@yourdomain.com',
|
|
39
|
+
to: simulatorAddress('bounce', 'signup-42'), // bounce+signup-42@simulator.groundmail.dev
|
|
40
|
+
subject: 'Bounce handling test',
|
|
41
|
+
html: '<p>Simulated.</p>',
|
|
42
|
+
})
|
|
43
|
+
// status `bounced`, then an `email.bounced` webhook with `data.test: true`
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Outcomes: `delivered`, `bounce`, `block`, `complaint`, `suppressed`, `delayed`. Details:
|
|
47
|
+
https://docs.groundmail.dev/testing
|
|
48
|
+
|
|
28
49
|
## Adapters
|
|
29
50
|
|
|
30
51
|
Optional entry points (install peer deps as needed):
|
|
@@ -41,6 +62,7 @@ Optional entry points (install peer deps as needed):
|
|
|
41
62
|
|
|
42
63
|
- Quickstart: https://docs.groundmail.dev/quickstart
|
|
43
64
|
- Node / Nodemailer: https://docs.groundmail.dev/frameworks/node
|
|
65
|
+
- Testing (test keys, simulator): https://docs.groundmail.dev/testing
|
|
44
66
|
- API reference: https://docs.groundmail.dev/api/emails
|
|
45
67
|
- Product: https://groundmail.dev
|
|
46
68
|
|
package/dist/authjs.d.ts
CHANGED
package/dist/authjs.js
CHANGED
package/dist/better-auth.d.ts
CHANGED
package/dist/better-auth.js
CHANGED
|
@@ -773,6 +773,19 @@ var MigrationsResource = class {
|
|
|
773
773
|
body: JSON.stringify(params)
|
|
774
774
|
});
|
|
775
775
|
}
|
|
776
|
+
/** Recent imports (newest first), with totals. */
|
|
777
|
+
async list(params = {}) {
|
|
778
|
+
const query = params.limit ? `?limit=${encodeURIComponent(String(params.limit))}` : "";
|
|
779
|
+
return this.client.request(`/migrations${query}`, { method: "GET" });
|
|
780
|
+
}
|
|
781
|
+
/** The stored report of one import, every request merged. Webhook secrets are not kept. */
|
|
782
|
+
async get(id) {
|
|
783
|
+
return this.client.request(`/migrations/${encodeURIComponent(id)}`, { method: "GET" });
|
|
784
|
+
}
|
|
785
|
+
/** The report as CSV text: one row per domain, webhook and template, plus counts, skips and next steps. */
|
|
786
|
+
async reportCsv(id) {
|
|
787
|
+
return this.client.requestText(`/migrations/${encodeURIComponent(id)}/report`);
|
|
788
|
+
}
|
|
776
789
|
/** The whole import: follows `next_cursor` until done and returns the combined report. */
|
|
777
790
|
async run(params, options = {}) {
|
|
778
791
|
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
@@ -995,6 +1008,7 @@ var EmailsResource = class {
|
|
|
995
1008
|
const search = new URLSearchParams();
|
|
996
1009
|
if (params.limit != null) search.set("limit", String(params.limit));
|
|
997
1010
|
if (params.cursor) search.set("cursor", params.cursor);
|
|
1011
|
+
if (params.test != null) search.set("test", String(params.test));
|
|
998
1012
|
const query = search.toString();
|
|
999
1013
|
return this.client.request(`/emails${query ? `?${query}` : ""}`, {
|
|
1000
1014
|
method: "GET"
|
|
@@ -1179,7 +1193,10 @@ var KeysResource = class {
|
|
|
1179
1193
|
method: "POST",
|
|
1180
1194
|
body: JSON.stringify({
|
|
1181
1195
|
...params.name ? { name: params.name } : {},
|
|
1182
|
-
...params.scope ? { scope: params.scope } : {}
|
|
1196
|
+
...params.scope && !params.scopes?.length ? { scope: params.scope } : {},
|
|
1197
|
+
...params.scopes?.length ? { scopes: params.scopes } : {},
|
|
1198
|
+
...params.allowedDomains?.length ? { allowed_domains: params.allowedDomains } : {},
|
|
1199
|
+
...params.test ? { test: true } : {}
|
|
1183
1200
|
})
|
|
1184
1201
|
});
|
|
1185
1202
|
}
|
|
@@ -1431,6 +1448,18 @@ var Groundmail = class {
|
|
|
1431
1448
|
get fetchImpl() {
|
|
1432
1449
|
return this.options.fetch || fetch;
|
|
1433
1450
|
}
|
|
1451
|
+
/** GET a text body (CSV downloads). Errors are JSON, like every other route. */
|
|
1452
|
+
async requestText(path) {
|
|
1453
|
+
const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
1454
|
+
method: "GET",
|
|
1455
|
+
headers: { Authorization: `Bearer ${this.apiKey}` }
|
|
1456
|
+
});
|
|
1457
|
+
if (!response.ok) {
|
|
1458
|
+
const body = await response.json().catch(() => ({}));
|
|
1459
|
+
throw GroundmailError.fromResponse(response.status, body);
|
|
1460
|
+
}
|
|
1461
|
+
return response.text();
|
|
1462
|
+
}
|
|
1434
1463
|
async request(path, init) {
|
|
1435
1464
|
const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
1436
1465
|
...init,
|
package/dist/clerk.d.ts
CHANGED
package/dist/clerk.js
CHANGED
|
@@ -78,6 +78,8 @@ type SendEmailResult = {
|
|
|
78
78
|
status: string;
|
|
79
79
|
/** Present when some recipients were held back and the email went to the rest. */
|
|
80
80
|
held_back?: HeldBackRecipient[];
|
|
81
|
+
/** `true` on a test send (a `gm_test_…` key or only simulator addresses): nothing was delivered. */
|
|
82
|
+
test?: true;
|
|
81
83
|
};
|
|
82
84
|
/** `details` on `POST /emails` 422 when Groundmail validation held back every `to` recipient. */
|
|
83
85
|
type HeldBackErrorDetails = {
|
|
@@ -111,6 +113,7 @@ type BatchSendEmailResult = {
|
|
|
111
113
|
id?: string;
|
|
112
114
|
status?: string;
|
|
113
115
|
held_back?: HeldBackRecipient[];
|
|
116
|
+
test?: true;
|
|
114
117
|
error?: {
|
|
115
118
|
message: string;
|
|
116
119
|
code?: string;
|
|
@@ -148,6 +151,11 @@ type EmailListItem = {
|
|
|
148
151
|
bounce_type: BounceType | null;
|
|
149
152
|
/** Recipients Groundmail validation held back before sending, with why. Empty when none were. */
|
|
150
153
|
held_back: HeldBackRecipient[];
|
|
154
|
+
/**
|
|
155
|
+
* `true` when the email never reached the mail server: sent with a test key or only to
|
|
156
|
+
* simulator addresses. Its status and events are simulated.
|
|
157
|
+
*/
|
|
158
|
+
test: boolean;
|
|
151
159
|
tags: unknown;
|
|
152
160
|
scheduled_at: string | null;
|
|
153
161
|
cancelled_at: string | null;
|
|
@@ -207,6 +215,8 @@ type ListReceivedEmailsResult = {
|
|
|
207
215
|
type ListEmailsParams = {
|
|
208
216
|
limit?: number;
|
|
209
217
|
cursor?: string;
|
|
218
|
+
/** `true`: only test emails; `false`: only live ones. Omit for both. */
|
|
219
|
+
test?: boolean;
|
|
210
220
|
};
|
|
211
221
|
type ListEmailsResult = {
|
|
212
222
|
emails: EmailListItem[];
|
|
@@ -261,6 +271,12 @@ type ApiKey = {
|
|
|
261
271
|
id: string;
|
|
262
272
|
name: string;
|
|
263
273
|
scope: ApiKeyScope;
|
|
274
|
+
/** Fine-grained scopes (`emails:send`, `domains:read`, …). */
|
|
275
|
+
scopes?: string[];
|
|
276
|
+
/** Domains the key may send from; empty means any verified domain. */
|
|
277
|
+
allowed_domains?: string[];
|
|
278
|
+
/** A test key (`gm_test_…`): its sends are simulated and never delivered. */
|
|
279
|
+
test?: boolean;
|
|
264
280
|
prefix: string;
|
|
265
281
|
created_at: string;
|
|
266
282
|
last_used_at: string | null;
|
|
@@ -277,11 +293,24 @@ type ListApiKeysResult = {
|
|
|
277
293
|
type CreateApiKeyParams = {
|
|
278
294
|
name?: string;
|
|
279
295
|
scope?: ApiKeyScope;
|
|
296
|
+
/** Fine-grained scopes, e.g. `['emails:send']`. Takes precedence over `scope`. */
|
|
297
|
+
scopes?: string[];
|
|
298
|
+
/** Verified domains the key may send from (needs `emails:send`, not `full`). */
|
|
299
|
+
allowedDomains?: string[];
|
|
300
|
+
/**
|
|
301
|
+
* Create a test key (`gm_test_…`): same scopes and checks as a live key, but sends are
|
|
302
|
+
* never delivered. They get simulated events and webhooks and count toward nothing.
|
|
303
|
+
*/
|
|
304
|
+
test?: boolean;
|
|
280
305
|
};
|
|
281
306
|
type CreateApiKeyResult = {
|
|
282
307
|
id: string;
|
|
283
308
|
name: string;
|
|
284
309
|
scope: ApiKeyScope;
|
|
310
|
+
scopes?: string[];
|
|
311
|
+
allowed_domains?: string[];
|
|
312
|
+
/** A test key (`gm_test_…`). */
|
|
313
|
+
test?: boolean;
|
|
285
314
|
prefix: string;
|
|
286
315
|
token: string;
|
|
287
316
|
created_at: string;
|
|
@@ -326,6 +355,8 @@ type EmailWebhookEventPayload = {
|
|
|
326
355
|
bounce_reason?: string | null;
|
|
327
356
|
/** Set on `email.bounced` and `email.failed` when the email bounced: `hard` or `block`. */
|
|
328
357
|
bounce_type?: BounceType | null;
|
|
358
|
+
/** `true` on simulated events (test keys, simulator addresses, `POST /emails/test`). Absent on real mail. */
|
|
359
|
+
test?: true;
|
|
329
360
|
};
|
|
330
361
|
};
|
|
331
362
|
/** `contact.unsubscribed` webhook payload (`scope` distinguishes global vs category opt-out). */
|
|
@@ -881,7 +912,31 @@ type CreateMigrationParams = {
|
|
|
881
912
|
/** `next_cursor` from the previous response, to continue. */
|
|
882
913
|
cursor?: string;
|
|
883
914
|
};
|
|
915
|
+
/**
|
|
916
|
+
* Running totals. Suppressions also count by kind: `bounce`, `complaint`,
|
|
917
|
+
* `unsubscribe`, `manual`, and `product_opt_out` (opt-outs that were never
|
|
918
|
+
* global at the old provider; they stop product email only).
|
|
919
|
+
*/
|
|
884
920
|
type MigrationTotals = Record<string, number>;
|
|
921
|
+
/** One DNS change for a domain, compared with what it publishes today. */
|
|
922
|
+
type MigrationDnsChange = {
|
|
923
|
+
/** `add` a record, `update` an existing one to `value` (SPF), `keep` yours (DMARC), or `done`. */
|
|
924
|
+
action: 'add' | 'update' | 'keep' | 'done';
|
|
925
|
+
type: string;
|
|
926
|
+
host: string;
|
|
927
|
+
value: string;
|
|
928
|
+
purpose: string;
|
|
929
|
+
/** What the name holds today, when relevant. */
|
|
930
|
+
current: string | null;
|
|
931
|
+
note: string | null;
|
|
932
|
+
};
|
|
933
|
+
type MigrationDnsPlan = {
|
|
934
|
+
/** False when DNS could not be read; every record is then listed as `add`. */
|
|
935
|
+
checked: boolean;
|
|
936
|
+
changes: MigrationDnsChange[];
|
|
937
|
+
/** Which old-provider records to keep while switching, and when to remove them. */
|
|
938
|
+
keep_old_records: string;
|
|
939
|
+
};
|
|
885
940
|
type MigrationDomainItem = {
|
|
886
941
|
name: string;
|
|
887
942
|
status: MigrationItemStatus;
|
|
@@ -893,6 +948,8 @@ type MigrationDomainItem = {
|
|
|
893
948
|
value: string;
|
|
894
949
|
purpose: string;
|
|
895
950
|
}>;
|
|
951
|
+
/** Null in a preview, or when the import ran out of time to check. */
|
|
952
|
+
dns_plan: MigrationDnsPlan | null;
|
|
896
953
|
dashboard_url: string | null;
|
|
897
954
|
message: string | null;
|
|
898
955
|
};
|
|
@@ -964,6 +1021,16 @@ type Migration = {
|
|
|
964
1021
|
}> | null;
|
|
965
1022
|
agent_prompt: string | null;
|
|
966
1023
|
};
|
|
1024
|
+
/** A stored import, as listed by `migrations.list()`. Previews are not stored. */
|
|
1025
|
+
type MigrationSummary = {
|
|
1026
|
+
id: string;
|
|
1027
|
+
provider: MigrationProvider;
|
|
1028
|
+
status: Migration['status'];
|
|
1029
|
+
resources: MigrationResource[];
|
|
1030
|
+
started_at: string;
|
|
1031
|
+
finished_at: string | null;
|
|
1032
|
+
totals: Partial<Record<MigrationResource, MigrationTotals>>;
|
|
1033
|
+
};
|
|
967
1034
|
type RunMigrationOptions = {
|
|
968
1035
|
/** Called after each request with the report so far. */
|
|
969
1036
|
onProgress?: (migration: Migration) => void;
|
|
@@ -1079,6 +1146,18 @@ declare class MigrationsResource {
|
|
|
1079
1146
|
create(params: CreateMigrationParams): Promise<{
|
|
1080
1147
|
migration: Migration;
|
|
1081
1148
|
}>;
|
|
1149
|
+
/** Recent imports (newest first), with totals. */
|
|
1150
|
+
list(params?: {
|
|
1151
|
+
limit?: number;
|
|
1152
|
+
}): Promise<{
|
|
1153
|
+
data: MigrationSummary[];
|
|
1154
|
+
}>;
|
|
1155
|
+
/** The stored report of one import, every request merged. Webhook secrets are not kept. */
|
|
1156
|
+
get(id: string): Promise<{
|
|
1157
|
+
migration: Migration;
|
|
1158
|
+
}>;
|
|
1159
|
+
/** The report as CSV text: one row per domain, webhook and template, plus counts, skips and next steps. */
|
|
1160
|
+
reportCsv(id: string): Promise<string>;
|
|
1082
1161
|
/** The whole import: follows `next_cursor` until done and returns the combined report. */
|
|
1083
1162
|
run(params: CreateMigrationParams, options?: RunMigrationOptions): Promise<Migration>;
|
|
1084
1163
|
}
|
|
@@ -1210,7 +1289,9 @@ declare class Groundmail {
|
|
|
1210
1289
|
validate(email: string): Promise<ValidateEmailResult>;
|
|
1211
1290
|
get baseUrl(): string;
|
|
1212
1291
|
get fetchImpl(): typeof fetch;
|
|
1292
|
+
/** GET a text body (CSV downloads). Errors are JSON, like every other route. */
|
|
1293
|
+
requestText(path: string): Promise<string>;
|
|
1213
1294
|
request<T>(path: string, init: RequestInit): Promise<T>;
|
|
1214
1295
|
}
|
|
1215
1296
|
|
|
1216
|
-
export { type EmailWebhookEventPayload as $, type ApiErrorBody as A, type BatchSendEmailResult as B, type CategoryUnsubscribedErrorDetails as C, type DnsRecord as D, type CreateSuppressionParams as E, type CreateTemplateParams as F, Groundmail as G, type CreateWebhookParams as H, DEFAULT_API_BASE_URL as I, type DailyRampLimitErrorDetails as J, type DeliverabilityBucket as K, type DeliverabilityDomainInsight as L, type DeliverabilityInsightsResult as M, type DeliverabilityMailServerRelay as N, type DeliverabilityWindow as O, type DnsProviderName as P, type Domain as Q, type DomainBimiAnalysis as R, type SendEmailResult as S, type DomainDetailResult as T, type DomainDmarcAnalysis as U, type DomainDnsAnalysis as V, type DomainStatus as W, type DomainTlsMode as X, type DomainTrackingDns as Y, type DomainTrackingStatus as Z, type EmailListItem as _, type ApiErrorCode as a,
|
|
1297
|
+
export { type EmailWebhookEventPayload as $, type ApiErrorBody as A, type BatchSendEmailResult as B, type CategoryUnsubscribedErrorDetails as C, type DnsRecord as D, type CreateSuppressionParams as E, type CreateTemplateParams as F, Groundmail as G, type CreateWebhookParams as H, DEFAULT_API_BASE_URL as I, type DailyRampLimitErrorDetails as J, type DeliverabilityBucket as K, type DeliverabilityDomainInsight as L, type DeliverabilityInsightsResult as M, type DeliverabilityMailServerRelay as N, type DeliverabilityWindow as O, type DnsProviderName as P, type Domain as Q, type DomainBimiAnalysis as R, type SendEmailResult as S, type DomainDetailResult as T, type DomainDmarcAnalysis as U, type DomainDnsAnalysis as V, type DomainStatus as W, type DomainTlsMode as X, type DomainTrackingDns as Y, type DomainTrackingStatus as Z, type EmailListItem as _, type ApiErrorCode as a, type WebhookEndpoint as a$, type EmailWebhookEventType as a0, type EnrollmentSkip as a1, type EventRecord as a2, type GroundmailOptions as a3, type HeldBackErrorDetails as a4, type HeldBackReason as a5, type HeldBackRecipient as a6, type ListApiKeysParams as a7, type ListApiKeysResult as a8, type ListAutomationRunsParams as a9, type ReceivedEmailAttachmentMeta as aA, type RemoteApplyDnsCredentials as aB, type RunMigrationOptions as aC, type SendEmailParams as aD, type SuppressedErrorDetails as aE, type Suppression as aF, type Template as aG, type TemplateFormat as aH, type TemplateLintWarning as aI, type TemplateStarter as aJ, type TemplateStatus as aK, type TemplateVersion as aL, type TestEmailWebhookParams as aM, type TestEmailWebhookResult as aN, type TriggerEventParams as aO, type TriggerEventResult as aP, type TwilioIntegrationResponse as aQ, type TwilioIntegrationStatus as aR, type UpdateAutomationParams as aS, type UpdateDomainParams as aT, type UpdateEmailParams as aU, type UpdateTemplateParams as aV, type UpdateWebhookParams as aW, type ValidateEmailResult as aX, type ValidationReason as aY, type ValidationVerdict as aZ, type VerifyDomainResult as a_, type ListAutomationRunsResult as aa, type ListAutomationsResult as ab, type ListDomainsParams as ac, type ListDomainsResult as ad, type ListEmailsParams as ae, type ListEmailsResult as af, type ListReceivedEmailsParams as ag, type ListReceivedEmailsResult as ah, type ListSuppressionsParams as ai, type ListSuppressionsResult as aj, type ListTemplatesParams as ak, type ListTemplatesResult as al, type MailServerSigningStatus as am, type Migration as an, type MigrationDnsChange as ao, type MigrationDnsPlan as ap, type MigrationDomainItem as aq, type MigrationItemStatus as ar, type MigrationProvider as as, type MigrationResource as at, type MigrationSummary as au, type MigrationTemplateItem as av, type MigrationTotals as aw, type MigrationWebhookItem as ax, type ReceivedEmail as ay, type ReceivedEmailAttachment as az, type ApiKey as b, type WebhookEndpointWithSecret as b0, type WebhookEventType as b1, mergeMigrations as b2, type ApiKeyScope as c, type ApplyDnsParams as d, type ApplyDnsRecordResult as e, type ApplyDnsResult as f, type Asset as g, type Automation as h, type AutomationResult as i, type AutomationRun as j, type AutomationRunResponse as k, type AutomationRunStatus as l, type AutomationRunStep as m, type AutomationRunStepStatus as n, type AutomationStatus as o, type AutomationStep as p, type AutomationTrigger as q, type BounceType as r, type ConnectTwilioParams as s, type ContactWebhookEventPayload as t, type CreateApiKeyParams as u, type CreateApiKeyResult as v, type CreateAutomationParams as w, type CreateDomainParams as x, type CreateDomainResult as y, type CreateMigrationParams as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as ApiErrorBody, D as DnsRecord } from './client-
|
|
2
|
-
export { a as ApiErrorCode, b as ApiKey, c as ApiKeyScope, d as ApplyDnsParams, e as ApplyDnsRecordResult, f as ApplyDnsResult, g as Asset, h as Automation, i as AutomationResult, j as AutomationRun, k as AutomationRunResponse, l as AutomationRunStatus, m as AutomationRunStep, n as AutomationRunStepStatus, o as AutomationStatus, p as AutomationStep, q as AutomationTrigger, B as BatchSendEmailResult, r as BounceType, C as CategoryUnsubscribedErrorDetails, s as ConnectTwilioParams, t as ContactWebhookEventPayload, u as CreateApiKeyParams, v as CreateApiKeyResult, w as CreateAutomationParams, x as CreateDomainParams, y as CreateDomainResult, z as CreateMigrationParams, E as CreateSuppressionParams, F as CreateTemplateParams, H as CreateWebhookParams, I as DEFAULT_API_BASE_URL, J as DailyRampLimitErrorDetails, K as DeliverabilityBucket, L as DeliverabilityDomainInsight, M as DeliverabilityInsightsResult, N as DeliverabilityMailServerRelay, O as DeliverabilityWindow, P as DnsProviderName, Q as Domain, R as DomainBimiAnalysis, T as DomainDetailResult, U as DomainDmarcAnalysis, V as DomainDnsAnalysis, W as DomainStatus, X as DomainTlsMode, Y as DomainTrackingDns, Z as DomainTrackingStatus, _ as EmailListItem, $ as EmailWebhookEventPayload, a0 as EmailWebhookEventType, a1 as EnrollmentSkip, a2 as EventRecord, G as Groundmail, a3 as GroundmailOptions, a4 as HeldBackErrorDetails, a5 as HeldBackReason, a6 as HeldBackRecipient, a7 as ListApiKeysParams, a8 as ListApiKeysResult, a9 as ListAutomationRunsParams, aa as ListAutomationRunsResult, ab as ListAutomationsResult, ac as ListDomainsParams, ad as ListDomainsResult, ae as ListEmailsParams, af as ListEmailsResult, ag as ListReceivedEmailsParams, ah as ListReceivedEmailsResult, ai as ListSuppressionsParams, aj as ListSuppressionsResult, ak as ListTemplatesParams, al as ListTemplatesResult, am as MailServerSigningStatus, an as Migration, ao as
|
|
1
|
+
import { A as ApiErrorBody, D as DnsRecord } from './client-DLz4rpD9.js';
|
|
2
|
+
export { a as ApiErrorCode, b as ApiKey, c as ApiKeyScope, d as ApplyDnsParams, e as ApplyDnsRecordResult, f as ApplyDnsResult, g as Asset, h as Automation, i as AutomationResult, j as AutomationRun, k as AutomationRunResponse, l as AutomationRunStatus, m as AutomationRunStep, n as AutomationRunStepStatus, o as AutomationStatus, p as AutomationStep, q as AutomationTrigger, B as BatchSendEmailResult, r as BounceType, C as CategoryUnsubscribedErrorDetails, s as ConnectTwilioParams, t as ContactWebhookEventPayload, u as CreateApiKeyParams, v as CreateApiKeyResult, w as CreateAutomationParams, x as CreateDomainParams, y as CreateDomainResult, z as CreateMigrationParams, E as CreateSuppressionParams, F as CreateTemplateParams, H as CreateWebhookParams, I as DEFAULT_API_BASE_URL, J as DailyRampLimitErrorDetails, K as DeliverabilityBucket, L as DeliverabilityDomainInsight, M as DeliverabilityInsightsResult, N as DeliverabilityMailServerRelay, O as DeliverabilityWindow, P as DnsProviderName, Q as Domain, R as DomainBimiAnalysis, T as DomainDetailResult, U as DomainDmarcAnalysis, V as DomainDnsAnalysis, W as DomainStatus, X as DomainTlsMode, Y as DomainTrackingDns, Z as DomainTrackingStatus, _ as EmailListItem, $ as EmailWebhookEventPayload, a0 as EmailWebhookEventType, a1 as EnrollmentSkip, a2 as EventRecord, G as Groundmail, a3 as GroundmailOptions, a4 as HeldBackErrorDetails, a5 as HeldBackReason, a6 as HeldBackRecipient, a7 as ListApiKeysParams, a8 as ListApiKeysResult, a9 as ListAutomationRunsParams, aa as ListAutomationRunsResult, ab as ListAutomationsResult, ac as ListDomainsParams, ad as ListDomainsResult, ae as ListEmailsParams, af as ListEmailsResult, ag as ListReceivedEmailsParams, ah as ListReceivedEmailsResult, ai as ListSuppressionsParams, aj as ListSuppressionsResult, ak as ListTemplatesParams, al as ListTemplatesResult, am as MailServerSigningStatus, an as Migration, ao as MigrationDnsChange, ap as MigrationDnsPlan, aq as MigrationDomainItem, ar as MigrationItemStatus, as as MigrationProvider, at as MigrationResource, au as MigrationSummary, av as MigrationTemplateItem, aw as MigrationTotals, ax as MigrationWebhookItem, ay as ReceivedEmail, az as ReceivedEmailAttachment, aA as ReceivedEmailAttachmentMeta, aB as RemoteApplyDnsCredentials, aC as RunMigrationOptions, aD as SendEmailParams, S as SendEmailResult, aE as SuppressedErrorDetails, aF as Suppression, aG as Template, aH as TemplateFormat, aI as TemplateLintWarning, aJ as TemplateStarter, aK as TemplateStatus, aL as TemplateVersion, aM as TestEmailWebhookParams, aN as TestEmailWebhookResult, aO as TriggerEventParams, aP as TriggerEventResult, aQ as TwilioIntegrationResponse, aR as TwilioIntegrationStatus, aS as UpdateAutomationParams, aT as UpdateDomainParams, aU as UpdateEmailParams, aV as UpdateTemplateParams, aW as UpdateWebhookParams, aX as ValidateEmailResult, aY as ValidationReason, aZ as ValidationVerdict, a_ as VerifyDomainResult, a$ as WebhookEndpoint, b0 as WebhookEndpointWithSecret, b1 as WebhookEventType, b2 as mergeMigrations } from './client-DLz4rpD9.js';
|
|
3
3
|
|
|
4
4
|
type GroundmailErrorOptions = {
|
|
5
5
|
code?: string;
|
|
@@ -43,6 +43,40 @@ declare function buildSignatureHeader(secret: string, payload: string, timestamp
|
|
|
43
43
|
*/
|
|
44
44
|
declare function verifyWebhookSignature(secret: string, payload: string, header: string | null | undefined, toleranceSec?: number): boolean;
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Test mode helpers.
|
|
48
|
+
*
|
|
49
|
+
* Simulator addresses at `simulator.groundmail.dev` produce one outcome each, with
|
|
50
|
+
* the same status and webhooks as real mail, and never leave Groundmail. They work
|
|
51
|
+
* with live and test keys. Plus addressing tells sends apart:
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { simulatorAddress } from 'groundmail'
|
|
55
|
+
* await groundmail.emails.send({ from, to: simulatorAddress('bounce', 'signup-42'), subject, html })
|
|
56
|
+
* // → bounce+signup-42@simulator.groundmail.dev: status `bounced`, `email.bounced` webhook
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* Docs: https://docs.groundmail.dev/testing
|
|
60
|
+
*/
|
|
61
|
+
declare const SIMULATOR_DOMAIN = "simulator.groundmail.dev";
|
|
62
|
+
declare const SIMULATOR_OUTCOMES: readonly ["delivered", "bounce", "block", "complaint", "suppressed", "delayed"];
|
|
63
|
+
/**
|
|
64
|
+
* - `delivered`: `email.delivered`
|
|
65
|
+
* - `bounce`: hard bounce, `email.bounced` with `bounce_type: "hard"`
|
|
66
|
+
* - `block`: block bounce, `email.bounced` with `bounce_type: "block"`
|
|
67
|
+
* - `complaint`: `email.delivered`, then `email.complained`
|
|
68
|
+
* - `suppressed`: refused like a suppressed recipient (422), `email.suppressed`
|
|
69
|
+
* - `delayed`: `email.delivery_delayed`
|
|
70
|
+
*/
|
|
71
|
+
type SimulatorOutcome = (typeof SIMULATOR_OUTCOMES)[number];
|
|
72
|
+
/** `simulatorAddress('bounce')` → `bounce@simulator.groundmail.dev`; a tag adds `+tag`. */
|
|
73
|
+
declare function simulatorAddress(outcome: SimulatorOutcome, tag?: string): string;
|
|
74
|
+
/** True for any address at the simulator domain. */
|
|
75
|
+
declare function isSimulatorAddress(address: string): boolean;
|
|
76
|
+
/** Test keys start with `gm_test_`. */
|
|
77
|
+
declare const TEST_API_KEY_PREFIX = "gm_test_";
|
|
78
|
+
declare function isTestApiKey(key: string | null | undefined): boolean;
|
|
79
|
+
|
|
46
80
|
/** Merge `include:host` into an existing SPF record (or create a minimal one). */
|
|
47
81
|
declare function mergeSpfInclude(existing: string | null | undefined, includeHost: string): string;
|
|
48
82
|
|
|
@@ -75,4 +109,4 @@ declare function applyDnsRecords(input: {
|
|
|
75
109
|
fetchImpl?: typeof fetch;
|
|
76
110
|
}): Promise<ApplyDnsResult>;
|
|
77
111
|
|
|
78
|
-
export { DnsRecord, GroundmailError, type GroundmailErrorOptions, applyDnsRecords, buildSignatureHeader, mergeSpfInclude, signWebhookPayload, verifyWebhookSignature };
|
|
112
|
+
export { DnsRecord, GroundmailError, type GroundmailErrorOptions, SIMULATOR_DOMAIN, SIMULATOR_OUTCOMES, type SimulatorOutcome, TEST_API_KEY_PREFIX, applyDnsRecords, buildSignatureHeader, isSimulatorAddress, isTestApiKey, mergeSpfInclude, signWebhookPayload, simulatorAddress, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -8,15 +8,41 @@ import {
|
|
|
8
8
|
mergeSpfInclude,
|
|
9
9
|
signWebhookPayload,
|
|
10
10
|
verifyWebhookSignature
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MJKAVFFN.js";
|
|
12
|
+
|
|
13
|
+
// src/simulator.ts
|
|
14
|
+
var SIMULATOR_DOMAIN = "simulator.groundmail.dev";
|
|
15
|
+
var SIMULATOR_OUTCOMES = ["delivered", "bounce", "block", "complaint", "suppressed", "delayed"];
|
|
16
|
+
function simulatorAddress(outcome, tag) {
|
|
17
|
+
if (!SIMULATOR_OUTCOMES.includes(outcome)) {
|
|
18
|
+
throw new Error(`Unknown simulator outcome: ${outcome}`);
|
|
19
|
+
}
|
|
20
|
+
const cleanTag = tag?.trim().replace(/[^A-Za-z0-9._-]+/g, "-");
|
|
21
|
+
return `${outcome}${cleanTag ? `+${cleanTag}` : ""}@${SIMULATOR_DOMAIN}`;
|
|
22
|
+
}
|
|
23
|
+
function isSimulatorAddress(address) {
|
|
24
|
+
const match = address.match(/<([^>]+)>/);
|
|
25
|
+
const bare = (match ? match[1] : address).trim().toLowerCase();
|
|
26
|
+
return bare.endsWith(`@${SIMULATOR_DOMAIN}`);
|
|
27
|
+
}
|
|
28
|
+
var TEST_API_KEY_PREFIX = "gm_test_";
|
|
29
|
+
function isTestApiKey(key) {
|
|
30
|
+
return Boolean(key?.startsWith(TEST_API_KEY_PREFIX));
|
|
31
|
+
}
|
|
12
32
|
export {
|
|
13
33
|
DEFAULT_API_BASE_URL,
|
|
14
34
|
Groundmail,
|
|
15
35
|
GroundmailError,
|
|
36
|
+
SIMULATOR_DOMAIN,
|
|
37
|
+
SIMULATOR_OUTCOMES,
|
|
38
|
+
TEST_API_KEY_PREFIX,
|
|
16
39
|
applyDnsRecords,
|
|
17
40
|
buildSignatureHeader,
|
|
41
|
+
isSimulatorAddress,
|
|
42
|
+
isTestApiKey,
|
|
18
43
|
mergeMigrations,
|
|
19
44
|
mergeSpfInclude,
|
|
20
45
|
signWebhookPayload,
|
|
46
|
+
simulatorAddress,
|
|
21
47
|
verifyWebhookSignature
|
|
22
48
|
};
|
package/dist/payload.d.ts
CHANGED
package/dist/payload.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "groundmail",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Groundmail transactional email API client",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"prepublishOnly": "npm run build && npm run build:nodemailer-bridge"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"groundmail-nodemailer": "0.15.
|
|
92
|
+
"groundmail-nodemailer": "0.15.3"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@types/nodemailer": "^8.0.1",
|