@framers/agentos-ext-gmail-source 0.2.0 → 0.4.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.js CHANGED
@@ -1,12 +1,18 @@
1
1
  /**
2
2
  * @fileoverview A read-only Gmail source's grant: Google's read-only scope on the AgentOS redirect OAuth flow and
3
- * sealed-token store, with capped, cancellable OAuth calls and fixed failures; and its text helpers: bounded
3
+ * sealed-token store, with capped, cancellable OAuth calls and fixed failures; its text helpers: bounded
4
4
  * pre-storage sanitization of mail text, allow-listed headers and metadata, and conservative trimming of reply history
5
- * and signatures.
5
+ * and signatures; its thread mapper: bounded MIME reading of one thread into a sanitized account-source document
6
+ * with message provenance, attachment listings and an explicit cache decision; and its read-only API client: capped
7
+ * profile, label, list, history and thread calls through the host's grant and quota services, with fixed failures.
6
8
  * @module agentos-ext-gmail-source
7
9
  */
8
10
  export { GmailOAuthFlow } from './GmailOAuthFlow.js';
9
11
  export { GMAIL_READONLY_SCOPE, GmailOAuthFault, } from './types.js';
10
12
  export { GmailTextFault, sanitizeMailText, sanitizeMailMetadata, sanitizeMailHeaders, } from './mailSanitize.js';
11
13
  export { messageText } from './messageText.js';
14
+ export { GmailThreadMapper } from './mapThread.js';
15
+ export { GmailMappingFault } from './mime.js';
16
+ export { GmailApi, GmailApiFault, } from './gmail.js';
17
+ export { classifyGmailHttp, gmailOAuthFault } from './retry.js';
12
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,oBAAoB,EAAE,eAAe,GAEtC,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,GAG5E,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,oBAAoB,EAAE,eAAe,GAEtC,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,GAG5E,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAA8B,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAA2B,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,QAAQ,EAAE,aAAa,GAExB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAA6B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { type SourceCachePermission, type SourceCacheHeaders, type SourceCacheDecision, type SourceSyncReadResult } from '@framers/agentos-ext-account-sources';
2
+ import { type GmailMappingBounds } from './mime.js';
3
+ /** The per-read values of one `map` call. The host supplies every value; none comes from a browser request. */
4
+ export interface GmailMapThreadOptions {
5
+ /** The requested thread id; the response must carry the same id. */
6
+ readonly sourceId: string;
7
+ /**
8
+ * The host's authenticated source-detail path, used as `SourceRef.url`: a relative path of segments made of letters,
9
+ * digits, `_` and `-`, with no query, fragment or origin, at most 512 characters. Never a Gmail link.
10
+ */
11
+ readonly sourceDetailUrl: string;
12
+ /** The selection cutoff, epoch milliseconds, no later than `receivedAt`: a message received after it is left out. */
13
+ readonly cutoff: number;
14
+ /**
15
+ * The message window in milliseconds, 1 to 90 days. A message received at or before `cutoff - windowMs`, or whose
16
+ * window has ended by `receivedAt`, is left out.
17
+ */
18
+ readonly windowMs: number;
19
+ /** When the thread request started, epoch milliseconds. */
20
+ readonly readStartedAt: number;
21
+ /** When the thread response was complete, epoch milliseconds; it becomes `SourceRef.readAt`. */
22
+ readonly receivedAt: number;
23
+ /** The host's evidenced cache permission; null refuses durable content. */
24
+ readonly permission: SourceCachePermission | null;
25
+ /** The thread response's own cache headers. */
26
+ readonly cacheHeaders: SourceCacheHeaders;
27
+ /** Label names from the cycle's labels response, by label id. */
28
+ readonly labelNames: Readonly<Record<string, string>>;
29
+ /** The labels response's own cache decision. Null, a refusal or an expired decision keeps ids without names. */
30
+ readonly labelCache: SourceCacheDecision | null;
31
+ /** Cancels the call between steps. */
32
+ readonly signal?: AbortSignal;
33
+ }
34
+ /**
35
+ * Maps one parsed Gmail thread into a sanitized account-source document: one thread, one document, with each retained
36
+ * message's id, dates, sanitized headers, labels, attachment listing and body span. It calls no endpoint, writes no log
37
+ * and keeps no state between calls.
38
+ */
39
+ export declare class GmailThreadMapper {
40
+ private readonly bounds;
41
+ /**
42
+ * @param bounds Every operational ceiling; see `GmailMappingBounds`.
43
+ * @throws {GmailMappingFault} `configuration` for an invalid bound.
44
+ */
45
+ constructor(bounds: GmailMappingBounds);
46
+ private policy;
47
+ private normalize;
48
+ /**
49
+ * Validates the whole response, filters each message by its internal date and by the spam, trash and draft labels,
50
+ * keeps the newest eligible messages up to the cap with ties broken by id, spends the thread's character budget
51
+ * newest first and renders the kept messages oldest first. A message's text is its sanitized header prefix followed
52
+ * by its sanitized, trimmed body, and its span covers the body alone. A message that cannot be read is counted under
53
+ * `metadata.omitted` by a fixed reason. The cache expiry is the earliest of the permission's retention, the read start
54
+ * plus `maximumCacheMs`, the response's cache headers, every kept message's window end and the label names' expiry.
55
+ *
56
+ * @param input The parsed `threads.get` response in the `full` format, from a transport that capped its bytes.
57
+ * @param options The per-read values.
58
+ * @returns A document, or a skip with a fixed reason: a thread-wide bound was exceeded, no message survived, or the
59
+ * cache policy refused durable content.
60
+ * @throws {GmailMappingFault} `configuration` for invalid options.
61
+ * @throws {SourceSyncFault} `invalid_response` for an invalid response, never an empty success; `cancelled` once the
62
+ * signal is aborted.
63
+ */
64
+ map(input: unknown, options: GmailMapThreadOptions): Promise<SourceSyncReadResult>;
65
+ }
66
+ //# sourceMappingURL=mapThread.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapThread.d.ts","sourceRoot":"","sources":["../src/mapThread.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EACjD,KAAK,oBAAoB,EACtD,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,WAAW,CAAC;AAOnB,+GAA+G;AAC/G,MAAM,WAAW,qBAAqB;IACpC,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,qHAAqH;IACrH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gGAAgG;IAChG,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAClD,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,gHAAgH;IAChH,QAAQ,CAAC,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAChD,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAyCD;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C;;;OAGG;gBACS,MAAM,EAAE,kBAAkB;IAEtC,OAAO,CAAC,MAAM;YAKA,SAAS;IAyBvB;;;;;;;;;;;;;;;OAeG;IACG,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAmFzF"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * @fileoverview Thread document mapping: one Gmail thread becomes one account-source document whose text holds each
3
+ * retained message's sanitized header prefix and trimmed body, with message ids, body spans, labels, attachment
4
+ * listings, omission counts and the earliest permitted cache expiry. The transient MIME objects are never returned or
5
+ * persisted, and the account-source store's fences still decide what is committed.
6
+ * @module agentos-ext-gmail-source/mapThread
7
+ */
8
+ import { createHash } from 'node:crypto';
9
+ import { decideSourceCache, SourceSyncFault, } from '@framers/agentos-ext-account-sources';
10
+ import { GmailMappingFault, mappingBounds, mappingActive, gmailId, parseMimeThread, decodedHeaders, decodeMimeWords, mimeBody, } from './mime.js';
11
+ import { GmailTextFault, sanitizeMailHeaders, sanitizeMailMetadata, } from './mailSanitize.js';
12
+ import { messageText } from './messageText.js';
13
+ // An epoch-millisecond value a Date can hold.
14
+ const validTime = (n) => Number.isSafeInteger(n) && n >= 0 && n <= 8_640_000_000_000_000;
15
+ const compareId = (a, b) => a < b ? -1 : a > b ? 1 : 0;
16
+ // Newest first, ties broken by id, so the selection is stable.
17
+ const newest = (a, b) => b.receivedAt - a.receivedAt || compareId(a.id, b.id);
18
+ // Clips without leaving the high half of a surrogate pair at the end.
19
+ function clip(text, maximum) {
20
+ let end = Math.min(text.length, maximum);
21
+ if (end > 0 && end < text.length && /[\uD800-\uDBFF]/.test(text[end - 1]) && /[\uDC00-\uDFFF]/.test(text[end]))
22
+ end--;
23
+ return text.slice(0, end);
24
+ }
25
+ // Refuses options that would point attribution outside the host or leave the window or the clock unbounded.
26
+ function configuration(options) {
27
+ const url = options.sourceDetailUrl;
28
+ if (!gmailId(options.sourceId) || typeof url !== 'string' || !/^\/[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*\/?$/.test(url)
29
+ || url.length > 512 || !validTime(options.cutoff) || !validTime(options.readStartedAt)
30
+ || !validTime(options.receivedAt) || options.receivedAt < options.readStartedAt || options.cutoff > options.receivedAt
31
+ || !Number.isSafeInteger(options.windowMs) || options.windowMs < 1 || options.windowMs > 90 * 86_400_000) {
32
+ throw new GmailMappingFault('configuration');
33
+ }
34
+ }
35
+ // The skip reason a refusal stands for; every other error propagates.
36
+ function mappingReason(error) {
37
+ if (error instanceof GmailMappingFault && error.reason !== 'configuration')
38
+ return error.reason;
39
+ if (error instanceof GmailTextFault && error.reason === 'input_too_large')
40
+ return 'response_too_large';
41
+ return null;
42
+ }
43
+ /**
44
+ * Maps one parsed Gmail thread into a sanitized account-source document: one thread, one document, with each retained
45
+ * message's id, dates, sanitized headers, labels, attachment listing and body span. It calls no endpoint, writes no log
46
+ * and keeps no state between calls.
47
+ */
48
+ export class GmailThreadMapper {
49
+ bounds;
50
+ /**
51
+ * @param bounds Every operational ceiling; see `GmailMappingBounds`.
52
+ * @throws {GmailMappingFault} `configuration` for an invalid bound.
53
+ */
54
+ constructor(bounds) { this.bounds = mappingBounds(bounds); }
55
+ // The sanitizer policy for one output cap.
56
+ policy(maximum) {
57
+ return { maxInputCharacters: this.bounds.maxInputCharacters,
58
+ maxLineCharacters: this.bounds.maxLineCharacters, maxOutputCharacters: Math.min(maximum, this.bounds.maxInputCharacters) };
59
+ }
60
+ // Decodes, sanitizes and trims one message; `map` counts its refusals against this message alone.
61
+ async normalize(message, budget, options) {
62
+ mappingActive(options.signal);
63
+ const metadataPolicy = this.policy(1000);
64
+ const headers = sanitizeMailHeaders(decodedHeaders(message.payload, budget), metadataPolicy);
65
+ const body = await mimeBody(message.payload, budget, options.signal);
66
+ mappingActive(options.signal);
67
+ const clean = messageText(body.text, this.policy(this.bounds.maxMessageCharacters));
68
+ const metadata = (input, maximum = 200) => sanitizeMailMetadata(decodeMimeWords(input, budget), this.policy(maximum)).text;
69
+ const attachments = body.attachments.map((attachment) => ({
70
+ filename: metadata(attachment.filename), mediaType: metadata(attachment.mediaType, 128), size: attachment.size,
71
+ }));
72
+ const labels = message.labels.map((id) => {
73
+ const permitted = options.labelCache?.kind === 'cache' && validTime(options.labelCache.expiresAt) && options.labelCache.expiresAt > options.receivedAt && options.labelCache.evidenceId.length > 0;
74
+ const raw = permitted && Object.hasOwn(options.labelNames, id) ? options.labelNames[id] : id;
75
+ if (typeof raw !== 'string')
76
+ throw new SourceSyncFault('invalid_response');
77
+ return { id, name: metadata(raw) };
78
+ });
79
+ const lines = ['subject', 'date', 'from', 'to', 'cc']
80
+ .filter((key) => headers[key] !== '').map((key) => key[0].toUpperCase() + key.slice(1) + ': ' + headers[key]);
81
+ const prefix = lines.length > 0 ? lines.join('\n') + '\n\n' : '';
82
+ if (!prefix && !clean.text)
83
+ throw new GmailMappingFault('no_eligible_content');
84
+ return { message, headers, prefix, body: clean.text,
85
+ trimmedQuote: clean.trimmedQuote, trimmedSignature: clean.trimmedSignature, truncated: clean.truncated,
86
+ attachments, labels, unsupportedParts: body.unsupportedParts };
87
+ }
88
+ /**
89
+ * Validates the whole response, filters each message by its internal date and by the spam, trash and draft labels,
90
+ * keeps the newest eligible messages up to the cap with ties broken by id, spends the thread's character budget
91
+ * newest first and renders the kept messages oldest first. A message's text is its sanitized header prefix followed
92
+ * by its sanitized, trimmed body, and its span covers the body alone. A message that cannot be read is counted under
93
+ * `metadata.omitted` by a fixed reason. The cache expiry is the earliest of the permission's retention, the read start
94
+ * plus `maximumCacheMs`, the response's cache headers, every kept message's window end and the label names' expiry.
95
+ *
96
+ * @param input The parsed `threads.get` response in the `full` format, from a transport that capped its bytes.
97
+ * @param options The per-read values.
98
+ * @returns A document, or a skip with a fixed reason: a thread-wide bound was exceeded, no message survived, or the
99
+ * cache policy refused durable content.
100
+ * @throws {GmailMappingFault} `configuration` for invalid options.
101
+ * @throws {SourceSyncFault} `invalid_response` for an invalid response, never an empty success; `cancelled` once the
102
+ * signal is aborted.
103
+ */
104
+ async map(input, options) {
105
+ configuration(options);
106
+ mappingActive(options.signal);
107
+ const skipped = (reason) => ({ kind: 'skipped', id: options.sourceId, reason });
108
+ const budget = { bounds: this.bounds, rawBytes: 0, decodedBytes: 0, parts: 0 };
109
+ let thread;
110
+ try {
111
+ thread = parseMimeThread(input, options.sourceId, budget, options.signal);
112
+ }
113
+ catch (error) {
114
+ const reason = mappingReason(error);
115
+ if (reason)
116
+ return skipped(reason);
117
+ throw error;
118
+ }
119
+ const omitted = {};
120
+ const omit = (reason, count = 1) => { if (count > 0)
121
+ omitted[reason] = (omitted[reason] ?? 0) + count; };
122
+ const eligible = [];
123
+ for (const message of thread.messages) {
124
+ if (message.receivedAt > options.cutoff || message.receivedAt <= options.cutoff - options.windowMs
125
+ || !validTime(message.receivedAt + options.windowMs) || message.receivedAt + options.windowMs <= options.receivedAt) {
126
+ omit('out_of_window');
127
+ continue;
128
+ }
129
+ if (message.labels.some((label) => ['SPAM', 'TRASH', 'DRAFT'].includes(label))) {
130
+ omit('excluded_label');
131
+ continue;
132
+ }
133
+ eligible.push(message);
134
+ }
135
+ eligible.sort(newest);
136
+ const selected = eligible.slice(0, this.bounds.maxMessages);
137
+ omit('message_limit', eligible.length - selected.length);
138
+ const retained = [];
139
+ let used = 0;
140
+ let lastReason = 'no_eligible_content';
141
+ for (const message of selected) {
142
+ mappingActive(options.signal);
143
+ const remaining = this.bounds.maxThreadCharacters - used - (retained.length ? 2 : 0);
144
+ if (remaining <= 0) {
145
+ omit('thread_limit');
146
+ continue;
147
+ }
148
+ let normalized;
149
+ try {
150
+ normalized = await this.normalize(message, budget, options);
151
+ }
152
+ catch (error) {
153
+ const reason = mappingReason(error);
154
+ if (!reason)
155
+ throw error;
156
+ lastReason = reason;
157
+ omit(reason);
158
+ continue;
159
+ }
160
+ mappingActive(options.signal);
161
+ const maximum = Math.min(this.bounds.maxMessageCharacters, remaining);
162
+ if (normalized.prefix.length > maximum) {
163
+ lastReason = 'structure_limit';
164
+ omit('thread_limit');
165
+ continue;
166
+ }
167
+ const body = clip(normalized.body, maximum - normalized.prefix.length);
168
+ const text = normalized.prefix + body;
169
+ if (!text) {
170
+ lastReason = 'no_eligible_content';
171
+ omit(lastReason);
172
+ continue;
173
+ }
174
+ retained.push({ normalized, text, bodyStart: normalized.prefix.length,
175
+ truncated: normalized.truncated || body.length < normalized.body.length });
176
+ used += text.length + (retained.length > 1 ? 2 : 0);
177
+ }
178
+ if (retained.length === 0) {
179
+ if (eligible.length === 0)
180
+ lastReason = omitted.excluded_label ? 'excluded_label' : omitted.out_of_window ? 'out_of_window' : lastReason;
181
+ return skipped(lastReason);
182
+ }
183
+ retained.sort((a, b) => a.normalized.message.receivedAt - b.normalized.message.receivedAt
184
+ || compareId(a.normalized.message.id, b.normalized.message.id));
185
+ const messages = [];
186
+ const metadataMessages = [];
187
+ const texts = [];
188
+ let offset = 0;
189
+ for (const kept of retained) {
190
+ const { normalized } = kept;
191
+ const { message, headers } = normalized;
192
+ if (texts.length)
193
+ offset += 2;
194
+ messages.push({ messageId: message.id, start: offset + kept.bodyStart, end: offset + kept.text.length,
195
+ receivedAt: message.receivedAt, windowExpiresAt: message.receivedAt + options.windowMs, truncated: kept.truncated });
196
+ metadataMessages.push({ messageId: message.id, headers: { ...headers }, labels: normalized.labels,
197
+ attachments: normalized.attachments, trimmedQuote: normalized.trimmedQuote,
198
+ trimmedSignature: normalized.trimmedSignature, unsupportedParts: normalized.unsupportedParts });
199
+ texts.push(kept.text);
200
+ offset += kept.text.length;
201
+ }
202
+ const metadata = { messages: metadataMessages,
203
+ omitted: Object.fromEntries(Object.entries(omitted).sort(([a], [b]) => compareId(a, b))),
204
+ attachmentsRead: false };
205
+ const metadataJson = JSON.stringify(metadata);
206
+ if (metadataJson.length > this.bounds.maxMetadataCharacters)
207
+ return skipped('structure_limit');
208
+ const cache = decideSourceCache({ permission: options.permission, maximumCacheMs: this.bounds.maximumCacheMs,
209
+ readStartedAt: options.readStartedAt, receivedAt: options.receivedAt,
210
+ windowExpiresAt: Math.min(...messages.map((m) => m.windowExpiresAt)), headers: options.cacheHeaders });
211
+ if (cache.kind === 'skip')
212
+ return skipped(cache.reason);
213
+ const labelExpiry = options.labelCache?.kind === 'cache' && options.labelCache.expiresAt > options.receivedAt ? options.labelCache.expiresAt : cache.expiresAt;
214
+ const allowedCache = { ...cache, expiresAt: Math.min(cache.expiresAt, labelExpiry) };
215
+ const text = texts.join('\n\n');
216
+ const contentHash = createHash('sha256').update(JSON.stringify({ text, metadata, messages })).digest('hex');
217
+ const version = thread.historyId + ':' + contentHash;
218
+ const mostRecent = [...retained].sort((a, b) => newest(a.normalized.message, b.normalized.message));
219
+ const title = mostRecent.find((m) => m.normalized.headers.subject)?.normalized.headers.subject || 'Mail thread';
220
+ mappingActive(options.signal);
221
+ return { kind: 'document', document: {
222
+ read: { item: { id: thread.id, title, size: text.length, version }, content: { text },
223
+ ref: { kind: 'gmail', title, url: options.sourceDetailUrl, version, readAt: new Date(options.receivedAt).toISOString() } },
224
+ messages, metadata, activityAt: Math.max(...messages.map((m) => m.receivedAt)), contentHash, cache: allowedCache,
225
+ } };
226
+ }
227
+ }
228
+ //# sourceMappingURL=mapThread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapThread.js","sourceRoot":"","sources":["../src/mapThread.ts"],"names":[],"mappings":"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"}
package/dist/mime.d.ts ADDED
@@ -0,0 +1,141 @@
1
+ import { type SourceSyncSkipReason } from '@framers/agentos-ext-account-sources';
2
+ import type { GmailHeaderInput } from './mailSanitize.js';
3
+ /**
4
+ * The ceilings one mapper enforces, each a positive safe integer no greater than the value in brackets. They are
5
+ * operating choices, not Gmail service limits.
6
+ */
7
+ export interface GmailMappingBounds {
8
+ /** Bytes of recognized strings read from one parsed thread response (2,097,152). */
9
+ readonly maxResponseBytes: number;
10
+ /** Bytes decoded from bodies and encoded header words in one thread (2,097,152). */
11
+ readonly maxDecodedBytes: number;
12
+ /** MIME nesting depth, a message's payload being level 1 (20). */
13
+ readonly maxMimeDepth: number;
14
+ /** MIME parts across every message of the thread, and the entries any one list may hold (1,000). */
15
+ readonly maxMimeParts: number;
16
+ /** Messages retained in one thread document, newest first (100). */
17
+ readonly maxMessages: number;
18
+ /** UTF-16 code units of one message's header prefix and body together (20,000). */
19
+ readonly maxMessageCharacters: number;
20
+ /** UTF-16 code units of the thread document's text, separators included (200,000). */
21
+ readonly maxThreadCharacters: number;
22
+ /** Characters of the document's serialized metadata (200,000). */
23
+ readonly maxMetadataCharacters: number;
24
+ /** Characters one string may hold before or after decoding, and the sanitizer's input cap (2,097,152). */
25
+ readonly maxInputCharacters: number;
26
+ /** The sanitizer's line cap: a longer line is suppressed (65,536). */
27
+ readonly maxLineCharacters: number;
28
+ /** Cache lifetime in milliseconds a document may receive before permission and response limits (86,400,000). */
29
+ readonly maximumCacheMs: number;
30
+ }
31
+ /**
32
+ * A mapper's fixed refusal; its message is `gmail_mapping_<reason>` and never carries mail text. `configuration` is
33
+ * thrown for invalid bounds or options. `map` catches every other reason and answers it as a skipped thread, or counts
34
+ * it against the one message it concerns.
35
+ */
36
+ export declare class GmailMappingFault extends Error {
37
+ readonly reason: 'configuration' | SourceSyncSkipReason;
38
+ /** @param reason `configuration`, or the skip reason the refusal stands for. */
39
+ constructor(reason: 'configuration' | SourceSyncSkipReason);
40
+ }
41
+ /** One MIME part as this package reads it. Internal: never persisted and not exported from the package root. */
42
+ export interface MimePart {
43
+ /** The media type in lower case. */
44
+ readonly mimeType: string;
45
+ /** Gmail's filename for the part; empty when there is none. */
46
+ readonly filename: string;
47
+ readonly headers: readonly GmailHeaderInput[];
48
+ /** Gmail's decoded byte count of the body. */
49
+ readonly size: number;
50
+ /** The base64url body, kept only for a text/plain or text/html part outside every attachment; otherwise empty. */
51
+ readonly data: string;
52
+ /** Whether the body sits behind an attachment id. */
53
+ readonly external: boolean;
54
+ /** Whether the part is listed as an attachment instead of read. */
55
+ readonly attachment: boolean;
56
+ readonly parts: readonly MimePart[];
57
+ }
58
+ /** One message's protocol fields. Internal. */
59
+ export interface MimeMessage {
60
+ readonly id: string;
61
+ /** Gmail's `internalDate`, epoch milliseconds. */
62
+ readonly receivedAt: number;
63
+ /** Label ids, unique and sorted. */
64
+ readonly labels: readonly string[];
65
+ readonly payload: MimePart;
66
+ }
67
+ /** One thread's protocol fields. Internal. */
68
+ export interface MimeThread {
69
+ readonly id: string;
70
+ /** The thread's history value, decimal digits. */
71
+ readonly historyId: string;
72
+ readonly messages: readonly MimeMessage[];
73
+ }
74
+ /** An attachment as listed: its contents are never read. Internal. */
75
+ export interface MimeAttachment {
76
+ readonly filename: string;
77
+ readonly mediaType: string;
78
+ readonly size: number;
79
+ }
80
+ /** A message body before sanitization, with its attachment list. Internal. */
81
+ export interface MimeBody {
82
+ readonly text: string;
83
+ readonly attachments: readonly MimeAttachment[];
84
+ /** Parts whose media type is not read, and alternatives that offered no readable branch. */
85
+ readonly unsupportedParts: number;
86
+ }
87
+ /** The running counts of one `map` call, checked against its bounds. Internal. */
88
+ export interface MimeBudget {
89
+ readonly bounds: GmailMappingBounds;
90
+ rawBytes: number;
91
+ decodedBytes: number;
92
+ parts: number;
93
+ }
94
+ /** Whether a value is an accepted Gmail message or thread id: 1 to 64 hexadecimal characters. */
95
+ export declare const gmailId: (value: unknown) => value is string;
96
+ /** Throws `SourceSyncFault('cancelled')` once the signal is aborted. */
97
+ export declare function mappingActive(signal?: AbortSignal): void;
98
+ /**
99
+ * Validates and freezes a mapper's bounds.
100
+ *
101
+ * @throws {GmailMappingFault} `configuration` when a bound is not a positive safe integer or exceeds its ceiling, or
102
+ * when the message or thread character cap exceeds the input cap.
103
+ */
104
+ export declare function mappingBounds(input: GmailMappingBounds): GmailMappingBounds;
105
+ /**
106
+ * Validate the whole structure before decoding any selected message. Copies only the fields this package reads: ids,
107
+ * internal dates, labels and each payload's MIME tree. Every message's tree, excluded messages included, counts against
108
+ * the byte, depth and part bounds. `raw`, `snippet` and unknown fields are never read.
109
+ *
110
+ * @param value The parsed `threads.get` response.
111
+ * @param sourceId The thread id the caller asked for; any other id is an invalid response.
112
+ * @param budget The call's running counts.
113
+ * @param signal Checked before each part.
114
+ * @throws {SourceSyncFault} `invalid_response` for an invalid shape, id, history value, date, label, media type or a
115
+ * repeated message id; `cancelled` once the signal is aborted.
116
+ * @throws {GmailMappingFault} `response_too_large` or `structure_limit` when a bound is exceeded.
117
+ */
118
+ export declare function parseMimeThread(value: unknown, sourceId: string, budget: MimeBudget, signal?: AbortSignal): MimeThread;
119
+ /**
120
+ * Decoding is followed by sanitation even when the input looked like ASCII. Decodes the RFC 2047 encoded words (B and
121
+ * Q) of one header value with a fatal decoder for each declared charset; whitespace between adjacent encoded words is
122
+ * dropped, as RFC 2047 requires.
123
+ *
124
+ * @throws {GmailMappingFault} `invalid_encoding` for a malformed or overlong word, invalid bytes or a value that still
125
+ * holds an encoded-word opener after decoding; `unsupported_charset` for a charset the runtime does not decode;
126
+ * `response_too_large` above the character or decoded-byte bound.
127
+ */
128
+ export declare function decodeMimeWords(input: string, budget: MimeBudget): string;
129
+ /** A part's Subject, Date, From, To and Cc, decoded; Bcc and every other header are never decoded or returned. */
130
+ export declare function decodedHeaders(part: MimePart, budget: MimeBudget): readonly GmailHeaderInput[];
131
+ /**
132
+ * Select before decoding, and never interpret Content-Transfer-Encoding a second time: Gmail's `data` already holds the
133
+ * part's bytes. Lists the message's attachments and builds its body text. Within `multipart/alternative` the branch
134
+ * with eligible plain text wins over HTML; other multipart containers join their text children in MIME order. HTML
135
+ * becomes inert text through `HtmlLoader` given an in-memory Buffer. Other media types are counted, not read.
136
+ *
137
+ * @throws {GmailMappingFault} `invalid_encoding`, `unsupported_charset` or `response_too_large` for the message.
138
+ * @throws {SourceSyncFault} `cancelled` once the signal is aborted.
139
+ */
140
+ export declare function mimeBody(root: MimePart, budget: MimeBudget, signal?: AbortSignal): Promise<MimeBody>;
141
+ //# sourceMappingURL=mime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mime.d.ts","sourceRoot":"","sources":["../src/mime.ts"],"names":[],"mappings":"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"}