@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.
@@ -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 api = async (endpoint, options = {}) => {
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/_adapter_entry_6a803a31-b62d-4320-9c3a-20765e86b853.ts
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="b293c3728278acddde96468b09dc14b7786eb02e404fcb1cb482363b3596d3d6";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});}})();
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