@dxv-systems/helpdesk 0.1.0 → 0.3.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/autosend.js DELETED
@@ -1,83 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_AUTO_SEND_POLICY = void 0;
4
- exports.evaluateAutoSend = evaluateAutoSend;
5
- exports.DEFAULT_AUTO_SEND_POLICY = {
6
- enabled: false,
7
- minConfidence: 0.9,
8
- maxAutoRepliesPerThread: 1,
9
- };
10
- const WEEKDAYS = { Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6, Sun: 7 };
11
- function minutes(hhmm) {
12
- const [h, m] = hhmm.split(":");
13
- return Number(h) * 60 + Number(m ?? 0);
14
- }
15
- function withinOfficeHours(hours, now) {
16
- const parts = new Intl.DateTimeFormat("en-US", {
17
- timeZone: hours.timeZone,
18
- weekday: "short",
19
- hour: "2-digit",
20
- minute: "2-digit",
21
- hourCycle: "h23",
22
- }).formatToParts(now);
23
- const get = (type) => parts.find((p) => p.type === type)?.value ?? "";
24
- const day = WEEKDAYS[get("weekday")];
25
- const at = Number(get("hour")) * 60 + Number(get("minute"));
26
- return hours.windows.some((w) => day !== undefined && w.days.includes(day) && at >= minutes(w.start) && at < minutes(w.end));
27
- }
28
- function senderMatches(sender, rules) {
29
- const domain = sender.split("@")[1] ?? "";
30
- return rules.some((r) => {
31
- const rule = r.trim().toLowerCase();
32
- return rule.startsWith("@") ? domain === rule.slice(1) : sender === rule;
33
- });
34
- }
35
- function evaluateAutoSend(policy, ctx) {
36
- const deny = (reason, detail) => ({
37
- allow: false,
38
- reason,
39
- ...(detail ? { detail } : {}),
40
- });
41
- const sender = ctx.sender.trim().toLowerCase();
42
- const domain = sender.split("@")[1] ?? "";
43
- if (ctx.paused)
44
- return deny("paused");
45
- if (ctx.writeMode !== "drafts_in_outlook")
46
- return deny("write_mode", ctx.writeMode);
47
- if (!policy.enabled)
48
- return deny("disabled");
49
- if (ctx.inboundIgnored || ctx.threadState === "ignored")
50
- return deny("ignored_mail");
51
- const internalAddresses = [...ctx.ownAddresses, ...ctx.connectedMailboxes].map((a) => a.toLowerCase());
52
- const internalDomains = (policy.internalDomains ?? []).map((d) => d.toLowerCase());
53
- if (internalAddresses.includes(sender) || internalDomains.includes(domain)) {
54
- return deny("internal_sender");
55
- }
56
- if (ctx.suppressAutoResponse)
57
- return deny("auto_response_suppressed");
58
- if (ctx.threadState !== "drafted")
59
- return deny("wrong_state", ctx.threadState);
60
- if (ctx.draftIsStale)
61
- return deny("stale_draft");
62
- const senders = policy.senders ?? [];
63
- const categories = policy.categories ?? [];
64
- if (senders.length === 0 && categories.length === 0)
65
- return deny("no_scope_configured");
66
- const senderOk = senders.length > 0 && senderMatches(sender, senders);
67
- const category = (ctx.category ?? "").toLowerCase();
68
- const categoryOk = categories.length > 0 && categories.some((c) => c.toLowerCase() === category);
69
- if (!senderOk && !categoryOk) {
70
- return senders.length > 0 && categories.length === 0
71
- ? deny("sender_not_allowed", sender)
72
- : deny("category_not_allowed", ctx.category ?? "none");
73
- }
74
- if (ctx.confidence < policy.minConfidence)
75
- return deny("low_confidence", String(ctx.confidence));
76
- if (policy.officeHours && !withinOfficeHours(policy.officeHours, ctx.now)) {
77
- return deny("outside_office_hours");
78
- }
79
- if (ctx.autoRepliesInThread >= policy.maxAutoRepliesPerThread) {
80
- return deny("max_auto_replies", String(ctx.autoRepliesInThread));
81
- }
82
- return { allow: true, reason: "all_rules_passed" };
83
- }
package/dist/cleanup.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { MailboxAccess } from "./controls";
2
- import type { DraftRun, HelpdeskDeps } from "./types";
3
- export declare function sendIntentIds(run: DraftRun): {
4
- perRun: string;
5
- perDraft: string | null;
6
- };
7
- export declare function discardPlacedDraft(deps: HelpdeskDeps, run: DraftRun, access: MailboxAccess, threadId: string): Promise<void>;
package/dist/cleanup.js DELETED
@@ -1,39 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sendIntentIds = sendIntentIds;
4
- exports.discardPlacedDraft = discardPlacedDraft;
5
- const internal_1 = require("./internal");
6
- const KEEP_FOR_INTENT = ["intended", "sending", "unknown", "sent"];
7
- function sendIntentIds(run) {
8
- return {
9
- perRun: `send:${run.mailbox}:${run.idempotencyKey}`,
10
- perDraft: run.placedDraftId ? `send:${run.mailbox}:${run.placedDraftId}` : null,
11
- };
12
- }
13
- async function discardPlacedDraft(deps, run, access, threadId) {
14
- try {
15
- const draftId = run.placedDraftId;
16
- if (access.mode !== "drafts_in_outlook")
17
- return;
18
- if (!draftId || run.threadId !== threadId || run.mailbox !== access.mailbox)
19
- return;
20
- const { perRun, perDraft } = sendIntentIds(run);
21
- for (const id of [perRun, perDraft]) {
22
- const intent = id ? await deps.store.getSendIntent(id) : null;
23
- if (intent && KEEP_FOR_INTENT.includes(intent.status))
24
- return;
25
- }
26
- try {
27
- await access.gateway().deleteDraft(draftId);
28
- await deps.store.updateDraftRun(run.idempotencyKey, {
29
- placedDraftId: null,
30
- draftCleanupError: null,
31
- });
32
- }
33
- catch (err) {
34
- await deps.store.updateDraftRun(run.idempotencyKey, { draftCleanupError: (0, internal_1.errorText)(err) });
35
- }
36
- }
37
- catch {
38
- }
39
- }