@astralibx/email-rule-engine 12.10.1 → 12.11.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/dist/index.cjs +53 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +53 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -375,7 +375,16 @@ function createEmailThrottleConfigSchema(collectionPrefix) {
|
|
|
375
375
|
maxPerUserPerDay: { type: Number, default: 1 },
|
|
376
376
|
maxPerUserPerWeek: { type: Number, default: 2 },
|
|
377
377
|
minGapDays: { type: Number, default: 3 },
|
|
378
|
-
throttleWindow: { type: String, enum: Object.values(THROTTLE_WINDOW), default: THROTTLE_WINDOW.Rolling }
|
|
378
|
+
throttleWindow: { type: String, enum: Object.values(THROTTLE_WINDOW), default: THROTTLE_WINDOW.Rolling },
|
|
379
|
+
sendWindow: {
|
|
380
|
+
type: {
|
|
381
|
+
startHour: { type: Number, min: 0, max: 23 },
|
|
382
|
+
endHour: { type: Number, min: 0, max: 23 },
|
|
383
|
+
timezone: { type: String }
|
|
384
|
+
},
|
|
385
|
+
_id: false,
|
|
386
|
+
default: void 0
|
|
387
|
+
}
|
|
379
388
|
},
|
|
380
389
|
{
|
|
381
390
|
timestamps: true,
|
|
@@ -1279,16 +1288,6 @@ var RuleRunnerService = class {
|
|
|
1279
1288
|
async runAllRules(triggeredBy = RUN_TRIGGER.Cron, runId) {
|
|
1280
1289
|
if (!runId) runId = crypto__default.default.randomUUID();
|
|
1281
1290
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1282
|
-
if (this.config.options?.sendWindow) {
|
|
1283
|
-
const { startHour, endHour, timezone } = this.config.options.sendWindow;
|
|
1284
|
-
const now = /* @__PURE__ */ new Date();
|
|
1285
|
-
const formatter = new Intl.DateTimeFormat("en-US", { hour: "numeric", hour12: false, timeZone: timezone });
|
|
1286
|
-
const currentHour = parseInt(formatter.format(now), 10);
|
|
1287
|
-
if (currentHour < startHour || currentHour >= endHour) {
|
|
1288
|
-
this.logger.info("Outside send window, skipping run", { currentHour, startHour, endHour, timezone });
|
|
1289
|
-
return { runId };
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
1291
|
const lockAcquired = await this.lock.acquire();
|
|
1293
1292
|
if (!lockAcquired) {
|
|
1294
1293
|
this.logger.warn("Rule runner already executing, skipping");
|
|
@@ -1307,9 +1306,20 @@ var RuleRunnerService = class {
|
|
|
1307
1306
|
let runStatus = "completed";
|
|
1308
1307
|
try {
|
|
1309
1308
|
const throttleConfig = await this.EmailThrottleConfig.getConfig();
|
|
1309
|
+
const sendWindow = throttleConfig.sendWindow ?? this.config.options?.sendWindow;
|
|
1310
|
+
if (sendWindow) {
|
|
1311
|
+
const { startHour, endHour, timezone } = sendWindow;
|
|
1312
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
1313
|
+
const formatter = new Intl.DateTimeFormat("en-US", { hour: "numeric", hour12: false, timeZone: timezone });
|
|
1314
|
+
const currentHour = parseInt(formatter.format(now2), 10);
|
|
1315
|
+
if (currentHour < startHour || currentHour >= endHour) {
|
|
1316
|
+
this.logger.info("Outside send window, skipping run", { currentHour, startHour, endHour, timezone });
|
|
1317
|
+
return { runId };
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1310
1320
|
const allActiveRules = await this.EmailRule.findActive();
|
|
1311
1321
|
const now = /* @__PURE__ */ new Date();
|
|
1312
|
-
const tz = this.config.options?.sendWindow?.timezone;
|
|
1322
|
+
const tz = sendWindow?.timezone ?? this.config.options?.sendWindow?.timezone;
|
|
1313
1323
|
const activeRules = allActiveRules.filter((rule) => {
|
|
1314
1324
|
if (rule.validFrom) {
|
|
1315
1325
|
const localNow = getLocalDate(now, tz);
|
|
@@ -2211,7 +2221,7 @@ function createSettingsController(EmailThrottleConfig) {
|
|
|
2211
2221
|
res.json({ success: true, data: { config } });
|
|
2212
2222
|
});
|
|
2213
2223
|
const updateThrottleConfig = asyncHandler(async (req, res) => {
|
|
2214
|
-
const { maxPerUserPerDay, maxPerUserPerWeek, minGapDays } = req.body;
|
|
2224
|
+
const { maxPerUserPerDay, maxPerUserPerWeek, minGapDays, sendWindow } = req.body;
|
|
2215
2225
|
const updates = {};
|
|
2216
2226
|
if (maxPerUserPerDay !== void 0) {
|
|
2217
2227
|
if (!Number.isInteger(maxPerUserPerDay) || maxPerUserPerDay < 1) {
|
|
@@ -2231,6 +2241,23 @@ function createSettingsController(EmailThrottleConfig) {
|
|
|
2231
2241
|
}
|
|
2232
2242
|
updates.minGapDays = minGapDays;
|
|
2233
2243
|
}
|
|
2244
|
+
if (sendWindow !== void 0) {
|
|
2245
|
+
if (sendWindow === null) {
|
|
2246
|
+
updates.sendWindow = void 0;
|
|
2247
|
+
} else {
|
|
2248
|
+
const { startHour, endHour, timezone } = sendWindow;
|
|
2249
|
+
if (!Number.isInteger(startHour) || startHour < 0 || startHour > 23) {
|
|
2250
|
+
return res.status(400).json({ success: false, error: "sendWindow.startHour must be an integer 0-23" });
|
|
2251
|
+
}
|
|
2252
|
+
if (!Number.isInteger(endHour) || endHour < 0 || endHour > 23) {
|
|
2253
|
+
return res.status(400).json({ success: false, error: "sendWindow.endHour must be an integer 0-23" });
|
|
2254
|
+
}
|
|
2255
|
+
if (typeof timezone !== "string" || !timezone.trim()) {
|
|
2256
|
+
return res.status(400).json({ success: false, error: "sendWindow.timezone must be a non-empty string" });
|
|
2257
|
+
}
|
|
2258
|
+
updates.sendWindow = { startHour, endHour, timezone: timezone.trim() };
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2234
2261
|
if (Object.keys(updates).length === 0) {
|
|
2235
2262
|
return res.status(400).json({ success: false, error: "No valid fields to update" });
|
|
2236
2263
|
}
|
|
@@ -2240,9 +2267,21 @@ function createSettingsController(EmailThrottleConfig) {
|
|
|
2240
2267
|
if (finalWeekly < finalDaily) {
|
|
2241
2268
|
return res.status(400).json({ success: false, error: "maxPerUserPerWeek must be >= maxPerUserPerDay" });
|
|
2242
2269
|
}
|
|
2270
|
+
const setFields = {};
|
|
2271
|
+
const unsetFields = {};
|
|
2272
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
2273
|
+
if (value === void 0) {
|
|
2274
|
+
unsetFields[key] = "";
|
|
2275
|
+
} else {
|
|
2276
|
+
setFields[key] = value;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
const updateOp = {};
|
|
2280
|
+
if (Object.keys(setFields).length > 0) updateOp["$set"] = setFields;
|
|
2281
|
+
if (Object.keys(unsetFields).length > 0) updateOp["$unset"] = unsetFields;
|
|
2243
2282
|
const updated = await EmailThrottleConfig.findByIdAndUpdate(
|
|
2244
2283
|
config._id,
|
|
2245
|
-
|
|
2284
|
+
updateOp,
|
|
2246
2285
|
{ new: true }
|
|
2247
2286
|
);
|
|
2248
2287
|
res.json({ success: true, data: { config: updated } });
|