@bobfrankston/mailx-types 0.1.10 → 0.1.12

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.
Files changed (3) hide show
  1. package/index.d.ts +25 -2
  2. package/index.js +44 -0
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -38,8 +38,7 @@ export interface AccountConfig {
38
38
  primaryContacts?: boolean; /** Per-feature override: use this account's Google Contacts. Falls back to `primary` if unset. */
39
39
  defaultSend?: boolean; /** Use this account's SMTP when From doesn't match any account */
40
40
  syncContacts?: boolean; /** Sync contacts even when account is disabled (contacts-only Gmail) */
41
- relayDomains?: string[]; /** Domains to skip in Delivered-To chain (e.g., ["m.connectivity.xyz"]) */
42
- deliveredToPrefix?: string[]; /** Prefixes to strip from Delivered-To to get clean alias (e.g., ["bobf-ma-", "bobf-"]) — order matters, longest first */
41
+ relayDomains?: string[]; /** Domains to skip in Delivered-To chain (e.g., ["relay.aaz.lt"]) */
43
42
  identityDomains?: string[]; /** Domains where Delivered-To address should become the reply From (e.g., ["bob.ma", "bobf.frankston.com"]) */
44
43
  spam?: string; /** IMAP folder path for "Mark as spam" button (e.g., "_spam"). Button hidden when not set. */
45
44
  signature?: string; /** Legacy: HTML signature appended to all outgoing messages (new + reply + forward). Plain text or HTML allowed. Superseded by `sig`. */
@@ -65,6 +64,30 @@ export interface Folder {
65
64
  unreadCount: number;
66
65
  children: Folder[]; /** Nested subfolders */
67
66
  }
67
+ interface FlagBearing {
68
+ flags: string[];
69
+ }
70
+ export declare const seenOf: (m: {
71
+ flags?: readonly string[];
72
+ }) => boolean;
73
+ export declare const flaggedOf: (m: {
74
+ flags?: readonly string[];
75
+ }) => boolean;
76
+ export declare const answeredOf: (m: {
77
+ flags?: readonly string[];
78
+ }) => boolean;
79
+ export declare const draftOf: (m: {
80
+ flags?: readonly string[];
81
+ }) => boolean;
82
+ export declare const deletedOf: (m: {
83
+ flags?: readonly string[];
84
+ }) => boolean;
85
+ export declare const setSeen: (m: FlagBearing, state: boolean) => void;
86
+ export declare const setFlagged: (m: FlagBearing, state: boolean) => void;
87
+ export declare const setAnswered: (m: FlagBearing, state: boolean) => void;
88
+ export declare const setDraft: (m: FlagBearing, state: boolean) => void;
89
+ export declare const toggleSeen: (m: FlagBearing) => void;
90
+ export declare const toggleFlagged: (m: FlagBearing) => void;
68
91
  /** Email address with optional display name */
69
92
  export interface EmailAddress {
70
93
  name: string; /** Display name, may be empty */
package/index.js CHANGED
@@ -12,6 +12,50 @@ export { CONTACT_RULES } from "./contact-rules.js";
12
12
  // send time. Both desktop and Android send paths consume this expander
13
13
  // against contacts.jsonc → groups.
14
14
  export { expandRecipients, splitRecipients, isAddressToken, extractAddress, } from "./groups.js";
15
+ // ── Message flag state ──
16
+ //
17
+ // External API surface for the IMAP system flags. The literal strings
18
+ // (`"\\Seen"`, `"\\Flagged"`, etc.) live ONLY inside this module — every
19
+ // caller speaks in terms of named predicates (`seenOf(msg)`) and verbs
20
+ // (`setSeen(msg, true)`, `toggleSeen(msg)`). That keeps a typo like
21
+ // `"\Seen"` (single backslash) from silently bypassing flag checks
22
+ // elsewhere, and removes the "two-API leak" of having both `FLAG.SEEN`
23
+ // constants AND verb helpers exposed simultaneously.
24
+ //
25
+ // These work against any object with a mutable `flags: string[]`
26
+ // property — `MessageEnvelope`, `Message`, and the row's `msg` reference
27
+ // all qualify. The verbs return `void` and mutate `msg.flags` in place
28
+ // (replacing the array with a fresh one so listeners observing
29
+ // reference identity, e.g. message-state, still re-render). Pure
30
+ // predicate calls (`seenOf`, `flaggedOf`) don't mutate.
31
+ const _SEEN = "\\Seen";
32
+ const _FLAGGED = "\\Flagged";
33
+ const _ANSWERED = "\\Answered";
34
+ const _DRAFT = "\\Draft";
35
+ const _DELETED = "\\Deleted";
36
+ function _has(msg, flag) {
37
+ return !!msg.flags && msg.flags.includes(flag);
38
+ }
39
+ function _set(msg, flag, state) {
40
+ const present = (msg.flags || []).includes(flag);
41
+ if (state === present)
42
+ return;
43
+ const next = state
44
+ ? [...(msg.flags || []), flag]
45
+ : (msg.flags || []).filter(f => f !== flag);
46
+ msg.flags = next;
47
+ }
48
+ export const seenOf = (m) => _has(m, _SEEN);
49
+ export const flaggedOf = (m) => _has(m, _FLAGGED);
50
+ export const answeredOf = (m) => _has(m, _ANSWERED);
51
+ export const draftOf = (m) => _has(m, _DRAFT);
52
+ export const deletedOf = (m) => _has(m, _DELETED);
53
+ export const setSeen = (m, state) => _set(m, _SEEN, state);
54
+ export const setFlagged = (m, state) => _set(m, _FLAGGED, state);
55
+ export const setAnswered = (m, state) => _set(m, _ANSWERED, state);
56
+ export const setDraft = (m, state) => _set(m, _DRAFT, state);
57
+ export const toggleSeen = (m) => _set(m, _SEEN, !_has(m, _SEEN));
58
+ export const toggleFlagged = (m) => _set(m, _FLAGGED, !_has(m, _FLAGGED));
15
59
  // ── Shared Utilities ──
16
60
  // Pure functions used by both desktop (mailx-service) and Android (web-service).
17
61
  // Kept here to avoid duplication — both platforms import from mailx-types.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-types",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",