groundmail 0.16.0 → 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-JYLRUBEJ.js → chunk-MJKAVFFN.js} +5 -1
- package/dist/clerk.d.ts +1 -1
- package/dist/clerk.js +1 -1
- package/dist/{client-DXYsWgOT.d.ts → client-DLz4rpD9.d.ts} +31 -0
- 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
|
@@ -1008,6 +1008,7 @@ var EmailsResource = class {
|
|
|
1008
1008
|
const search = new URLSearchParams();
|
|
1009
1009
|
if (params.limit != null) search.set("limit", String(params.limit));
|
|
1010
1010
|
if (params.cursor) search.set("cursor", params.cursor);
|
|
1011
|
+
if (params.test != null) search.set("test", String(params.test));
|
|
1011
1012
|
const query = search.toString();
|
|
1012
1013
|
return this.client.request(`/emails${query ? `?${query}` : ""}`, {
|
|
1013
1014
|
method: "GET"
|
|
@@ -1192,7 +1193,10 @@ var KeysResource = class {
|
|
|
1192
1193
|
method: "POST",
|
|
1193
1194
|
body: JSON.stringify({
|
|
1194
1195
|
...params.name ? { name: params.name } : {},
|
|
1195
|
-
...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 } : {}
|
|
1196
1200
|
})
|
|
1197
1201
|
});
|
|
1198
1202
|
}
|
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). */
|
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 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-
|
|
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",
|