@push.rocks/smartjmap 1.0.0 → 2.0.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,109 @@
1
+ import type { IJmapEmailAddress } from './classes.jmapclient.js';
2
+ import { type IJmapAccountInfo, type IJmapBlobRecord, type IJmapChanges, type IJmapEmailQueryOptions, type IJmapEmailQueryResult, type IJmapEmailRecord, type IJmapEmailSetRequest, type IJmapEmailSetResult, type IJmapEnvelope, type IJmapGetResult, type IJmapIdentityRecord, type IJmapMailBackend, type IJmapMailboxRecord, type IJmapSubmissionInput, type IJmapSubmissionRecord, type IJmapThreadRecord, type TJmapChangeListener, type TJmapPrincipal } from './interfaces.backend.js';
3
+ /** A change-log entry: which ids changed at which numeric state. */
4
+ export interface IMemoryChangeEntry {
5
+ state: number;
6
+ created: string[];
7
+ updated: string[];
8
+ destroyed: string[];
9
+ }
10
+ /** Base mailbox fields stored in memory; counters are computed on read. */
11
+ export interface IMemoryMailbox {
12
+ id: string;
13
+ name: string;
14
+ role: string | null;
15
+ parentId: string | null;
16
+ sortOrder: number;
17
+ }
18
+ /** A stored submission, including the envelope and raw payload for inspection. */
19
+ export interface IMemorySubmission extends IJmapSubmissionRecord {
20
+ envelope: IJmapEnvelope;
21
+ message: Uint8Array;
22
+ }
23
+ /** The in-memory per-account store, exposed publicly for test assertions. */
24
+ export interface IMemoryMailAccount {
25
+ username: string;
26
+ accountId: string;
27
+ mailboxes: Map<string, IMemoryMailbox>;
28
+ emails: Map<string, IJmapEmailRecord>;
29
+ blobs: Map<string, IJmapBlobRecord>;
30
+ submissions: Map<string, IMemorySubmission>;
31
+ identities: IJmapIdentityRecord[];
32
+ emailState: number;
33
+ emailChanges: IMemoryChangeEntry[];
34
+ mailboxState: number;
35
+ mailboxChanges: IMemoryChangeEntry[];
36
+ threadIdsBySubject: Map<string, string>;
37
+ idCounter: number;
38
+ }
39
+ /** Seeding input for `addEmail`: a convenience superset of an Email create. */
40
+ export interface IMemoryEmailInput {
41
+ from: IJmapEmailAddress | IJmapEmailAddress[];
42
+ to: IJmapEmailAddress | IJmapEmailAddress[];
43
+ cc?: IJmapEmailAddress[];
44
+ bcc?: IJmapEmailAddress[];
45
+ subject?: string;
46
+ textBody?: string;
47
+ htmlBody?: string;
48
+ keywords?: Record<string, boolean>;
49
+ receivedAt?: string;
50
+ attachments?: Array<{
51
+ name: string;
52
+ type: string;
53
+ content: string | Uint8Array;
54
+ }>;
55
+ }
56
+ /**
57
+ * The in-memory reference implementation of `IJmapMailBackend`, used as the
58
+ * default backend of `JmapServer` for offline testing. Accounts are keyed by
59
+ * username (accountId = `account_<username>`) and auto-created on first
60
+ * reference. Seeding helpers: `addAccount`, `createMailbox`, `addEmail`.
61
+ *
62
+ * Documented simplifications: thread ids derive from normalized subjects (not
63
+ * References headers), raw RFC 5322 blobs render headers + the text body only
64
+ * (attachments are separate blobs, not MIME-encoded into the raw message),
65
+ * the change log grows unboundedly (one entry per mutation), and destroyed
66
+ * emails leave their blobs in the blob store.
67
+ */
68
+ export declare class MemoryMailBackend implements IJmapMailBackend {
69
+ accounts: Map<string, IMemoryMailAccount>;
70
+ private changeListeners;
71
+ /** Ensures an account exists for the username and returns it. */
72
+ addAccount(username: string): IMemoryMailAccount;
73
+ /** Creates a mailbox (name must be unique per account). Returns the mailbox id. */
74
+ createMailbox(username: string, name: string, role?: string): string;
75
+ /**
76
+ * Seeds an email into a mailbox (matched by name or role), bumps the Email
77
+ * state, and notifies change listeners — connected JmapServers turn this
78
+ * into a StateChange push. Returns the email id.
79
+ */
80
+ addEmail(username: string, mailboxName: string, input: IMemoryEmailInput): string;
81
+ resolveAccount(principal: TJmapPrincipal): Promise<IJmapAccountInfo | null>;
82
+ getMailboxes(accountId: string, ids: string[] | null): Promise<IJmapGetResult<IJmapMailboxRecord>>;
83
+ getMailboxChanges(accountId: string, sinceState: string, maxChanges?: number): Promise<IJmapChanges | null>;
84
+ getEmails(accountId: string, ids: string[], _properties?: string[] | null): Promise<IJmapGetResult<IJmapEmailRecord>>;
85
+ queryEmails(accountId: string, options: IJmapEmailQueryOptions): Promise<IJmapEmailQueryResult>;
86
+ getEmailChanges(accountId: string, sinceState: string, maxChanges?: number): Promise<IJmapChanges | null>;
87
+ setEmails(accountId: string, request: IJmapEmailSetRequest): Promise<IJmapEmailSetResult>;
88
+ getThreads(accountId: string, ids: string[]): Promise<IJmapGetResult<IJmapThreadRecord>>;
89
+ uploadBlob(accountId: string, data: Uint8Array, type: string): Promise<{
90
+ blobId: string;
91
+ size: number;
92
+ }>;
93
+ getBlob(accountId: string, blobId: string): Promise<IJmapBlobRecord | null>;
94
+ getIdentities(accountId: string): Promise<IJmapGetResult<IJmapIdentityRecord>>;
95
+ submitEmail(accountId: string, submission: IJmapSubmissionInput): Promise<IJmapSubmissionRecord>;
96
+ subscribeToChanges(listener: TJmapChangeListener): () => void;
97
+ private ensureAccount;
98
+ private requireAccountById;
99
+ private matchesFilter;
100
+ /** Builds a full email record from a validated create spec. Throws JmapBackendError. */
101
+ private buildEmailRecord;
102
+ /** Applies a normalized email update in place. Throws JmapBackendError. */
103
+ private applyEmailUpdate;
104
+ private resolveThreadId;
105
+ private collectChanges;
106
+ private bumpEmailState;
107
+ private emitChange;
108
+ private toSetError;
109
+ }