apple-mail-mcp 2.20.16 → 2.20.18
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/build/index.js +129 -28
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -65193,16 +65193,112 @@ function getHeader(headers, name2) {
|
|
|
65193
65193
|
if (!match) return null;
|
|
65194
65194
|
return match[1].replace(/\r?\n[ \t]+/g, " ").trim();
|
|
65195
65195
|
}
|
|
65196
|
+
function decodeBytes(bytes, charset) {
|
|
65197
|
+
try {
|
|
65198
|
+
return new TextDecoder(charset.trim().toLowerCase()).decode(bytes);
|
|
65199
|
+
} catch {
|
|
65200
|
+
return bytes.toString("utf8");
|
|
65201
|
+
}
|
|
65202
|
+
}
|
|
65203
|
+
function parseParams(value) {
|
|
65204
|
+
const pieces = [];
|
|
65205
|
+
let current = "";
|
|
65206
|
+
let quoted = false;
|
|
65207
|
+
for (let i = 0; i < value.length; i++) {
|
|
65208
|
+
const ch = value[i];
|
|
65209
|
+
if (ch === "\\" && quoted && i + 1 < value.length) {
|
|
65210
|
+
current += ch + value[++i];
|
|
65211
|
+
continue;
|
|
65212
|
+
}
|
|
65213
|
+
if (ch === '"') quoted = !quoted;
|
|
65214
|
+
if (ch === ";" && !quoted) {
|
|
65215
|
+
pieces.push(current);
|
|
65216
|
+
current = "";
|
|
65217
|
+
} else {
|
|
65218
|
+
current += ch;
|
|
65219
|
+
}
|
|
65220
|
+
}
|
|
65221
|
+
pieces.push(current);
|
|
65222
|
+
const params = /* @__PURE__ */ new Map();
|
|
65223
|
+
for (const piece of pieces.slice(1)) {
|
|
65224
|
+
const eq = piece.indexOf("=");
|
|
65225
|
+
if (eq < 0) continue;
|
|
65226
|
+
let val = piece.slice(eq + 1).trim();
|
|
65227
|
+
if (val.length >= 2 && val.startsWith('"') && val.endsWith('"')) {
|
|
65228
|
+
val = val.slice(1, -1).replace(/\\(.)/g, "$1");
|
|
65229
|
+
}
|
|
65230
|
+
params.set(piece.slice(0, eq).trim().toLowerCase(), val);
|
|
65231
|
+
}
|
|
65232
|
+
return params;
|
|
65233
|
+
}
|
|
65234
|
+
function decodeEncodedWords(text) {
|
|
65235
|
+
return text.replace(/(\?=)\s+(?==\?)/g, "$1").replace(
|
|
65236
|
+
/=\?([^?\s]+)\?([bq])\?([^?]*)\?=/gi,
|
|
65237
|
+
(_all, charset, kind, body) => {
|
|
65238
|
+
const bytes = kind.toLowerCase() === "b" ? Buffer.from(body, "base64") : Buffer.from(
|
|
65239
|
+
body.replace(/_/g, " ").replace(
|
|
65240
|
+
/=([0-9a-f]{2})/gi,
|
|
65241
|
+
(_m, hex) => String.fromCharCode(parseInt(hex, 16))
|
|
65242
|
+
),
|
|
65243
|
+
"latin1"
|
|
65244
|
+
);
|
|
65245
|
+
return decodeBytes(bytes, charset.split("*")[0]);
|
|
65246
|
+
}
|
|
65247
|
+
);
|
|
65248
|
+
}
|
|
65249
|
+
function decodeExtendedValue(segments) {
|
|
65250
|
+
let charset = "utf-8";
|
|
65251
|
+
const chunks = [];
|
|
65252
|
+
segments.forEach((segment, index) => {
|
|
65253
|
+
let value = segment.value;
|
|
65254
|
+
if (!segment.encoded) {
|
|
65255
|
+
chunks.push(Buffer.from(value, "utf8"));
|
|
65256
|
+
return;
|
|
65257
|
+
}
|
|
65258
|
+
if (index === 0) {
|
|
65259
|
+
const head = value.match(/^([^']*)'[^']*'([\s\S]*)$/);
|
|
65260
|
+
if (head) {
|
|
65261
|
+
charset = head[1] || charset;
|
|
65262
|
+
value = head[2];
|
|
65263
|
+
}
|
|
65264
|
+
}
|
|
65265
|
+
chunks.push(
|
|
65266
|
+
Buffer.from(
|
|
65267
|
+
value.replace(
|
|
65268
|
+
/%([0-9a-f]{2})/gi,
|
|
65269
|
+
(_m, hex) => String.fromCharCode(parseInt(hex, 16))
|
|
65270
|
+
),
|
|
65271
|
+
"latin1"
|
|
65272
|
+
)
|
|
65273
|
+
);
|
|
65274
|
+
});
|
|
65275
|
+
return decodeBytes(Buffer.concat(chunks), charset);
|
|
65276
|
+
}
|
|
65277
|
+
function paramValue(params, name2) {
|
|
65278
|
+
const extended = params.get(`${name2}*`);
|
|
65279
|
+
if (extended !== void 0) return decodeExtendedValue([{ value: extended, encoded: true }]);
|
|
65280
|
+
const segments = [];
|
|
65281
|
+
for (let i = 0; ; i++) {
|
|
65282
|
+
const encoded = params.get(`${name2}*${i}*`);
|
|
65283
|
+
const plain = params.get(`${name2}*${i}`);
|
|
65284
|
+
if (encoded !== void 0) segments.push({ value: encoded, encoded: true });
|
|
65285
|
+
else if (plain !== void 0) segments.push({ value: plain, encoded: false });
|
|
65286
|
+
else break;
|
|
65287
|
+
}
|
|
65288
|
+
if (segments.length > 0) return decodeExtendedValue(segments);
|
|
65289
|
+
const value = params.get(name2);
|
|
65290
|
+
return value === void 0 ? null : decodeEncodedWords(value);
|
|
65291
|
+
}
|
|
65196
65292
|
function extractFilename(headers) {
|
|
65197
65293
|
const dispHeader = getHeader(headers, "Content-Disposition");
|
|
65198
65294
|
if (dispHeader) {
|
|
65199
|
-
const
|
|
65200
|
-
if (
|
|
65295
|
+
const filename = paramValue(parseParams(dispHeader), "filename")?.trim();
|
|
65296
|
+
if (filename) return filename;
|
|
65201
65297
|
}
|
|
65202
65298
|
const ctHeader = getHeader(headers, "Content-Type");
|
|
65203
65299
|
if (ctHeader) {
|
|
65204
|
-
const
|
|
65205
|
-
if (
|
|
65300
|
+
const name2 = paramValue(parseParams(ctHeader), "name")?.trim();
|
|
65301
|
+
if (name2) return name2;
|
|
65206
65302
|
}
|
|
65207
65303
|
return null;
|
|
65208
65304
|
}
|
|
@@ -65217,23 +65313,33 @@ function extractContentId(headers) {
|
|
|
65217
65313
|
const id = raw.replace(/^<+/, "").replace(/>+$/, "").trim().toLowerCase();
|
|
65218
65314
|
return id || null;
|
|
65219
65315
|
}
|
|
65220
|
-
function isEmbeddedResource(headers,
|
|
65316
|
+
function isEmbeddedResource(headers, referenced) {
|
|
65221
65317
|
if (!isInlineDisposition(headers)) return false;
|
|
65222
65318
|
const cid = extractContentId(headers);
|
|
65223
65319
|
if (!cid) return false;
|
|
65224
|
-
|
|
65225
|
-
return htmlBodies.some((html) => html.includes(needle));
|
|
65320
|
+
return referenced().has(cid);
|
|
65226
65321
|
}
|
|
65227
|
-
function
|
|
65228
|
-
const
|
|
65322
|
+
function cidReferences(html) {
|
|
65323
|
+
const refs = /* @__PURE__ */ new Set();
|
|
65324
|
+
for (const match of html.matchAll(/cid:([^\s"'<>()]+)/gi)) {
|
|
65325
|
+
let ref = match[1];
|
|
65326
|
+
try {
|
|
65327
|
+
ref = decodeURIComponent(ref);
|
|
65328
|
+
} catch {
|
|
65329
|
+
}
|
|
65330
|
+
refs.add(ref.trim().toLowerCase());
|
|
65331
|
+
}
|
|
65332
|
+
return refs;
|
|
65333
|
+
}
|
|
65334
|
+
function collectCidReferences(parts) {
|
|
65335
|
+
const refs = /* @__PURE__ */ new Set();
|
|
65229
65336
|
for (const part of parts) {
|
|
65230
65337
|
if (extractMimeType(part.headers) !== "text/html") continue;
|
|
65231
65338
|
const encoding = getHeader(part.headers, "Content-Transfer-Encoding");
|
|
65232
|
-
|
|
65233
|
-
|
|
65234
|
-
);
|
|
65339
|
+
const html = decodePartText(decodeBody(part.body, encoding), extractCharset(part.headers));
|
|
65340
|
+
for (const ref of cidReferences(html)) refs.add(ref);
|
|
65235
65341
|
}
|
|
65236
|
-
return
|
|
65342
|
+
return refs;
|
|
65237
65343
|
}
|
|
65238
65344
|
function extractSize(headers) {
|
|
65239
65345
|
const dispHeader = getHeader(headers, "Content-Disposition");
|
|
@@ -65340,12 +65446,13 @@ function parseMimeAttachments(source) {
|
|
|
65340
65446
|
const boundary = extractBoundary(source);
|
|
65341
65447
|
if (!boundary) return [];
|
|
65342
65448
|
const parts = walkLeafParts(source, boundary);
|
|
65343
|
-
|
|
65449
|
+
let refs;
|
|
65450
|
+
const referenced = () => refs ??= collectCidReferences(parts);
|
|
65344
65451
|
const attachments = [];
|
|
65345
65452
|
for (const part of parts) {
|
|
65346
65453
|
const filename = extractFilename(part.headers);
|
|
65347
65454
|
if (!filename) continue;
|
|
65348
|
-
if (isEmbeddedResource(part.headers,
|
|
65455
|
+
if (isEmbeddedResource(part.headers, referenced)) continue;
|
|
65349
65456
|
const encoding = getHeader(part.headers, "Content-Transfer-Encoding");
|
|
65350
65457
|
attachments.push({
|
|
65351
65458
|
name: filename,
|
|
@@ -65432,7 +65539,7 @@ var init_mimeParse = __esm({
|
|
|
65432
65539
|
});
|
|
65433
65540
|
|
|
65434
65541
|
// src/utils/headers.ts
|
|
65435
|
-
function
|
|
65542
|
+
function decodeEncodedWords2(value) {
|
|
65436
65543
|
if (!value.includes("=?")) return value;
|
|
65437
65544
|
const joined = value.replace(/(\?=)\s+(=\?)/g, "$1$2");
|
|
65438
65545
|
return joined.replace(
|
|
@@ -65522,7 +65629,7 @@ function parseHeaderBlock(input) {
|
|
|
65522
65629
|
const all = (name2) => headers.filter((h) => h.name.toLowerCase() === name2.toLowerCase()).map((h) => h.value);
|
|
65523
65630
|
const decoded = (name2) => {
|
|
65524
65631
|
const v = first(name2);
|
|
65525
|
-
return v === void 0 ? void 0 :
|
|
65632
|
+
return v === void 0 ? void 0 : decodeEncodedWords2(v);
|
|
65526
65633
|
};
|
|
65527
65634
|
const dateHeader = first("Date") || void 0;
|
|
65528
65635
|
let date3;
|
|
@@ -83437,16 +83544,10 @@ function buildMessageRowLoop(opts) {
|
|
|
83437
83544
|
-- outside date range; skip
|
|
83438
83545
|
else` : "";
|
|
83439
83546
|
const dateClose = dateFilter ? `end if` : "";
|
|
83440
|
-
const attBulk = withAttachments ? `
|
|
83441
|
-
set _atts to mail attachments of _msgs` : "";
|
|
83442
83547
|
const attRow = withAttachments ? `
|
|
83443
83548
|
set msgHasAtt to "false"
|
|
83444
83549
|
try
|
|
83445
|
-
if
|
|
83446
|
-
if (count of (item _i of _atts)) > 0 then set msgHasAtt to "true"
|
|
83447
|
-
else
|
|
83448
|
-
if (count of mail attachments of (item _i of _msgs)) > 0 then set msgHasAtt to "true"
|
|
83449
|
-
end if
|
|
83550
|
+
if (count of mail attachments of (item _i of _msgs)) > 0 then set msgHasAtt to "true"
|
|
83450
83551
|
end try` : "";
|
|
83451
83552
|
const attField = withAttachments ? ` & "${FIELD_SEP}" & msgHasAtt` : "";
|
|
83452
83553
|
return `
|
|
@@ -83459,7 +83560,7 @@ function buildMessageRowLoop(opts) {
|
|
|
83459
83560
|
set _dates to date received of _msgs
|
|
83460
83561
|
set _reads to read status of _msgs
|
|
83461
83562
|
set _flags to flagged status of _msgs
|
|
83462
|
-
set _flagColors to flag index of _msgs
|
|
83563
|
+
set _flagColors to flag index of _msgs
|
|
83463
83564
|
on error
|
|
83464
83565
|
set _bulkOK to false
|
|
83465
83566
|
end try
|
|
@@ -84821,7 +84922,7 @@ ${indent}end try${this.sanitizeFragment("_uacct", indent)}${this.sanitizeFragmen
|
|
|
84821
84922
|
ignoring case
|
|
84822
84923
|
if _wantNames contains (name of mb) then
|
|
84823
84924
|
try
|
|
84824
|
-
${buildMessageRowLoop({ collection: `messages of mb ${searchCondition}`, limit, dedup: true, dateFilter, trailing: ` & "${FIELD_SEP}" & mbName` })}
|
|
84925
|
+
${buildMessageRowLoop({ collection: `messages of mb ${searchCondition}`, limit, dedup: true, dateFilter, withAttachments: true, trailing: ` & "${FIELD_SEP}" & mbName` })}
|
|
84825
84926
|
on error _errMsg number _errNum
|
|
84826
84927
|
set _timedOut to true
|
|
84827
84928
|
set _notSearched to _notSearched & mbName & "${DIAG_ITEM_SEP}"
|
|
@@ -84843,7 +84944,7 @@ ${indent}end try${this.sanitizeFragment("_uacct", indent)}${this.sanitizeFragmen
|
|
|
84843
84944
|
set _notSearched to "${escapeForAppleScript(targetMailbox)}${DIAG_ITEM_SEP}"
|
|
84844
84945
|
else
|
|
84845
84946
|
try
|
|
84846
|
-
${buildMessageRowLoop({ collection: `messages of theMailbox ${searchCondition}`, limit, dateFilter })}
|
|
84947
|
+
${buildMessageRowLoop({ collection: `messages of theMailbox ${searchCondition}`, limit, dateFilter, withAttachments: true })}
|
|
84847
84948
|
on error _errMsg number _errNum
|
|
84848
84949
|
set _timedOut to true
|
|
84849
84950
|
set _notSearched to "${escapeForAppleScript(targetMailbox)}${DIAG_ITEM_SEP}"
|
|
@@ -84881,7 +84982,7 @@ ${indent}end try${this.sanitizeFragment("_uacct", indent)}${this.sanitizeFragmen
|
|
|
84881
84982
|
set _skipped to _skipped & mbName & " (" & (mbCount as string) & ")${DIAG_ITEM_SEP}"
|
|
84882
84983
|
else
|
|
84883
84984
|
try
|
|
84884
|
-
${buildMessageRowLoop({ collection: `messages of mb ${searchCondition}`, limit, dedup: true, dateFilter, trailing: ` & "${FIELD_SEP}" & mbName` })}
|
|
84985
|
+
${buildMessageRowLoop({ collection: `messages of mb ${searchCondition}`, limit, dedup: true, dateFilter, withAttachments: true, trailing: ` & "${FIELD_SEP}" & mbName` })}
|
|
84885
84986
|
on error _errMsg number _errNum
|
|
84886
84987
|
set _timedOut to true
|
|
84887
84988
|
set _notSearched to _notSearched & mbName & "${DIAG_ITEM_SEP}"
|
package/package.json
CHANGED