@opentabs-dev/opentabs-plugin-outlook 0.0.81 → 0.0.82
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/adapter.iife.js +86 -9
- package/dist/adapter.iife.js.map +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/outlook-api.d.ts +1 -0
- package/dist/outlook-api.d.ts.map +1 -1
- package/dist/outlook-api.js +51 -13
- package/dist/outlook-api.js.map +1 -1
- package/dist/tools/download-attachment.d.ts +11 -0
- package/dist/tools/download-attachment.d.ts.map +1 -0
- package/dist/tools/download-attachment.js +67 -0
- package/dist/tools/download-attachment.js.map +1 -0
- package/dist/tools.json +54 -0
- package/package.json +1 -1
package/dist/adapter.iife.js
CHANGED
|
@@ -370,6 +370,11 @@
|
|
|
370
370
|
var OUTLOOK_API_BASE = "https://outlook.office.com/api/v2.0";
|
|
371
371
|
var MSAL_CLIENT_ID = "9199bf20-a13f-4107-85dc-02114787ef48";
|
|
372
372
|
var MSAL_CLIENT_ID_CONSUMER = "2821b473-fe24-4c86-ba16-62834d6e80c3";
|
|
373
|
+
var MAIL_SCOPES = ["mail.read", "mail.readwrite", "mail.send"];
|
|
374
|
+
var hasMailScope = (target) => {
|
|
375
|
+
const lower = target.toLowerCase();
|
|
376
|
+
return MAIL_SCOPES.some((scope) => lower.includes(scope));
|
|
377
|
+
};
|
|
373
378
|
var findMsalV2Token = (clientId, scopeMatch) => {
|
|
374
379
|
const tokenKeysRaw = getLocalStorage(`msal.2.token.keys.${clientId}`);
|
|
375
380
|
if (!tokenKeysRaw) return null;
|
|
@@ -391,6 +396,9 @@
|
|
|
391
396
|
if (!matches) continue;
|
|
392
397
|
const expiresOn = Number.parseInt(parsed.expiresOn, 10);
|
|
393
398
|
if (expiresOn && expiresOn * 1e3 < Date.now()) continue;
|
|
399
|
+
if (scopeMatch.includes("graph.microsoft.com") && !hasMailScope(target)) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
394
402
|
const apiBase = scopeMatch.includes("graph.microsoft.com") ? GRAPH_API_BASE : OUTLOOK_API_BASE;
|
|
395
403
|
return { token: parsed.secret, apiBase };
|
|
396
404
|
} catch {
|
|
@@ -466,9 +474,7 @@
|
|
|
466
474
|
}
|
|
467
475
|
return result;
|
|
468
476
|
};
|
|
469
|
-
var
|
|
470
|
-
const auth = getAuth();
|
|
471
|
-
if (!auth) throw ToolError.auth("Not authenticated \u2014 please sign in to Microsoft 365.");
|
|
477
|
+
var sendRequest = async (auth, endpoint, options) => {
|
|
472
478
|
const isOutlookApi = auth.apiBase === OUTLOOK_API_BASE;
|
|
473
479
|
const query = options.query ? { ...options.query } : void 0;
|
|
474
480
|
if (isOutlookApi && query) {
|
|
@@ -511,10 +517,7 @@
|
|
|
511
517
|
const retryMs = retryAfter ? Number.parseInt(retryAfter, 10) * 1e3 : void 0;
|
|
512
518
|
throw ToolError.rateLimited("Microsoft API rate limit exceeded.", retryMs);
|
|
513
519
|
}
|
|
514
|
-
if (response.status === 401 || response.status === 403)
|
|
515
|
-
clearAuthCache("outlook");
|
|
516
|
-
throw ToolError.auth("Authentication expired \u2014 please refresh the Outlook page.");
|
|
517
|
-
}
|
|
520
|
+
if (response.status === 401 || response.status === 403) return null;
|
|
518
521
|
if (response.status === 404) {
|
|
519
522
|
throw ToolError.notFound("The requested resource was not found.");
|
|
520
523
|
}
|
|
@@ -535,6 +538,19 @@
|
|
|
535
538
|
const json2 = await response.json();
|
|
536
539
|
return isOutlookApi ? normalizeKeys(json2) : json2;
|
|
537
540
|
};
|
|
541
|
+
var api = async (endpoint, options = {}) => {
|
|
542
|
+
let auth = getAuth();
|
|
543
|
+
if (!auth) throw ToolError.auth("Not authenticated \u2014 please sign in to Microsoft 365.");
|
|
544
|
+
const result = await sendRequest(auth, endpoint, options);
|
|
545
|
+
if (result !== null) return result;
|
|
546
|
+
clearAuthCache("outlook");
|
|
547
|
+
auth = getAuth();
|
|
548
|
+
if (!auth) throw ToolError.auth("Authentication expired \u2014 please refresh the Outlook page.");
|
|
549
|
+
const retry2 = await sendRequest(auth, endpoint, options);
|
|
550
|
+
if (retry2 !== null) return retry2;
|
|
551
|
+
clearAuthCache("outlook");
|
|
552
|
+
throw ToolError.auth("Authentication expired \u2014 please refresh the Outlook page.");
|
|
553
|
+
};
|
|
538
554
|
|
|
539
555
|
// node_modules/zod/v4/classic/external.js
|
|
540
556
|
var external_exports = {};
|
|
@@ -14396,6 +14412,66 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14396
14412
|
}
|
|
14397
14413
|
});
|
|
14398
14414
|
|
|
14415
|
+
// src/tools/download-attachment.ts
|
|
14416
|
+
function base64ToBytes(base643) {
|
|
14417
|
+
const binary = atob(base643);
|
|
14418
|
+
const bytes = new Uint8Array(binary.length);
|
|
14419
|
+
for (let i = 0; i < binary.length; i++) {
|
|
14420
|
+
bytes[i] = binary.charCodeAt(i);
|
|
14421
|
+
}
|
|
14422
|
+
return bytes;
|
|
14423
|
+
}
|
|
14424
|
+
function triggerBrowserDownload(bytes, filename, mimeType) {
|
|
14425
|
+
const blob = new Blob([bytes.buffer], { type: mimeType });
|
|
14426
|
+
const url2 = URL.createObjectURL(blob);
|
|
14427
|
+
const a = document.createElement("a");
|
|
14428
|
+
a.href = url2;
|
|
14429
|
+
a.download = filename;
|
|
14430
|
+
a.style.display = "none";
|
|
14431
|
+
document.body.appendChild(a);
|
|
14432
|
+
a.click();
|
|
14433
|
+
setTimeout(() => {
|
|
14434
|
+
document.body.removeChild(a);
|
|
14435
|
+
URL.revokeObjectURL(url2);
|
|
14436
|
+
}, 1e3);
|
|
14437
|
+
}
|
|
14438
|
+
var downloadAttachment = defineTool({
|
|
14439
|
+
name: "download_attachment",
|
|
14440
|
+
displayName: "Download Attachment",
|
|
14441
|
+
description: "Download an email attachment to the local filesystem (browser Downloads folder). Works with any file type \u2014 Excel, PDF, images, Word documents, etc. Returns the filename so you can locate it in the Downloads folder.",
|
|
14442
|
+
summary: "Save attachment to Downloads folder",
|
|
14443
|
+
icon: "download",
|
|
14444
|
+
group: "Messages",
|
|
14445
|
+
input: external_exports.object({
|
|
14446
|
+
message_id: external_exports.string().describe("The message ID"),
|
|
14447
|
+
attachment_id: external_exports.string().describe("The attachment ID (from list_attachments)")
|
|
14448
|
+
}),
|
|
14449
|
+
output: external_exports.object({
|
|
14450
|
+
name: external_exports.string().describe("Downloaded file name"),
|
|
14451
|
+
content_type: external_exports.string().describe("MIME type"),
|
|
14452
|
+
size: external_exports.number().describe("Size in bytes"),
|
|
14453
|
+
downloaded: external_exports.boolean().describe("Whether the download was triggered successfully")
|
|
14454
|
+
}),
|
|
14455
|
+
handle: async (params) => {
|
|
14456
|
+
const data = await api(
|
|
14457
|
+
`/me/messages/${params.message_id}/attachments/${params.attachment_id}`,
|
|
14458
|
+
{
|
|
14459
|
+
query: { $select: "id,name,contentType,size,isInline,contentBytes" }
|
|
14460
|
+
}
|
|
14461
|
+
);
|
|
14462
|
+
const name = data.name ?? "attachment";
|
|
14463
|
+
const contentType = data.contentType ?? "application/octet-stream";
|
|
14464
|
+
const size = data.size ?? 0;
|
|
14465
|
+
const contentBytes = data.contentBytes ?? "";
|
|
14466
|
+
if (!contentBytes) {
|
|
14467
|
+
return { name, content_type: contentType, size, downloaded: false };
|
|
14468
|
+
}
|
|
14469
|
+
const bytes = base64ToBytes(contentBytes);
|
|
14470
|
+
triggerBrowserDownload(bytes, name, contentType);
|
|
14471
|
+
return { name, content_type: contentType, size, downloaded: true };
|
|
14472
|
+
}
|
|
14473
|
+
});
|
|
14474
|
+
|
|
14399
14475
|
// src/tools/get-attachment-content.ts
|
|
14400
14476
|
var getAttachmentContent = defineTool({
|
|
14401
14477
|
name: "get_attachment_content",
|
|
@@ -14851,6 +14927,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14851
14927
|
deleteMessage,
|
|
14852
14928
|
listAttachments,
|
|
14853
14929
|
getAttachmentContent,
|
|
14930
|
+
downloadAttachment,
|
|
14854
14931
|
// Folders
|
|
14855
14932
|
listFolders
|
|
14856
14933
|
];
|
|
@@ -14861,7 +14938,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14861
14938
|
};
|
|
14862
14939
|
var src_default = new OutlookPlugin();
|
|
14863
14940
|
|
|
14864
|
-
// dist/
|
|
14941
|
+
// dist/_adapter_entry_d78e8034-60fa-407a-99d9-bb3c26746268.ts
|
|
14865
14942
|
if (!globalThis.__openTabs) {
|
|
14866
14943
|
globalThis.__openTabs = {};
|
|
14867
14944
|
} else {
|
|
@@ -15077,5 +15154,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15077
15154
|
};
|
|
15078
15155
|
delete src_default.onDeactivate;
|
|
15079
15156
|
}
|
|
15080
|
-
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["outlook"]){var a=o.adapters["outlook"];a.__adapterHash="
|
|
15157
|
+
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["outlook"]){var a=o.adapters["outlook"];a.__adapterHash="458ce072f700a122fbdb3c0d1e66e8fcafd0ce11b7934c7a74ac55594af01036";if(a.tools&&Array.isArray(a.tools)){for(var i=0;i<a.tools.length;i++){Object.freeze(a.tools[i]);}Object.freeze(a.tools);}Object.freeze(a);Object.defineProperty(o.adapters,"outlook",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
|
|
15081
15158
|
//# sourceMappingURL=adapter.iife.js.map
|