@better-forge/notify 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +11 -3
- package/dist/alertPolicy.d.ts +41 -0
- package/dist/alertPolicy.d.ts.map +1 -0
- package/dist/alertPolicy.js +137 -0
- package/dist/alertPolicy.js.map +1 -0
- package/dist/channelInput.d.ts +34 -0
- package/dist/channelInput.d.ts.map +1 -0
- package/dist/channelInput.js +156 -0
- package/dist/channelInput.js.map +1 -0
- package/dist/channelSecrets.d.ts +8 -0
- package/dist/channelSecrets.d.ts.map +1 -0
- package/dist/channelSecrets.js +17 -0
- package/dist/channelSecrets.js.map +1 -0
- package/dist/engine.d.ts +68 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +314 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations.d.ts +907 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +86 -0
- package/dist/migrations.js.map +1 -0
- package/dist/notice.d.ts +55 -0
- package/dist/notice.d.ts.map +1 -0
- package/dist/notice.js +25 -0
- package/dist/notice.js.map +1 -0
- package/dist/routes.d.ts +74 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +302 -0
- package/dist/routes.js.map +1 -0
- package/dist/tables.d.ts +919 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +68 -0
- package/dist/tables.js.map +1 -0
- package/dist/template.d.ts +35 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +72 -0
- package/dist/template.js.map +1 -0
- package/dist/transports.d.ts +50 -0
- package/dist/transports.d.ts.map +1 -0
- package/dist/transports.js +274 -0
- package/dist/transports.js.map +1 -0
- package/dist/worker.d.ts +25 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +38 -0
- package/dist/worker.js.map +1 -0
- package/package.json +59 -6
- package/src/alertPolicy.ts +149 -0
- package/src/channelInput.ts +153 -0
- package/src/channelSecrets.ts +20 -0
- package/src/engine.ts +423 -0
- package/src/index.ts +16 -0
- package/src/migrations.ts +88 -0
- package/src/notice.ts +68 -0
- package/src/routes.ts +362 -0
- package/src/tables.ts +96 -0
- package/src/template.ts +76 -0
- package/src/transports.ts +351 -0
- package/src/worker.ts +58 -0
package/dist/engine.js
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { and, asc, desc, eq, gt, gte, inArray, isNotNull, like, lt, lte, ne, sql } from 'drizzle-orm';
|
|
2
|
+
import { createAlertPolicy, isWithinQuietHours, quietHoursEndAt } from './alertPolicy.js';
|
|
3
|
+
import { MAX_DELIVERY_ATTEMPTS, RETRY_DELAYS_MS } from './template.js';
|
|
4
|
+
/** Delivery history older than this is purged. */
|
|
5
|
+
const DELIVERY_RETENTION_MS = 180 * 24 * 60 * 60 * 1000;
|
|
6
|
+
/**
|
|
7
|
+
* The delivery engine: records every notification, applies the channel's alert hygiene, sends with retries, folds
|
|
8
|
+
* bursts into digests and sends SMTP mail. Locks and in-flight sets live in the returned closure, so two engines
|
|
9
|
+
* never share state.
|
|
10
|
+
*/
|
|
11
|
+
export function createNotifyEngine(options) {
|
|
12
|
+
const { db, deliver, resolveSecret } = options;
|
|
13
|
+
const { notificationChannels, notificationDeliveries, notificationDeliveryAttempts, smtpSettings } = options.tables;
|
|
14
|
+
const { parseAlertPolicy } = createAlertPolicy({ minSourcesKey: options.minSourcesKey });
|
|
15
|
+
const activeDeliveries = new Set();
|
|
16
|
+
/**
|
|
17
|
+
* Writes one delivery row. A pending row is picked up for sending at `releaseAt`; a suppressed row
|
|
18
|
+
* records an event that alert hygiene dropped, so the history still shows what was not sent.
|
|
19
|
+
*/
|
|
20
|
+
async function insertDelivery(channel, vars, details, variant) {
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
const [delivery] = await db.insert(notificationDeliveries).values({
|
|
23
|
+
channelId: channel.id,
|
|
24
|
+
channelName: channel.name,
|
|
25
|
+
channelType: channel.type,
|
|
26
|
+
sourceId: details.sourceId,
|
|
27
|
+
sourceName: details.sourceName,
|
|
28
|
+
eventType: details.eventType,
|
|
29
|
+
status: variant.status,
|
|
30
|
+
targetStatus: vars['status'] ?? 'unknown',
|
|
31
|
+
previousStatus: vars['previous_status'] ?? 'unknown',
|
|
32
|
+
variables: JSON.stringify(vars),
|
|
33
|
+
attemptCount: 0,
|
|
34
|
+
maxAttempts: MAX_DELIVERY_ATTEMPTS,
|
|
35
|
+
...(variant.status === 'pending'
|
|
36
|
+
? { nextAttemptAt: variant.releaseAt ?? now, groupKey: variant.groupKey ?? null }
|
|
37
|
+
: { nextAttemptAt: null, suppressionReason: variant.reason }),
|
|
38
|
+
createdAt: now,
|
|
39
|
+
updatedAt: now,
|
|
40
|
+
}).returning({ id: notificationDeliveries.id });
|
|
41
|
+
return delivery.id;
|
|
42
|
+
}
|
|
43
|
+
async function attemptDelivery(deliveryId, now = Date.now()) {
|
|
44
|
+
if (activeDeliveries.has(deliveryId))
|
|
45
|
+
return;
|
|
46
|
+
activeDeliveries.add(deliveryId);
|
|
47
|
+
try {
|
|
48
|
+
const delivery = (await db.select().from(notificationDeliveries).where(eq(notificationDeliveries.id, deliveryId)))[0];
|
|
49
|
+
if (!delivery || delivery.status === 'delivered' || delivery.attemptCount >= delivery.maxAttempts)
|
|
50
|
+
return;
|
|
51
|
+
const channel = (await db.select().from(notificationChannels).where(eq(notificationChannels.id, delivery.channelId)))[0];
|
|
52
|
+
const attemptNumber = delivery.attemptCount + 1;
|
|
53
|
+
const startedAt = Date.now();
|
|
54
|
+
try {
|
|
55
|
+
if (!channel)
|
|
56
|
+
throw new Error('Notification channel no longer exists');
|
|
57
|
+
if (channel.enabled !== 1)
|
|
58
|
+
throw new Error('Notification channel is disabled');
|
|
59
|
+
await deliver(channel, JSON.parse(delivery.variables));
|
|
60
|
+
const completedAt = Date.now();
|
|
61
|
+
await db.insert(notificationDeliveryAttempts).values({ deliveryId, attemptNumber, status: 'delivered', error: null, startedAt, completedAt });
|
|
62
|
+
await db.update(notificationDeliveries).set({
|
|
63
|
+
status: 'delivered', attemptCount: attemptNumber, nextAttemptAt: null,
|
|
64
|
+
lastAttemptAt: completedAt, deliveredAt: completedAt, lastError: null, updatedAt: completedAt,
|
|
65
|
+
}).where(eq(notificationDeliveries.id, deliveryId));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const completedAt = Date.now();
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
const exhausted = attemptNumber >= delivery.maxAttempts;
|
|
71
|
+
const delay = RETRY_DELAYS_MS[Math.min(attemptNumber - 1, RETRY_DELAYS_MS.length - 1)];
|
|
72
|
+
await db.insert(notificationDeliveryAttempts).values({ deliveryId, attemptNumber, status: 'failed', error: message, startedAt, completedAt });
|
|
73
|
+
await db.update(notificationDeliveries).set({
|
|
74
|
+
status: exhausted ? 'failed' : 'pending', attemptCount: attemptNumber,
|
|
75
|
+
nextAttemptAt: exhausted ? null : now + delay, lastAttemptAt: completedAt,
|
|
76
|
+
lastError: message, updatedAt: completedAt,
|
|
77
|
+
}).where(eq(notificationDeliveries.id, deliveryId));
|
|
78
|
+
console.error(`[notifier] Delivery ${deliveryId}, attempt ${attemptNumber} failed: ${message}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
activeDeliveries.delete(deliveryId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// ── Alert hygiene: rate caps, quiet hours and digest windows ───────────────
|
|
86
|
+
/** Alerts already sent or queued for this source on this channel inside the throttle window. */
|
|
87
|
+
async function countRecentAlerts(channelId, sourceId, windowStart) {
|
|
88
|
+
const [row] = await db.select({ count: sql `count(*)` }).from(notificationDeliveries).where(and(eq(notificationDeliveries.channelId, channelId), eq(notificationDeliveries.sourceId, sourceId), eq(notificationDeliveries.eventType, options.events.alert), ne(notificationDeliveries.status, 'suppressed'), gte(notificationDeliveries.createdAt, windowStart)));
|
|
89
|
+
return row?.count ?? 0;
|
|
90
|
+
}
|
|
91
|
+
/** The digest window this channel already has open, so a burst lands in a single group. */
|
|
92
|
+
async function findOpenGroup(channelId, eventType, now) {
|
|
93
|
+
const [row] = await db.select({ groupKey: notificationDeliveries.groupKey, releaseAt: notificationDeliveries.nextAttemptAt })
|
|
94
|
+
.from(notificationDeliveries)
|
|
95
|
+
.where(and(eq(notificationDeliveries.channelId, channelId), eq(notificationDeliveries.status, 'pending'), like(notificationDeliveries.groupKey, `ch${channelId}:${eventType}:w%`), gt(notificationDeliveries.nextAttemptAt, now)))
|
|
96
|
+
.orderBy(asc(notificationDeliveries.nextAttemptAt))
|
|
97
|
+
.limit(1);
|
|
98
|
+
return row?.groupKey && row.releaseAt !== null ? { groupKey: row.groupKey, releaseAt: row.releaseAt } : null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Applies a channel's alert hygiene to one event. Order matters: the rate cap runs first so a
|
|
102
|
+
* throttled alert never holds a digest window open, then quiet hours decide whether the event is
|
|
103
|
+
* dropped or held, then grouping decides which digest it joins.
|
|
104
|
+
*/
|
|
105
|
+
async function planDelivery(channel, policy, details, now) {
|
|
106
|
+
// Recoveries are never throttled — the all-clear must always get through.
|
|
107
|
+
if (policy.throttle.enabled && details.eventType === options.events.alert && details.sourceId !== null) {
|
|
108
|
+
const windowStart = now - policy.throttle.windowMinutes * 60_000;
|
|
109
|
+
const recent = await countRecentAlerts(channel.id, details.sourceId, windowStart);
|
|
110
|
+
if (recent >= policy.throttle.maxAlerts)
|
|
111
|
+
return { releaseAt: now, groupKey: null, suppressionReason: 'throttled' };
|
|
112
|
+
}
|
|
113
|
+
let releaseAt = now;
|
|
114
|
+
let quietUntil = null;
|
|
115
|
+
if (isWithinQuietHours(policy.quietHours, now)) {
|
|
116
|
+
if (policy.quietHours.mode === 'suppress')
|
|
117
|
+
return { releaseAt: now, groupKey: null, suppressionReason: 'quiet-hours' };
|
|
118
|
+
quietUntil = quietHoursEndAt(policy.quietHours, now);
|
|
119
|
+
releaseAt = Math.max(releaseAt, quietUntil);
|
|
120
|
+
}
|
|
121
|
+
let groupKey = null;
|
|
122
|
+
if (policy.grouping.enabled && details.eventType !== options.events.ungrouped) {
|
|
123
|
+
if (quietUntil !== null) {
|
|
124
|
+
// Everything held for the same quiet window is released at once — digest it as one message.
|
|
125
|
+
groupKey = `ch${channel.id}:${details.eventType}:q${quietUntil}`;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const open = await findOpenGroup(channel.id, details.eventType, now);
|
|
129
|
+
if (open) {
|
|
130
|
+
groupKey = open.groupKey;
|
|
131
|
+
releaseAt = Math.max(releaseAt, open.releaseAt);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
groupKey = `ch${channel.id}:${details.eventType}:w${now}`;
|
|
135
|
+
releaseAt = Math.max(releaseAt, now + policy.grouping.windowSeconds * 1000);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { releaseAt, groupKey, suppressionReason: null };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Planning reads a channel's recent deliveries and then writes one. Two events for the same
|
|
143
|
+
* channel must not interleave across those awaits, or a burst — precisely what grouping exists
|
|
144
|
+
* for — would open one digest window per source, and a rate cap would be counted from a stale
|
|
145
|
+
* total. Sending happens outside the lock so a slow endpoint never stalls the queue.
|
|
146
|
+
*/
|
|
147
|
+
const channelLocks = new Map();
|
|
148
|
+
function withChannelLock(channelId, work) {
|
|
149
|
+
const previous = channelLocks.get(channelId) ?? Promise.resolve();
|
|
150
|
+
const next = previous.then(work, work);
|
|
151
|
+
channelLocks.set(channelId, next.catch(() => undefined));
|
|
152
|
+
return next;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Collapses every due digest window into a single notification. A window that did not reach
|
|
156
|
+
* `minSources` distinct sources is simply released as ordinary individual deliveries, so
|
|
157
|
+
* grouping costs at most `windowSeconds` of latency and never swallows a lone alert.
|
|
158
|
+
*/
|
|
159
|
+
let flushChain = Promise.resolve();
|
|
160
|
+
function flushGroups(now = Date.now()) {
|
|
161
|
+
// The retry worker fires every 30s without awaiting the previous pass; overlapping flushes
|
|
162
|
+
// would each turn the same window into its own digest.
|
|
163
|
+
const run = () => flushDueGroups(now);
|
|
164
|
+
const next = flushChain.then(run, run);
|
|
165
|
+
flushChain = next.catch(() => undefined);
|
|
166
|
+
return next;
|
|
167
|
+
}
|
|
168
|
+
async function flushDueGroups(now) {
|
|
169
|
+
const pending = await db.select().from(notificationDeliveries).where(and(eq(notificationDeliveries.status, 'pending'), isNotNull(notificationDeliveries.groupKey), lte(notificationDeliveries.nextAttemptAt, now))).orderBy(asc(notificationDeliveries.createdAt));
|
|
170
|
+
if (pending.length === 0)
|
|
171
|
+
return 0;
|
|
172
|
+
const groups = new Map();
|
|
173
|
+
for (const row of pending) {
|
|
174
|
+
const bucket = groups.get(row.groupKey);
|
|
175
|
+
if (bucket)
|
|
176
|
+
bucket.push(row);
|
|
177
|
+
else
|
|
178
|
+
groups.set(row.groupKey, [row]);
|
|
179
|
+
}
|
|
180
|
+
let digests = 0;
|
|
181
|
+
for (const rows of groups.values()) {
|
|
182
|
+
const ids = rows.map((row) => row.id);
|
|
183
|
+
const channel = (await db.select().from(notificationChannels).where(eq(notificationChannels.id, rows[0].channelId)))[0];
|
|
184
|
+
const policy = channel ? parseAlertPolicy(channel.alertPolicy) : null;
|
|
185
|
+
const distinctSources = new Set(rows.map((row) => row.sourceId ?? -row.id)).size;
|
|
186
|
+
if (!channel || !policy?.grouping.enabled || distinctSources < policy.grouping.minSources) {
|
|
187
|
+
// Not a burst — or grouping was switched off mid-window. Send them individually.
|
|
188
|
+
await db.update(notificationDeliveries).set({ groupKey: null, updatedAt: now })
|
|
189
|
+
.where(inArray(notificationDeliveries.id, ids));
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const { vars, sourceName } = options.digest(rows, now);
|
|
193
|
+
// Retire the members first: a crash between the two writes must not let both forms go out.
|
|
194
|
+
await db.update(notificationDeliveries).set({
|
|
195
|
+
status: 'suppressed', suppressionReason: 'grouped', nextAttemptAt: null, updatedAt: now,
|
|
196
|
+
}).where(inArray(notificationDeliveries.id, ids));
|
|
197
|
+
await insertDelivery(channel, vars, {
|
|
198
|
+
sourceId: null,
|
|
199
|
+
sourceName,
|
|
200
|
+
eventType: rows[0].eventType,
|
|
201
|
+
}, { status: 'pending', releaseAt: now });
|
|
202
|
+
digests++;
|
|
203
|
+
}
|
|
204
|
+
return digests;
|
|
205
|
+
}
|
|
206
|
+
async function processDue(now = Date.now()) {
|
|
207
|
+
await flushGroups(now);
|
|
208
|
+
const due = await db.select({ id: notificationDeliveries.id }).from(notificationDeliveries).where(and(eq(notificationDeliveries.status, 'pending'), lte(notificationDeliveries.nextAttemptAt, now)));
|
|
209
|
+
await Promise.allSettled(due.map((delivery) => attemptDelivery(delivery.id, now)));
|
|
210
|
+
return due.length;
|
|
211
|
+
}
|
|
212
|
+
async function retryDelivery(deliveryId) {
|
|
213
|
+
const delivery = (await db.select().from(notificationDeliveries).where(eq(notificationDeliveries.id, deliveryId)))[0];
|
|
214
|
+
if (!delivery || delivery.status !== 'failed')
|
|
215
|
+
return false;
|
|
216
|
+
const now = Date.now();
|
|
217
|
+
await db.update(notificationDeliveries).set({
|
|
218
|
+
status: 'pending', maxAttempts: delivery.attemptCount + MAX_DELIVERY_ATTEMPTS,
|
|
219
|
+
nextAttemptAt: now, deliveredAt: null, lastError: null, updatedAt: now,
|
|
220
|
+
}).where(eq(notificationDeliveries.id, deliveryId));
|
|
221
|
+
await attemptDelivery(deliveryId, now);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
async function purgeOldDeliveries(now = Date.now()) {
|
|
225
|
+
await db.delete(notificationDeliveries).where(lt(notificationDeliveries.createdAt, now - DELIVERY_RETENTION_MS));
|
|
226
|
+
}
|
|
227
|
+
/** True when the latest alert-or-recovery event recorded for this source is an alert. */
|
|
228
|
+
async function hasOpenAlert(sourceId) {
|
|
229
|
+
// Suppressed rows count: an alert that quiet hours or a digest swallowed was still raised.
|
|
230
|
+
const [last] = await db.select({ eventType: notificationDeliveries.eventType }).from(notificationDeliveries)
|
|
231
|
+
.where(and(eq(notificationDeliveries.sourceId, sourceId), inArray(notificationDeliveries.eventType, [options.events.alert, options.events.recovery])))
|
|
232
|
+
.orderBy(desc(notificationDeliveries.id))
|
|
233
|
+
.limit(1);
|
|
234
|
+
return last?.eventType === options.events.alert;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Plans one event for one channel under its lock and records it. Resolves to the delivery to send right away, or
|
|
238
|
+
* null when nothing is to be sent now (suppressed, or held for quiet hours or a digest window). Recording is
|
|
239
|
+
* separate from sending so a caller can record every channel's delivery in its own transaction and send afterwards:
|
|
240
|
+
* a recorded delivery that was never sent is picked up by `processDue`.
|
|
241
|
+
*/
|
|
242
|
+
async function plan(channel, vars, details) {
|
|
243
|
+
return withChannelLock(channel.id, async () => {
|
|
244
|
+
const now = Date.now();
|
|
245
|
+
const delivery = await planDelivery(channel, parseAlertPolicy(channel.alertPolicy), details, now);
|
|
246
|
+
if (delivery.suppressionReason) {
|
|
247
|
+
await insertDelivery(channel, vars, details, { status: 'suppressed', reason: delivery.suppressionReason });
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
const deliveryId = await insertDelivery(channel, vars, details, { status: 'pending', releaseAt: delivery.releaseAt, groupKey: delivery.groupKey });
|
|
251
|
+
return delivery.releaseAt <= now ? deliveryId : null;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/** Plans one event for one channel and sends it right away when nothing holds it back. */
|
|
255
|
+
async function dispatch(channel, vars, details) {
|
|
256
|
+
const sendNow = await plan(channel, vars, details);
|
|
257
|
+
if (sendNow !== null)
|
|
258
|
+
await attemptDelivery(sendNow);
|
|
259
|
+
}
|
|
260
|
+
/** Records a delivery that bypasses alert hygiene and sends it at once; resolves to the outcome. */
|
|
261
|
+
async function sendDirect(channel, vars, details) {
|
|
262
|
+
const deliveryId = await insertDelivery(channel, vars, details, { status: 'pending' });
|
|
263
|
+
await attemptDelivery(deliveryId);
|
|
264
|
+
const delivery = (await db.select().from(notificationDeliveries).where(eq(notificationDeliveries.id, deliveryId)))[0];
|
|
265
|
+
return delivery.status === 'delivered' ? { ok: true } : { ok: false, error: delivery.lastError ?? 'Delivery failed' };
|
|
266
|
+
}
|
|
267
|
+
// ── SMTP ───────────────────────────────────────────────────────────────────
|
|
268
|
+
async function isSmtpConfigured() {
|
|
269
|
+
const smtp = (await db.select({ host: smtpSettings.host }).from(smtpSettings))[0];
|
|
270
|
+
return !!smtp?.host;
|
|
271
|
+
}
|
|
272
|
+
/** Sends one message through the configured SMTP server. Throws when SMTP is not set up. */
|
|
273
|
+
async function sendSmtpMail(message) {
|
|
274
|
+
const smtp = (await db.select().from(smtpSettings))[0];
|
|
275
|
+
if (!smtp?.host)
|
|
276
|
+
throw new Error('SMTP not configured');
|
|
277
|
+
let smtpUser = smtp.user;
|
|
278
|
+
let smtpPass = smtp.password;
|
|
279
|
+
if (smtp.vaultConfig) {
|
|
280
|
+
const ref = JSON.parse(smtp.vaultConfig);
|
|
281
|
+
const creds = await resolveSecret(ref);
|
|
282
|
+
smtpUser = creds['username'] ?? creds['user'] ?? smtpUser;
|
|
283
|
+
smtpPass = creds['password'] ?? creds['value'] ?? smtpPass;
|
|
284
|
+
// A vault reference means sign-in was intended; without a user nodemailer would skip auth silently.
|
|
285
|
+
if (!smtpUser)
|
|
286
|
+
throw new Error('SMTP vault secret has no username: use a User / Password secret or map a username in a JSON secret');
|
|
287
|
+
}
|
|
288
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
289
|
+
const nodemailer = await import('nodemailer');
|
|
290
|
+
const nm = nodemailer.default ?? nodemailer;
|
|
291
|
+
const transporter = nm.createTransport({
|
|
292
|
+
host: smtp.host,
|
|
293
|
+
port: smtp.port,
|
|
294
|
+
secure: !!smtp.secure,
|
|
295
|
+
auth: smtpUser ? { user: smtpUser, pass: smtpPass } : undefined,
|
|
296
|
+
});
|
|
297
|
+
const from = smtp.fromAddress
|
|
298
|
+
? `"${smtp.fromName}" <${smtp.fromAddress}>`
|
|
299
|
+
: smtp.fromName;
|
|
300
|
+
await transporter.sendMail({
|
|
301
|
+
from,
|
|
302
|
+
to: message.to,
|
|
303
|
+
subject: message.subject,
|
|
304
|
+
text: message.text,
|
|
305
|
+
...(message.html ? { html: message.html } : {}),
|
|
306
|
+
...(message.headers ? { headers: message.headers } : {}),
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
plan, dispatch, sendDirect, attemptDelivery, flushGroups, processDue, retryDelivery, purgeOldDeliveries, hasOpenAlert,
|
|
311
|
+
isSmtpConfigured, sendSmtpMail,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAGrG,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAoB,MAAM,kBAAkB,CAAA;AAE3G,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAuDtE,kDAAkD;AAClD,MAAM,qBAAqB,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEvD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAA;IAC9C,MAAM,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAA;IACnH,MAAM,EAAE,gBAAgB,EAAE,GAAG,iBAAiB,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;IACxF,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;IAE1C;;;OAGG;IACH,KAAK,UAAU,cAAc,CAC3B,OAAmB,EACnB,IAA4B,EAC5B,OAAwB,EACxB,OAAwB;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC;YAChE,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS;YACzC,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,SAAS;YACpD,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC/B,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,qBAAqB;YAClC,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS;gBAC9B,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,SAAS,IAAI,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE;gBACjF,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YAC/D,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,sBAAsB,CAAC,EAAE,EAAE,CAAC,CAAA;QAC/C,OAAO,QAAS,CAAC,EAAE,CAAA;IACrB,CAAC;IAED,KAAK,UAAU,eAAe,CAAC,UAAkB,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACjE,IAAI,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAM;QAC5C,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAChC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACrH,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,IAAI,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,WAAW;gBAAE,OAAM;YACzG,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACxH,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,GAAG,CAAC,CAAA;YAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAC5B,IAAI,CAAC;gBACH,IAAI,CAAC,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;gBACtE,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;gBAC9E,MAAM,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAA2B,CAAC,CAAA;gBAChF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAC9B,MAAM,EAAE,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAA;gBAC7I,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC;oBAC1C,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI;oBACrE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW;iBAC9F,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAA;YACrD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBACtE,MAAM,SAAS,GAAG,aAAa,IAAI,QAAQ,CAAC,WAAW,CAAA;gBACvD,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,CAAC,EAAE,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAE,CAAA;gBACvF,MAAM,EAAE,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAA;gBAC7I,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC;oBAC1C,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,aAAa;oBACrE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,EAAE,aAAa,EAAE,WAAW;oBACzE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW;iBAC3C,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAA;gBACnD,OAAO,CAAC,KAAK,CAAC,uBAAuB,UAAU,aAAa,aAAa,YAAY,OAAO,EAAE,CAAC,CAAA;YACjG,CAAC;QACH,CAAC;gBAAS,CAAC;YAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAAC,CAAC;IACnD,CAAC;IAED,8EAA8E;IAE9E,gGAAgG;IAChG,KAAK,UAAU,iBAAiB,CAAC,SAAiB,EAAE,QAAgB,EAAE,WAAmB;QACvF,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAQ,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,GAAG,CACpG,EAAE,CAAC,sBAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,EAC/C,EAAE,CAAC,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAC7C,EAAE,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAC1D,EAAE,CAAC,sBAAsB,CAAC,MAAM,EAAE,YAAY,CAAC,EAC/C,GAAG,CAAC,sBAAsB,CAAC,SAAS,EAAE,WAAW,CAAC,CACnD,CAAC,CAAA;QACF,OAAO,GAAG,EAAE,KAAK,IAAI,CAAC,CAAA;IACxB,CAAC;IAED,2FAA2F;IAC3F,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,SAAiB,EAAE,GAAW;QAC5E,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,EAAE,SAAS,EAAE,sBAAsB,CAAC,aAAa,EAAE,CAAC;aAC1H,IAAI,CAAC,sBAAsB,CAAC;aAC5B,KAAK,CAAC,GAAG,CACR,EAAE,CAAC,sBAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,EAC/C,EAAE,CAAC,sBAAsB,CAAC,MAAM,EAAE,SAAS,CAAC,EAC5C,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,KAAK,SAAS,IAAI,SAAS,KAAK,CAAC,EACvE,EAAE,CAAC,sBAAsB,CAAC,aAAa,EAAE,GAAG,CAAC,CAC9C,CAAC;aACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC;aAClD,KAAK,CAAC,CAAC,CAAC,CAAA;QACX,OAAO,GAAG,EAAE,QAAQ,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9G,CAAC;IAED;;;;OAIG;IACH,KAAK,UAAU,YAAY,CACzB,OAAmB,EACnB,MAAmB,EACnB,OAAwB,EACxB,GAAW;QAEX,0EAA0E;QAC1E,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvG,MAAM,WAAW,GAAG,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,GAAG,MAAM,CAAA;YAChE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;YACjF,IAAI,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS;gBAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,CAAA;QACpH,CAAC;QAED,IAAI,SAAS,GAAG,GAAG,CAAA;QACnB,IAAI,UAAU,GAAkB,IAAI,CAAA;QACpC,IAAI,kBAAkB,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;YAC/C,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,UAAU;gBAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAA;YACtH,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;YACpD,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;QAC7C,CAAC;QAED,IAAI,QAAQ,GAAkB,IAAI,CAAA;QAClC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC9E,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBACxB,4FAA4F;gBAC5F,QAAQ,GAAG,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,SAAS,KAAK,UAAU,EAAE,CAAA;YAClE,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;gBACpE,IAAI,IAAI,EAAE,CAAC;oBACT,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;oBACxB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;gBACjD,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,SAAS,KAAK,GAAG,EAAE,CAAA;oBACzD,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;gBAC7E,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAA;IACzD,CAAC;IAED;;;;;OAKG;IACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAA4B,CAAA;IAExD,SAAS,eAAe,CAAI,SAAiB,EAAE,IAAsB;QACnE,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;QACjE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACtC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;QACxD,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;OAIG;IACH,IAAI,UAAU,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAA;IAEpD,SAAS,WAAW,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACnC,2FAA2F;QAC3F,uDAAuD;QACvD,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACtC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACxC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,UAAU,cAAc,CAAC,GAAW;QACvC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,GAAG,CACtE,EAAE,CAAC,sBAAsB,CAAC,MAAM,EAAE,SAAS,CAAC,EAC5C,SAAS,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAC1C,GAAG,CAAC,sBAAsB,CAAC,aAAa,EAAE,GAAG,CAAC,CAC/C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC,CAAA;QACjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAA;QAElC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAA;QAC/C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,QAAS,CAAC,CAAA;YACxC,IAAI,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;;gBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,QAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;QACvC,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACrC,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACxH,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YACrE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;YAEhF,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,IAAI,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC1F,iFAAiF;gBACjF,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;qBAC5E,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;gBACjD,SAAQ;YACV,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;YACtD,2FAA2F;YAC3F,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC;gBAC1C,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG;aACxF,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;YACjD,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE;gBAClC,QAAQ,EAAE,IAAI;gBACd,UAAU;gBACV,SAAS,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,SAAS;aAC9B,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;YACzC,OAAO,EAAE,CAAA;QACX,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QACxC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAA;QACtB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,sBAAsB,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAC/F,GAAG,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,sBAAsB,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAClG,CAAA;QACD,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;QAClF,OAAO,GAAG,CAAC,MAAM,CAAA;IACnB,CAAC;IAED,KAAK,UAAU,aAAa,CAAC,UAAkB;QAC7C,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACrH,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAA;QAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC;YAC1C,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,YAAY,GAAG,qBAAqB;YAC7E,aAAa,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG;SACvE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAA;QACnD,MAAM,eAAe,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;QACtC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,UAAU,kBAAkB,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QAChD,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,EAAE,GAAG,GAAG,qBAAqB,CAAC,CAAC,CAAA;IAClH,CAAC;IAED,yFAAyF;IACzF,KAAK,UAAU,YAAY,CAAC,QAAgB;QAC1C,2FAA2F;QAC3F,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,sBAAsB,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC;aACzG,KAAK,CAAC,GAAG,CACR,EAAE,CAAC,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAC7C,OAAO,CAAC,sBAAsB,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAC3F,CAAC;aACD,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;aACxC,KAAK,CAAC,CAAC,CAAC,CAAA;QACX,OAAO,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAA;IACjD,CAAC;IAED;;;;;OAKG;IACH,KAAK,UAAU,IAAI,CAAC,OAAmB,EAAE,IAA4B,EAAE,OAAwB;QAC7F,OAAO,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI,EAAE;YAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACtB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;YAEjG,IAAI,QAAQ,CAAC,iBAAiB,EAAE,CAAC;gBAC/B,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAA;gBAC1G,OAAO,IAAI,CAAA;YACb,CAAC;YAED,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;YAClJ,OAAO,QAAQ,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAA;QACtD,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,0FAA0F;IAC1F,KAAK,UAAU,QAAQ,CAAC,OAAmB,EAAE,IAA4B,EAAE,OAAwB;QACjG,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;QAClD,IAAI,OAAO,KAAK,IAAI;YAAE,MAAM,eAAe,CAAC,OAAO,CAAC,CAAA;IACtD,CAAC;IAED,oGAAoG;IACpG,KAAK,UAAU,UAAU,CACvB,OAAmB,EACnB,IAA4B,EAC5B,OAAwB;QAExB,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;QACtF,MAAM,eAAe,CAAC,UAAU,CAAC,CAAA;QACjC,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAA;QACtH,OAAO,QAAQ,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,IAAI,iBAAiB,EAAE,CAAA;IACvH,CAAC;IAED,8EAA8E;IAE9E,KAAK,UAAU,gBAAgB;QAC7B,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACjF,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,CAAA;IACrB,CAAC;IAED,4FAA4F;IAC5F,KAAK,UAAU,YAAY,CAAC,OAAoB;QAC9C,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACtD,IAAI,CAAC,IAAI,EAAE,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;QAEvD,IAAI,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAA;QACxB,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC5B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAa,CAAA;YACpD,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAA;YACtC,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAA;YACzD,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAA;YAC1D,oGAAoG;YACpG,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,oGAAoG,CAAC,CAAA;QACtI,CAAC;QAED,8DAA8D;QAC9D,MAAM,UAAU,GAAQ,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;QAClD,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,IAAI,UAAU,CAAA;QAC3C,MAAM,WAAW,GAAG,EAAE,CAAC,eAAe,CAAC;YACrC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;YACrB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS;SAChE,CAAC,CAAA;QAEF,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW;YAC3B,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,WAAW,GAAG;YAC5C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAA;QAEjB,MAAM,WAAW,CAAC,QAAQ,CAAC;YACzB,IAAI;YACJ,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzD,CAAC,CAAA;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,kBAAkB,EAAE,YAAY;QACrH,gBAAgB,EAAE,YAAY;KAC/B,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { CHANNEL_TYPES, TEMPLATE_KEYS, channelConfigError, configForEvent, eventOverridesError, type DefaultWording, type EventWording, ntfyConfigError, pushoverConfigError, telegramConfigError } from './channelInput.js';
|
|
2
|
+
export { CHANNEL_DESTINATIONS, CHANNEL_SECRETS } from './channelSecrets.js';
|
|
3
|
+
export { createAlertPolicy, DEFAULT_ALERT_POLICY, isValidTimezone, isWithinQuietHours, localMinutes, quietHoursEndAt, type AlertPolicy, type GroupingPolicy, type ThrottlePolicy, } from './alertPolicy.js';
|
|
4
|
+
export { createNotifyDbModule, notifyMigrations } from './migrations.js';
|
|
5
|
+
export { defineNotifyTables, type NotifyTableOptions, type NotifyTables } from './tables.js';
|
|
6
|
+
export { buildWebhookRequest, escapeJsonString, placeholderInAuthority, MAX_DELIVERY_ATTEMPTS, RETRY_DELAYS_MS, substituteVars } from './template.js';
|
|
7
|
+
export { createNotifyEngine, type ChannelRow, type DeliveryDetails, type DeliveryRow, type NotifyEngine, type NotifyEngineOptions, type SmtpMessage, } from './engine.js';
|
|
8
|
+
export { readableTimestamp, renderSegments, type Notice, type NoticeFact, type NoticeSegment, type NoticeSeverity } from './notice.js';
|
|
9
|
+
export { createTransports, type TransportChannel, type TransportOptions, type Transports } from './transports.js';
|
|
10
|
+
export { createNotifyRoutes, type KeyResult, type NotifyRoutesOptions } from './routes.js';
|
|
11
|
+
export { createDeliveryWorker, type DeliveryWorkerOptions, type WorkerTask } from './worker.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC5N,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC3E,OAAO,EACL,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,kBAAkB,EAAE,YAAY,EAAE,eAAe,EAC3G,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,GAC3D,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACrJ,OAAO,EACL,kBAAkB,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,WAAW,GAC3I,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AACtI,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjH,OAAO,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC1F,OAAO,EAAE,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { CHANNEL_TYPES, TEMPLATE_KEYS, channelConfigError, configForEvent, eventOverridesError, ntfyConfigError, pushoverConfigError, telegramConfigError } from './channelInput.js';
|
|
2
|
+
export { CHANNEL_DESTINATIONS, CHANNEL_SECRETS } from './channelSecrets.js';
|
|
3
|
+
export { createAlertPolicy, DEFAULT_ALERT_POLICY, isValidTimezone, isWithinQuietHours, localMinutes, quietHoursEndAt, } from './alertPolicy.js';
|
|
4
|
+
export { createNotifyDbModule, notifyMigrations } from './migrations.js';
|
|
5
|
+
export { defineNotifyTables } from './tables.js';
|
|
6
|
+
export { buildWebhookRequest, escapeJsonString, placeholderInAuthority, MAX_DELIVERY_ATTEMPTS, RETRY_DELAYS_MS, substituteVars } from './template.js';
|
|
7
|
+
export { createNotifyEngine, } from './engine.js';
|
|
8
|
+
export { readableTimestamp, renderSegments } from './notice.js';
|
|
9
|
+
export { createTransports } from './transports.js';
|
|
10
|
+
export { createNotifyRoutes } from './routes.js';
|
|
11
|
+
export { createDeliveryWorker } from './worker.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAA0C,eAAe,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC5N,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC3E,OAAO,EACL,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,kBAAkB,EAAE,YAAY,EAAE,eAAe,GAE5G,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAA8C,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACrJ,OAAO,EACL,kBAAkB,GACnB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAyE,MAAM,aAAa,CAAA;AACtI,OAAO,EAAE,gBAAgB,EAAiE,MAAM,iBAAiB,CAAA;AACjH,OAAO,EAAE,kBAAkB,EAA4C,MAAM,aAAa,CAAA;AAC1F,OAAO,EAAE,oBAAoB,EAA+C,MAAM,aAAa,CAAA"}
|