apple-mail-mcp 2.20.17 → 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 +124 -17
- 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;
|
package/package.json
CHANGED