@fluxmail/core 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.
@@ -0,0 +1,5 @@
1
+ import type { EmailAddress } from './types.js';
2
+ /** Parse an RFC 5322 address list ("Ann <a@x.com>, b@y.com") into structured addresses. */
3
+ export declare function parseAddressList(raw: string | undefined): EmailAddress[];
4
+ export declare function parseSingleAddress(raw: string): EmailAddress | null;
5
+ //# sourceMappingURL=addresses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addresses.d.ts","sourceRoot":"","sources":["../src/addresses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,EAAE,CAoBxE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAanE"}
@@ -0,0 +1,48 @@
1
+ /** Parse an RFC 5322 address list ("Ann <a@x.com>, b@y.com") into structured addresses. */
2
+ export function parseAddressList(raw) {
3
+ if (!raw)
4
+ return [];
5
+ const out = [];
6
+ let depth = 0;
7
+ let inQuotes = false;
8
+ let current = '';
9
+ const flush = () => {
10
+ const addr = parseSingleAddress(current.trim());
11
+ if (addr)
12
+ out.push(addr);
13
+ current = '';
14
+ };
15
+ for (const ch of raw) {
16
+ if (ch === '"')
17
+ inQuotes = !inQuotes;
18
+ else if (!inQuotes && ch === '(')
19
+ depth++;
20
+ else if (!inQuotes && ch === ')')
21
+ depth = Math.max(0, depth - 1);
22
+ if (ch === ',' && !inQuotes && depth === 0)
23
+ flush();
24
+ else
25
+ current += ch;
26
+ }
27
+ flush();
28
+ return out;
29
+ }
30
+ export function parseSingleAddress(raw) {
31
+ if (!raw)
32
+ return null;
33
+ const angled = raw.match(/^\s*(?:"?([^"]*)"?\s+)?<([^>]+)>\s*$/);
34
+ if (angled?.[2]) {
35
+ const name = angled[1]?.trim();
36
+ const email = angled[2].trim();
37
+ if (!/^[^\s<>,;@]+@[^\s<>,;@]+$/.test(email))
38
+ return null;
39
+ return { email, ...(name ? { name } : {}) };
40
+ }
41
+ if ((raw.match(/@/g) ?? []).length !== 1)
42
+ return null;
43
+ const bare = raw.match(/[^\s<>,;@]+@[^\s<>,;@]+/);
44
+ if (bare)
45
+ return { email: bare[0] };
46
+ return null;
47
+ }
48
+ //# sourceMappingURL=addresses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addresses.js","sourceRoot":"","sources":["../src/addresses.ts"],"names":[],"mappings":"AAEA,2FAA2F;AAC3F,MAAM,UAAU,gBAAgB,CAAC,GAAuB;IACtD,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,IAAI;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,OAAO,GAAG,EAAE,CAAC;IACf,CAAC,CAAC;IACF,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,EAAE,KAAK,GAAG;YAAE,QAAQ,GAAG,CAAC,QAAQ,CAAC;aAChC,IAAI,CAAC,QAAQ,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aACrC,IAAI,CAAC,QAAQ,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QACjE,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,CAAC;YAAE,KAAK,EAAE,CAAC;;YAC/C,OAAO,IAAI,EAAE,CAAC;IACrB,CAAC;IACD,KAAK,EAAE,CAAC;IACR,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACjE,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1D,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAClD,IAAI,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type EmailErrorCode = 'auth_expired' | 'rate_limited' | 'not_found' | 'invalid_request' | 'provider_unavailable' | 'entitlement_exceeded' | 'unsupported_capability';
2
+ export declare class EmailError extends Error {
3
+ readonly code: EmailErrorCode;
4
+ /** Machine-readable extras, e.g. { reauthUrl } for auth_expired. */
5
+ readonly data?: Record<string, unknown>;
6
+ constructor(code: EmailErrorCode, message: string, data?: Record<string, unknown>);
7
+ }
8
+ export declare function isEmailError(err: unknown): err is EmailError;
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,cAAc,GACd,WAAW,GACX,iBAAiB,GACjB,sBAAsB,GACtB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE5B,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMlF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,UAAU,CAE5D"}
package/dist/errors.js ADDED
@@ -0,0 +1,15 @@
1
+ export class EmailError extends Error {
2
+ code;
3
+ /** Machine-readable extras, e.g. { reauthUrl } for auth_expired. */
4
+ data;
5
+ constructor(code, message, data) {
6
+ super(message);
7
+ this.name = 'EmailError';
8
+ this.code = code;
9
+ this.data = data;
10
+ }
11
+ }
12
+ export function isEmailError(err) {
13
+ return err instanceof EmailError;
14
+ }
15
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IAC9B,oEAAoE;IAC3D,IAAI,CAA2B;IAExC,YAAY,IAAoB,EAAE,OAAe,EAAE,IAA8B;QAC/E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO,GAAG,YAAY,UAAU,CAAC;AACnC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './types.js';
2
+ export * from './errors.js';
3
+ export * from './provider.js';
4
+ export * from './reply.js';
5
+ export * from './addresses.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './types.js';
2
+ export * from './errors.js';
3
+ export * from './provider.js';
4
+ export * from './reply.js';
5
+ export * from './addresses.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { AttachmentMeta, Capabilities, DraftInput, EmailQuery, Folder, Message, ModifyAction, Page, PageOpts, SendResult, Thread } from './types.js';
2
+ export interface GetMessageOpts {
3
+ /** Include selected RFC 5322 headers (Message-ID, References, ...). */
4
+ includeHeaders?: boolean;
5
+ }
6
+ /**
7
+ * The unified provider contract. Every provider package (gmail, outlook, imap)
8
+ * implements exactly this; nothing above this layer knows which provider it
9
+ * is talking to.
10
+ */
11
+ export interface EmailProvider {
12
+ readonly capabilities: Capabilities;
13
+ /** Cheap connectivity + auth check. Throws EmailError('auth_expired') on bad credentials. */
14
+ testConnection(): Promise<void>;
15
+ /** Metadata-level listing (no bodies). */
16
+ listMessages(q: EmailQuery, page?: PageOpts): Promise<Page<Message>>;
17
+ /** Full message including body and attachment metadata. */
18
+ getMessage(id: string, opts?: GetMessageOpts): Promise<Message>;
19
+ getThread(threadId: string): Promise<Thread>;
20
+ listFolders(): Promise<Folder[]>;
21
+ createDraft(d: DraftInput): Promise<Message>;
22
+ /** Fetch a draft by draft id (message with draftId populated). */
23
+ getDraft(draftId: string): Promise<Message>;
24
+ updateDraft(draftId: string, d: DraftInput): Promise<Message>;
25
+ deleteDraft(draftId: string): Promise<void>;
26
+ send(input: DraftInput | {
27
+ draftId: string;
28
+ }): Promise<SendResult>;
29
+ modify(ids: string[], action: ModifyAction): Promise<void>;
30
+ getAttachment(messageId: string, attachmentId: string): Promise<{
31
+ meta: AttachmentMeta;
32
+ content: Buffer;
33
+ }>;
34
+ }
35
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,EACV,MAAM,EACN,OAAO,EACP,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,MAAM,EACP,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAEpC,6FAA6F;IAC7F,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC,0CAA0C;IAC1C,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,2DAA2D;IAC3D,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEjC,WAAW,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEnE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import type { EmailAddress, Message } from './types.js';
2
+ export interface ReplyRecipients {
3
+ to: EmailAddress[];
4
+ cc: EmailAddress[];
5
+ }
6
+ /**
7
+ * Compute reply / reply-all recipients from the original message. Provider-agnostic:
8
+ * reply targets Reply-To (falling back to From); reply-all additionally includes the
9
+ * original To/Cc, minus the replying account's own address.
10
+ */
11
+ export declare function computeReplyRecipients(original: Message, ownAddress: string, replyAll: boolean): ReplyRecipients;
12
+ /** "Re: subject" without stacking prefixes. */
13
+ export declare function replySubject(subject: string): string;
14
+ /** "Fwd: subject" without stacking prefixes. */
15
+ export declare function forwardSubject(subject: string): string;
16
+ export declare function formatAddress(a: EmailAddress): string;
17
+ export declare function formatAddressList(addrs: EmailAddress[] | undefined): string;
18
+ //# sourceMappingURL=reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply.d.ts","sourceRoot":"","sources":["../src/reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,YAAY,EAAE,CAAC;IACnB,EAAE,EAAE,YAAY,EAAE,CAAC;CACpB;AAeD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,GAChB,eAAe,CAejB;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAErD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,SAAS,GAAG,MAAM,CAE3E"}
package/dist/reply.js ADDED
@@ -0,0 +1,45 @@
1
+ function sameAddress(a, b) {
2
+ return a.email.trim().toLowerCase() === b.email.trim().toLowerCase();
3
+ }
4
+ function dedupe(addrs) {
5
+ const out = [];
6
+ for (const a of addrs) {
7
+ if (!a.email)
8
+ continue;
9
+ if (!out.some((b) => sameAddress(a, b)))
10
+ out.push(a);
11
+ }
12
+ return out;
13
+ }
14
+ /**
15
+ * Compute reply / reply-all recipients from the original message. Provider-agnostic:
16
+ * reply targets Reply-To (falling back to From); reply-all additionally includes the
17
+ * original To/Cc, minus the replying account's own address.
18
+ */
19
+ export function computeReplyRecipients(original, ownAddress, replyAll) {
20
+ const self = { email: ownAddress };
21
+ const replyTarget = original.replyTo?.length ? original.replyTo : original.from ? [original.from] : [];
22
+ if (!replyAll) {
23
+ const to = dedupe(replyTarget).filter((a) => !sameAddress(a, self));
24
+ // Replying to yourself (e.g. a note in Sent): fall back to the original To.
25
+ return { to: to.length ? to : dedupe(original.to), cc: [] };
26
+ }
27
+ const to = dedupe([...replyTarget, ...original.to]).filter((a) => !sameAddress(a, self));
28
+ const cc = dedupe(original.cc ?? []).filter((a) => !sameAddress(a, self) && !to.some((b) => sameAddress(a, b)));
29
+ return { to: to.length ? to : [self], cc };
30
+ }
31
+ /** "Re: subject" without stacking prefixes. */
32
+ export function replySubject(subject) {
33
+ return /^\s*re:/i.test(subject) ? subject : `Re: ${subject}`;
34
+ }
35
+ /** "Fwd: subject" without stacking prefixes. */
36
+ export function forwardSubject(subject) {
37
+ return /^\s*fwd?:/i.test(subject) ? subject : `Fwd: ${subject}`;
38
+ }
39
+ export function formatAddress(a) {
40
+ return a.name ? `${a.name} <${a.email}>` : a.email;
41
+ }
42
+ export function formatAddressList(addrs) {
43
+ return (addrs ?? []).map(formatAddress).join(', ');
44
+ }
45
+ //# sourceMappingURL=reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply.js","sourceRoot":"","sources":["../src/reply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ export type Provider = 'gmail' | 'outlook' | 'imap';
2
+ export interface Capabilities {
3
+ /** Gmail: many-to-many labels. Outlook/IMAP: a message lives in exactly one folder. */
4
+ labels: boolean;
5
+ /** Gmail/Outlook thread server-side; IMAP threads are synthesized from References headers. */
6
+ serverThreads: boolean;
7
+ /** Gmail q= / Graph $search vs IMAP SEARCH. */
8
+ serverSearch: 'rich' | 'basic';
9
+ /** Whether list results include snippets without fetching bodies. */
10
+ snippets: boolean;
11
+ }
12
+ export interface Account {
13
+ id: string;
14
+ provider: Provider;
15
+ email: string;
16
+ displayName?: string;
17
+ status: 'active' | 'auth_error' | 'disabled';
18
+ capabilities: Capabilities;
19
+ /** Owning member on the instance; absent means the mailbox is shared. */
20
+ memberId?: string;
21
+ }
22
+ export interface EmailAddress {
23
+ name?: string;
24
+ email: string;
25
+ }
26
+ export type FolderRole = 'inbox' | 'sent' | 'drafts' | 'trash' | 'spam' | 'archive' | 'starred' | 'all';
27
+ export interface Folder {
28
+ id: string;
29
+ /** Display path, e.g. "Projects/2026". */
30
+ name: string;
31
+ role?: FolderRole;
32
+ unreadCount?: number;
33
+ }
34
+ export interface AttachmentMeta {
35
+ id: string;
36
+ filename: string;
37
+ mimeType: string;
38
+ sizeBytes: number;
39
+ /** RFC Content-ID without angle brackets, used by HTML cid: references. */
40
+ contentId?: string;
41
+ disposition?: 'inline' | 'attachment';
42
+ }
43
+ export interface MessageBody {
44
+ text?: string;
45
+ html?: string;
46
+ }
47
+ export interface MessageFlags {
48
+ read: boolean;
49
+ starred: boolean;
50
+ draft: boolean;
51
+ }
52
+ export interface Message {
53
+ id: string;
54
+ threadId: string;
55
+ accountId: string;
56
+ /** Present when this message is a draft; use with updateDraft/deleteDraft/send. */
57
+ draftId?: string;
58
+ /** Canonical location. Gmail: derived from labels; Outlook/IMAP: the containing folder. */
59
+ folder?: Folder;
60
+ /** Gmail only (capabilities.labels). Label names. */
61
+ labels?: string[];
62
+ from?: EmailAddress;
63
+ to: EmailAddress[];
64
+ cc?: EmailAddress[];
65
+ bcc?: EmailAddress[];
66
+ replyTo?: EmailAddress[];
67
+ subject: string;
68
+ /** ISO 8601. */
69
+ date: string;
70
+ snippet?: string;
71
+ /** Populated on getMessage/getThread, not on list. */
72
+ body?: MessageBody;
73
+ /** Populated on getMessage/getThread; omitted when a list response has no MIME metadata. */
74
+ attachments?: AttachmentMeta[];
75
+ flags: MessageFlags;
76
+ /** Selected RFC 5322 headers (Message-ID, References, In-Reply-To, ...) when requested. */
77
+ headers?: Record<string, string>;
78
+ }
79
+ export interface Thread {
80
+ id: string;
81
+ subject: string;
82
+ messages: Message[];
83
+ }
84
+ export interface AttachmentInput {
85
+ filename: string;
86
+ mimeType: string;
87
+ /** Base64-encoded content. */
88
+ content: string;
89
+ /** Preserve embedded HTML images when forwarding. */
90
+ contentId?: string;
91
+ disposition?: 'inline' | 'attachment';
92
+ }
93
+ export interface DraftInput {
94
+ /** Optional when derived from a reply (replyToMessageId). */
95
+ to?: EmailAddress[];
96
+ cc?: EmailAddress[];
97
+ bcc?: EmailAddress[];
98
+ /** Defaults to "Re: ..." when replying. */
99
+ subject?: string;
100
+ body: MessageBody;
101
+ attachments?: AttachmentInput[];
102
+ /**
103
+ * Reply threading: the adapter resolves this message's Message-ID/References
104
+ * (and provider thread id) so the sent message threads correctly everywhere.
105
+ */
106
+ replyToMessageId?: string;
107
+ }
108
+ export interface SendResult {
109
+ id: string;
110
+ threadId: string;
111
+ }
112
+ export type ModifyAction = 'markRead' | 'markUnread' | 'star' | 'unstar' | 'archive' | 'trash' | 'untrash' | 'delete' | {
113
+ move: string;
114
+ } | {
115
+ addLabels: string[];
116
+ } | {
117
+ removeLabels: string[];
118
+ };
119
+ export interface EmailQuery {
120
+ /** Folder id or role. Defaults to no folder restriction. */
121
+ folder?: string;
122
+ /** Full-text search. */
123
+ text?: string;
124
+ from?: string;
125
+ to?: string;
126
+ subject?: string;
127
+ unreadOnly?: boolean;
128
+ starredOnly?: boolean;
129
+ hasAttachment?: boolean;
130
+ /** ISO date (inclusive). */
131
+ after?: string;
132
+ /** ISO date (exclusive). */
133
+ before?: string;
134
+ /** Escape hatch: passed to the provider verbatim (e.g. Gmail q=). */
135
+ rawProviderQuery?: string;
136
+ }
137
+ export interface PageOpts {
138
+ pageSize?: number;
139
+ pageToken?: string;
140
+ }
141
+ export interface Page<T> {
142
+ items: T[];
143
+ nextPageToken?: string;
144
+ }
145
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@fluxmail/core",
3
+ "version": "0.1.0",
4
+ "description": "Unified email types and provider interface for Fluxmail",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^22.15.0"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc -p tsconfig.json",
25
+ "typecheck": "tsc -p tsconfig.json --noEmit",
26
+ "test": "vitest run"
27
+ }
28
+ }