@jbctechsolutions/mcp-outlook-mac 1.0.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/LICENSE +21 -0
- package/README.md +358 -0
- package/dist/applescript/account-repository.d.ts +29 -0
- package/dist/applescript/account-repository.d.ts.map +1 -0
- package/dist/applescript/account-repository.js +34 -0
- package/dist/applescript/account-repository.js.map +1 -0
- package/dist/applescript/account-scripts.d.ts +22 -0
- package/dist/applescript/account-scripts.d.ts.map +1 -0
- package/dist/applescript/account-scripts.js +176 -0
- package/dist/applescript/account-scripts.js.map +1 -0
- package/dist/applescript/calendar-manager.d.ts +45 -0
- package/dist/applescript/calendar-manager.d.ts.map +1 -0
- package/dist/applescript/calendar-manager.js +88 -0
- package/dist/applescript/calendar-manager.js.map +1 -0
- package/dist/applescript/calendar-writer.d.ts +38 -0
- package/dist/applescript/calendar-writer.d.ts.map +1 -0
- package/dist/applescript/calendar-writer.js +90 -0
- package/dist/applescript/calendar-writer.js.map +1 -0
- package/dist/applescript/content-readers.d.ts +93 -0
- package/dist/applescript/content-readers.d.ts.map +1 -0
- package/dist/applescript/content-readers.js +299 -0
- package/dist/applescript/content-readers.js.map +1 -0
- package/dist/applescript/executor.d.ts +62 -0
- package/dist/applescript/executor.d.ts.map +1 -0
- package/dist/applescript/executor.js +164 -0
- package/dist/applescript/executor.js.map +1 -0
- package/dist/applescript/index.d.ts +16 -0
- package/dist/applescript/index.d.ts.map +1 -0
- package/dist/applescript/index.js +25 -0
- package/dist/applescript/index.js.map +1 -0
- package/dist/applescript/mail-sender.d.ts +30 -0
- package/dist/applescript/mail-sender.d.ts.map +1 -0
- package/dist/applescript/mail-sender.js +53 -0
- package/dist/applescript/mail-sender.js.map +1 -0
- package/dist/applescript/parser.d.ts +215 -0
- package/dist/applescript/parser.d.ts.map +1 -0
- package/dist/applescript/parser.js +431 -0
- package/dist/applescript/parser.js.map +1 -0
- package/dist/applescript/repository.d.ts +58 -0
- package/dist/applescript/repository.d.ts.map +1 -0
- package/dist/applescript/repository.js +417 -0
- package/dist/applescript/repository.js.map +1 -0
- package/dist/applescript/scripts.d.ts +242 -0
- package/dist/applescript/scripts.d.ts.map +1 -0
- package/dist/applescript/scripts.js +1300 -0
- package/dist/applescript/scripts.js.map +1 -0
- package/dist/approval/hash.d.ts +26 -0
- package/dist/approval/hash.d.ts.map +1 -0
- package/dist/approval/hash.js +28 -0
- package/dist/approval/hash.js.map +1 -0
- package/dist/approval/index.d.ts +9 -0
- package/dist/approval/index.d.ts.map +1 -0
- package/dist/approval/index.js +8 -0
- package/dist/approval/index.js.map +1 -0
- package/dist/approval/token-manager.d.ts +48 -0
- package/dist/approval/token-manager.d.ts.map +1 -0
- package/dist/approval/token-manager.js +100 -0
- package/dist/approval/token-manager.js.map +1 -0
- package/dist/approval/types.d.ts +40 -0
- package/dist/approval/types.d.ts.map +1 -0
- package/dist/approval/types.js +8 -0
- package/dist/approval/types.js.map +1 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/database/connection.d.ts +73 -0
- package/dist/database/connection.d.ts.map +1 -0
- package/dist/database/connection.js +126 -0
- package/dist/database/connection.js.map +1 -0
- package/dist/database/index.d.ts +7 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +7 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/queries.d.ts +89 -0
- package/dist/database/queries.d.ts.map +1 -0
- package/dist/database/queries.js +422 -0
- package/dist/database/queries.js.map +1 -0
- package/dist/database/repository.d.ts +188 -0
- package/dist/database/repository.d.ts.map +1 -0
- package/dist/database/repository.js +187 -0
- package/dist/database/repository.js.map +1 -0
- package/dist/graph/auth/config.d.ts +33 -0
- package/dist/graph/auth/config.d.ts.map +1 -0
- package/dist/graph/auth/config.js +53 -0
- package/dist/graph/auth/config.js.map +1 -0
- package/dist/graph/auth/device-code-flow.d.ts +51 -0
- package/dist/graph/auth/device-code-flow.d.ts.map +1 -0
- package/dist/graph/auth/device-code-flow.js +176 -0
- package/dist/graph/auth/device-code-flow.js.map +1 -0
- package/dist/graph/auth/index.d.ts +9 -0
- package/dist/graph/auth/index.d.ts.map +1 -0
- package/dist/graph/auth/index.js +9 -0
- package/dist/graph/auth/index.js.map +1 -0
- package/dist/graph/auth/token-cache.d.ts +43 -0
- package/dist/graph/auth/token-cache.d.ts.map +1 -0
- package/dist/graph/auth/token-cache.js +99 -0
- package/dist/graph/auth/token-cache.js.map +1 -0
- package/dist/graph/client/cache.d.ts +65 -0
- package/dist/graph/client/cache.d.ts.map +1 -0
- package/dist/graph/client/cache.js +109 -0
- package/dist/graph/client/cache.js.map +1 -0
- package/dist/graph/client/graph-client.d.ts +150 -0
- package/dist/graph/client/graph-client.d.ts.map +1 -0
- package/dist/graph/client/graph-client.js +538 -0
- package/dist/graph/client/graph-client.js.map +1 -0
- package/dist/graph/client/index.d.ts +8 -0
- package/dist/graph/client/index.d.ts.map +1 -0
- package/dist/graph/client/index.js +8 -0
- package/dist/graph/client/index.js.map +1 -0
- package/dist/graph/content-readers.d.ts +102 -0
- package/dist/graph/content-readers.d.ts.map +1 -0
- package/dist/graph/content-readers.js +327 -0
- package/dist/graph/content-readers.js.map +1 -0
- package/dist/graph/index.d.ts +14 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +19 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/mailbox-adapter.d.ts +25 -0
- package/dist/graph/mailbox-adapter.d.ts.map +1 -0
- package/dist/graph/mailbox-adapter.js +56 -0
- package/dist/graph/mailbox-adapter.js.map +1 -0
- package/dist/graph/mappers/contact-mapper.d.ts +10 -0
- package/dist/graph/mappers/contact-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/contact-mapper.js +19 -0
- package/dist/graph/mappers/contact-mapper.js.map +1 -0
- package/dist/graph/mappers/email-mapper.d.ts +10 -0
- package/dist/graph/mappers/email-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/email-mapper.js +43 -0
- package/dist/graph/mappers/email-mapper.js.map +1 -0
- package/dist/graph/mappers/event-mapper.d.ts +10 -0
- package/dist/graph/mappers/event-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/event-mapper.js +28 -0
- package/dist/graph/mappers/event-mapper.js.map +1 -0
- package/dist/graph/mappers/folder-mapper.d.ts +18 -0
- package/dist/graph/mappers/folder-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/folder-mapper.js +50 -0
- package/dist/graph/mappers/folder-mapper.js.map +1 -0
- package/dist/graph/mappers/index.d.ts +12 -0
- package/dist/graph/mappers/index.d.ts.map +1 -0
- package/dist/graph/mappers/index.js +12 -0
- package/dist/graph/mappers/index.js.map +1 -0
- package/dist/graph/mappers/task-mapper.d.ts +16 -0
- package/dist/graph/mappers/task-mapper.d.ts.map +1 -0
- package/dist/graph/mappers/task-mapper.js +26 -0
- package/dist/graph/mappers/task-mapper.js.map +1 -0
- package/dist/graph/mappers/utils.d.ts +75 -0
- package/dist/graph/mappers/utils.d.ts.map +1 -0
- package/dist/graph/mappers/utils.js +130 -0
- package/dist/graph/mappers/utils.js.map +1 -0
- package/dist/graph/repository.d.ts +112 -0
- package/dist/graph/repository.d.ts.map +1 -0
- package/dist/graph/repository.js +549 -0
- package/dist/graph/repository.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1821 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/html-stripper.d.ts +43 -0
- package/dist/parsers/html-stripper.d.ts.map +1 -0
- package/dist/parsers/html-stripper.js +175 -0
- package/dist/parsers/html-stripper.js.map +1 -0
- package/dist/parsers/index.d.ts +8 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +8 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/olk15.d.ts +99 -0
- package/dist/parsers/olk15.d.ts.map +1 -0
- package/dist/parsers/olk15.js +364 -0
- package/dist/parsers/olk15.js.map +1 -0
- package/dist/tools/calendar.d.ts +203 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +251 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/contacts.d.ts +89 -0
- package/dist/tools/contacts.d.ts.map +1 -0
- package/dist/tools/contacts.js +129 -0
- package/dist/tools/contacts.js.map +1 -0
- package/dist/tools/index.d.ts +12 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +18 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/mail.d.ts +83 -0
- package/dist/tools/mail.d.ts.map +1 -0
- package/dist/tools/mail.js +217 -0
- package/dist/tools/mail.js.map +1 -0
- package/dist/tools/mailbox-organization.d.ts +337 -0
- package/dist/tools/mailbox-organization.d.ts.map +1 -0
- package/dist/tools/mailbox-organization.js +525 -0
- package/dist/tools/mailbox-organization.js.map +1 -0
- package/dist/tools/notes.d.ts +70 -0
- package/dist/tools/notes.d.ts.map +1 -0
- package/dist/tools/notes.js +132 -0
- package/dist/tools/notes.js.map +1 -0
- package/dist/tools/tasks.d.ts +70 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +122 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/types/calendar.d.ts +56 -0
- package/dist/types/calendar.d.ts.map +1 -0
- package/dist/types/calendar.js +14 -0
- package/dist/types/calendar.js.map +1 -0
- package/dist/types/contacts.d.ts +92 -0
- package/dist/types/contacts.d.ts.map +1 -0
- package/dist/types/contacts.js +37 -0
- package/dist/types/contacts.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mail.d.ts +87 -0
- package/dist/types/mail.d.ts.map +1 -0
- package/dist/types/mail.js +32 -0
- package/dist/types/mail.js.map +1 -0
- package/dist/types/notes.d.ts +22 -0
- package/dist/types/notes.d.ts.map +1 -0
- package/dist/types/notes.js +5 -0
- package/dist/types/notes.js.map +1 -0
- package/dist/types/tasks.d.ts +27 -0
- package/dist/types/tasks.d.ts.map +1 -0
- package/dist/types/tasks.js +5 -0
- package/dist/types/tasks.js.map +1 -0
- package/dist/utils/dates.d.ts +62 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +90 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/errors.d.ts +198 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +281 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Microsoft Graph API repository implementation.
|
|
3
|
+
*
|
|
4
|
+
* Implements the IRepository interface using Microsoft Graph API
|
|
5
|
+
* for data access instead of AppleScript or SQLite.
|
|
6
|
+
*/
|
|
7
|
+
import type { IRepository, FolderRow, EmailRow, EventRow, ContactRow, TaskRow, NoteRow } from '../database/repository.js';
|
|
8
|
+
import { GraphClient } from './client/index.js';
|
|
9
|
+
import type { DeviceCodeCallback } from './auth/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Repository implementation using Microsoft Graph API.
|
|
12
|
+
*
|
|
13
|
+
* Provides read-only access to Outlook data via the Graph API.
|
|
14
|
+
*/
|
|
15
|
+
export declare class GraphRepository implements IRepository {
|
|
16
|
+
private readonly client;
|
|
17
|
+
private readonly idCache;
|
|
18
|
+
constructor(deviceCodeCallback?: DeviceCodeCallback);
|
|
19
|
+
listFolders(): FolderRow[];
|
|
20
|
+
listFoldersAsync(): Promise<FolderRow[]>;
|
|
21
|
+
getFolder(id: number): FolderRow | undefined;
|
|
22
|
+
getFolderAsync(id: number): Promise<FolderRow | undefined>;
|
|
23
|
+
listEmails(folderId: number, limit: number, offset: number): EmailRow[];
|
|
24
|
+
listEmailsAsync(folderId: number, limit: number, offset: number): Promise<EmailRow[]>;
|
|
25
|
+
private listEmailsWithGraphId;
|
|
26
|
+
listUnreadEmails(folderId: number, limit: number, offset: number): EmailRow[];
|
|
27
|
+
listUnreadEmailsAsync(folderId: number, limit: number, offset: number): Promise<EmailRow[]>;
|
|
28
|
+
private listUnreadEmailsWithGraphId;
|
|
29
|
+
searchEmails(query: string, limit: number): EmailRow[];
|
|
30
|
+
searchEmailsAsync(query: string, limit: number): Promise<EmailRow[]>;
|
|
31
|
+
searchEmailsInFolder(folderId: number, query: string, limit: number): EmailRow[];
|
|
32
|
+
searchEmailsInFolderAsync(folderId: number, query: string, limit: number): Promise<EmailRow[]>;
|
|
33
|
+
private searchEmailsInFolderWithGraphId;
|
|
34
|
+
getEmail(id: number): EmailRow | undefined;
|
|
35
|
+
getEmailAsync(id: number): Promise<EmailRow | undefined>;
|
|
36
|
+
getUnreadCount(): number;
|
|
37
|
+
getUnreadCountAsync(): Promise<number>;
|
|
38
|
+
getUnreadCountByFolder(folderId: number): number;
|
|
39
|
+
getUnreadCountByFolderAsync(folderId: number): Promise<number>;
|
|
40
|
+
listCalendars(): FolderRow[];
|
|
41
|
+
listCalendarsAsync(): Promise<FolderRow[]>;
|
|
42
|
+
listEvents(limit: number): EventRow[];
|
|
43
|
+
listEventsAsync(limit: number): Promise<EventRow[]>;
|
|
44
|
+
listEventsByFolder(folderId: number, limit: number): EventRow[];
|
|
45
|
+
listEventsByFolderAsync(folderId: number, limit: number): Promise<EventRow[]>;
|
|
46
|
+
listEventsByDateRange(startDate: number, endDate: number, limit: number): EventRow[];
|
|
47
|
+
listEventsByDateRangeAsync(startDate: number, endDate: number, limit: number): Promise<EventRow[]>;
|
|
48
|
+
getEvent(id: number): EventRow | undefined;
|
|
49
|
+
getEventAsync(id: number): Promise<EventRow | undefined>;
|
|
50
|
+
listContacts(limit: number, offset: number): ContactRow[];
|
|
51
|
+
listContactsAsync(limit: number, offset: number): Promise<ContactRow[]>;
|
|
52
|
+
searchContacts(query: string, limit: number): ContactRow[];
|
|
53
|
+
searchContactsAsync(query: string, limit: number): Promise<ContactRow[]>;
|
|
54
|
+
getContact(id: number): ContactRow | undefined;
|
|
55
|
+
getContactAsync(id: number): Promise<ContactRow | undefined>;
|
|
56
|
+
listTasks(limit: number, offset: number): TaskRow[];
|
|
57
|
+
listTasksAsync(limit: number, offset: number): Promise<TaskRow[]>;
|
|
58
|
+
listIncompleteTasks(limit: number, offset: number): TaskRow[];
|
|
59
|
+
listIncompleteTasksAsync(limit: number, offset: number): Promise<TaskRow[]>;
|
|
60
|
+
searchTasks(query: string, limit: number): TaskRow[];
|
|
61
|
+
searchTasksAsync(query: string, limit: number): Promise<TaskRow[]>;
|
|
62
|
+
getTask(id: number): TaskRow | undefined;
|
|
63
|
+
getTaskAsync(id: number): Promise<TaskRow | undefined>;
|
|
64
|
+
listNotes(limit: number, offset: number): NoteRow[];
|
|
65
|
+
listNotesAsync(limit: number, offset: number): Promise<NoteRow[]>;
|
|
66
|
+
getNote(id: number): NoteRow | undefined;
|
|
67
|
+
getNoteAsync(id: number): Promise<NoteRow | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* Gets the Graph client instance for direct access if needed.
|
|
70
|
+
*/
|
|
71
|
+
getClient(): GraphClient;
|
|
72
|
+
/**
|
|
73
|
+
* Gets the Graph string ID from a numeric ID.
|
|
74
|
+
*/
|
|
75
|
+
getGraphId(type: 'folder' | 'message' | 'event' | 'contact', numericId: number): string | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Gets task info from a numeric ID.
|
|
78
|
+
*/
|
|
79
|
+
getTaskInfo(numericId: number): {
|
|
80
|
+
taskListId: string;
|
|
81
|
+
taskId: string;
|
|
82
|
+
} | undefined;
|
|
83
|
+
moveEmail(_emailId: number, _destinationFolderId: number): void;
|
|
84
|
+
deleteEmail(_emailId: number): void;
|
|
85
|
+
archiveEmail(_emailId: number): void;
|
|
86
|
+
junkEmail(_emailId: number): void;
|
|
87
|
+
markEmailRead(_emailId: number, _isRead: boolean): void;
|
|
88
|
+
setEmailFlag(_emailId: number, _flagStatus: number): void;
|
|
89
|
+
setEmailCategories(_emailId: number, _categories: string[]): void;
|
|
90
|
+
createFolder(_name: string, _parentFolderId?: number): FolderRow;
|
|
91
|
+
deleteFolder(_folderId: number): void;
|
|
92
|
+
renameFolder(_folderId: number, _newName: string): void;
|
|
93
|
+
moveFolder(_folderId: number, _destinationParentId: number): void;
|
|
94
|
+
emptyFolder(_folderId: number): void;
|
|
95
|
+
moveEmailAsync(emailId: number, destinationFolderId: number): Promise<void>;
|
|
96
|
+
deleteEmailAsync(emailId: number): Promise<void>;
|
|
97
|
+
archiveEmailAsync(emailId: number): Promise<void>;
|
|
98
|
+
junkEmailAsync(emailId: number): Promise<void>;
|
|
99
|
+
markEmailReadAsync(emailId: number, isRead: boolean): Promise<void>;
|
|
100
|
+
setEmailFlagAsync(emailId: number, flagStatus: number): Promise<void>;
|
|
101
|
+
setEmailCategoriesAsync(emailId: number, categories: string[]): Promise<void>;
|
|
102
|
+
createFolderAsync(name: string, parentFolderId?: number): Promise<FolderRow>;
|
|
103
|
+
deleteFolderAsync(folderId: number): Promise<void>;
|
|
104
|
+
renameFolderAsync(folderId: number, newName: string): Promise<void>;
|
|
105
|
+
moveFolderAsync(folderId: number, destinationParentId: number): Promise<void>;
|
|
106
|
+
emptyFolderAsync(folderId: number): Promise<void>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Creates a Microsoft Graph API repository.
|
|
110
|
+
*/
|
|
111
|
+
export declare function createGraphRepository(deviceCodeCallback?: DeviceCodeCallback): GraphRepository;
|
|
112
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/graph/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Microsoft Graph API repository implementation.
|
|
3
|
+
*
|
|
4
|
+
* Implements the IRepository interface using Microsoft Graph API
|
|
5
|
+
* for data access instead of AppleScript or SQLite.
|
|
6
|
+
*/
|
|
7
|
+
import { GraphClient } from './client/index.js';
|
|
8
|
+
import { mapMailFolderToRow, mapCalendarToFolderRow, mapMessageToEmailRow, mapEventToEventRow, mapContactToContactRow, mapTaskToTaskRow, hashStringToNumber, } from './mappers/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* Repository implementation using Microsoft Graph API.
|
|
11
|
+
*
|
|
12
|
+
* Provides read-only access to Outlook data via the Graph API.
|
|
13
|
+
*/
|
|
14
|
+
export class GraphRepository {
|
|
15
|
+
client;
|
|
16
|
+
idCache = {
|
|
17
|
+
folders: new Map(),
|
|
18
|
+
messages: new Map(),
|
|
19
|
+
events: new Map(),
|
|
20
|
+
contacts: new Map(),
|
|
21
|
+
tasks: new Map(),
|
|
22
|
+
};
|
|
23
|
+
constructor(deviceCodeCallback) {
|
|
24
|
+
this.client = new GraphClient(deviceCodeCallback);
|
|
25
|
+
}
|
|
26
|
+
// ===========================================================================
|
|
27
|
+
// Folders
|
|
28
|
+
// ===========================================================================
|
|
29
|
+
listFolders() {
|
|
30
|
+
// Note: Graph API is async, but IRepository interface is sync
|
|
31
|
+
// We need to use a sync wrapper or change the interface
|
|
32
|
+
// For now, we'll throw and require the async version
|
|
33
|
+
throw new Error('Use listFoldersAsync() for Graph repository');
|
|
34
|
+
}
|
|
35
|
+
async listFoldersAsync() {
|
|
36
|
+
const folders = await this.client.listMailFolders();
|
|
37
|
+
// Update ID cache
|
|
38
|
+
for (const folder of folders) {
|
|
39
|
+
if (folder.id != null) {
|
|
40
|
+
const numericId = hashStringToNumber(folder.id);
|
|
41
|
+
this.idCache.folders.set(numericId, folder.id);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return folders.map(mapMailFolderToRow);
|
|
45
|
+
}
|
|
46
|
+
getFolder(id) {
|
|
47
|
+
throw new Error('Use getFolderAsync() for Graph repository');
|
|
48
|
+
}
|
|
49
|
+
async getFolderAsync(id) {
|
|
50
|
+
const graphId = this.idCache.folders.get(id);
|
|
51
|
+
if (graphId == null) {
|
|
52
|
+
// Try to find it by listing all folders
|
|
53
|
+
await this.listFoldersAsync();
|
|
54
|
+
const refreshedGraphId = this.idCache.folders.get(id);
|
|
55
|
+
if (refreshedGraphId == null) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const folder = await this.client.getMailFolder(refreshedGraphId);
|
|
59
|
+
return folder != null ? mapMailFolderToRow(folder) : undefined;
|
|
60
|
+
}
|
|
61
|
+
const folder = await this.client.getMailFolder(graphId);
|
|
62
|
+
return folder != null ? mapMailFolderToRow(folder) : undefined;
|
|
63
|
+
}
|
|
64
|
+
// ===========================================================================
|
|
65
|
+
// Emails
|
|
66
|
+
// ===========================================================================
|
|
67
|
+
listEmails(folderId, limit, offset) {
|
|
68
|
+
throw new Error('Use listEmailsAsync() for Graph repository');
|
|
69
|
+
}
|
|
70
|
+
async listEmailsAsync(folderId, limit, offset) {
|
|
71
|
+
const graphFolderId = this.idCache.folders.get(folderId);
|
|
72
|
+
if (graphFolderId == null) {
|
|
73
|
+
// Refresh folder cache
|
|
74
|
+
await this.listFoldersAsync();
|
|
75
|
+
const refreshedId = this.idCache.folders.get(folderId);
|
|
76
|
+
if (refreshedId == null) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
return this.listEmailsWithGraphId(refreshedId, limit, offset);
|
|
80
|
+
}
|
|
81
|
+
return this.listEmailsWithGraphId(graphFolderId, limit, offset);
|
|
82
|
+
}
|
|
83
|
+
async listEmailsWithGraphId(folderId, limit, offset) {
|
|
84
|
+
const messages = await this.client.listMessages(folderId, limit, offset);
|
|
85
|
+
// Update ID cache
|
|
86
|
+
for (const message of messages) {
|
|
87
|
+
if (message.id != null) {
|
|
88
|
+
const numericId = hashStringToNumber(message.id);
|
|
89
|
+
this.idCache.messages.set(numericId, message.id);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return messages.map((m) => mapMessageToEmailRow(m, folderId));
|
|
93
|
+
}
|
|
94
|
+
listUnreadEmails(folderId, limit, offset) {
|
|
95
|
+
throw new Error('Use listUnreadEmailsAsync() for Graph repository');
|
|
96
|
+
}
|
|
97
|
+
async listUnreadEmailsAsync(folderId, limit, offset) {
|
|
98
|
+
const graphFolderId = this.idCache.folders.get(folderId);
|
|
99
|
+
if (graphFolderId == null) {
|
|
100
|
+
await this.listFoldersAsync();
|
|
101
|
+
const refreshedId = this.idCache.folders.get(folderId);
|
|
102
|
+
if (refreshedId == null) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
return this.listUnreadEmailsWithGraphId(refreshedId, limit, offset);
|
|
106
|
+
}
|
|
107
|
+
return this.listUnreadEmailsWithGraphId(graphFolderId, limit, offset);
|
|
108
|
+
}
|
|
109
|
+
async listUnreadEmailsWithGraphId(folderId, limit, offset) {
|
|
110
|
+
const messages = await this.client.listUnreadMessages(folderId, limit, offset);
|
|
111
|
+
for (const message of messages) {
|
|
112
|
+
if (message.id != null) {
|
|
113
|
+
const numericId = hashStringToNumber(message.id);
|
|
114
|
+
this.idCache.messages.set(numericId, message.id);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return messages.map((m) => mapMessageToEmailRow(m, folderId));
|
|
118
|
+
}
|
|
119
|
+
searchEmails(query, limit) {
|
|
120
|
+
throw new Error('Use searchEmailsAsync() for Graph repository');
|
|
121
|
+
}
|
|
122
|
+
async searchEmailsAsync(query, limit) {
|
|
123
|
+
const messages = await this.client.searchMessages(query, limit);
|
|
124
|
+
for (const message of messages) {
|
|
125
|
+
if (message.id != null) {
|
|
126
|
+
const numericId = hashStringToNumber(message.id);
|
|
127
|
+
this.idCache.messages.set(numericId, message.id);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return messages.map((m) => mapMessageToEmailRow(m));
|
|
131
|
+
}
|
|
132
|
+
searchEmailsInFolder(folderId, query, limit) {
|
|
133
|
+
throw new Error('Use searchEmailsInFolderAsync() for Graph repository');
|
|
134
|
+
}
|
|
135
|
+
async searchEmailsInFolderAsync(folderId, query, limit) {
|
|
136
|
+
const graphFolderId = this.idCache.folders.get(folderId);
|
|
137
|
+
if (graphFolderId == null) {
|
|
138
|
+
await this.listFoldersAsync();
|
|
139
|
+
const refreshedId = this.idCache.folders.get(folderId);
|
|
140
|
+
if (refreshedId == null) {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
return this.searchEmailsInFolderWithGraphId(refreshedId, query, limit);
|
|
144
|
+
}
|
|
145
|
+
return this.searchEmailsInFolderWithGraphId(graphFolderId, query, limit);
|
|
146
|
+
}
|
|
147
|
+
async searchEmailsInFolderWithGraphId(folderId, query, limit) {
|
|
148
|
+
const messages = await this.client.searchMessagesInFolder(folderId, query, limit);
|
|
149
|
+
for (const message of messages) {
|
|
150
|
+
if (message.id != null) {
|
|
151
|
+
const numericId = hashStringToNumber(message.id);
|
|
152
|
+
this.idCache.messages.set(numericId, message.id);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return messages.map((m) => mapMessageToEmailRow(m, folderId));
|
|
156
|
+
}
|
|
157
|
+
getEmail(id) {
|
|
158
|
+
throw new Error('Use getEmailAsync() for Graph repository');
|
|
159
|
+
}
|
|
160
|
+
async getEmailAsync(id) {
|
|
161
|
+
const graphId = this.idCache.messages.get(id);
|
|
162
|
+
if (graphId == null) {
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
const message = await this.client.getMessage(graphId);
|
|
166
|
+
return message != null ? mapMessageToEmailRow(message) : undefined;
|
|
167
|
+
}
|
|
168
|
+
getUnreadCount() {
|
|
169
|
+
throw new Error('Use getUnreadCountAsync() for Graph repository');
|
|
170
|
+
}
|
|
171
|
+
async getUnreadCountAsync() {
|
|
172
|
+
const folders = await this.client.listMailFolders();
|
|
173
|
+
return folders.reduce((sum, f) => sum + (f.unreadItemCount ?? 0), 0);
|
|
174
|
+
}
|
|
175
|
+
getUnreadCountByFolder(folderId) {
|
|
176
|
+
throw new Error('Use getUnreadCountByFolderAsync() for Graph repository');
|
|
177
|
+
}
|
|
178
|
+
async getUnreadCountByFolderAsync(folderId) {
|
|
179
|
+
const graphId = this.idCache.folders.get(folderId);
|
|
180
|
+
if (graphId == null) {
|
|
181
|
+
await this.listFoldersAsync();
|
|
182
|
+
const refreshedId = this.idCache.folders.get(folderId);
|
|
183
|
+
if (refreshedId == null) {
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
const folder = await this.client.getMailFolder(refreshedId);
|
|
187
|
+
return folder?.unreadItemCount ?? 0;
|
|
188
|
+
}
|
|
189
|
+
const folder = await this.client.getMailFolder(graphId);
|
|
190
|
+
return folder?.unreadItemCount ?? 0;
|
|
191
|
+
}
|
|
192
|
+
// ===========================================================================
|
|
193
|
+
// Calendar
|
|
194
|
+
// ===========================================================================
|
|
195
|
+
listCalendars() {
|
|
196
|
+
throw new Error('Use listCalendarsAsync() for Graph repository');
|
|
197
|
+
}
|
|
198
|
+
async listCalendarsAsync() {
|
|
199
|
+
const calendars = await this.client.listCalendars();
|
|
200
|
+
for (const calendar of calendars) {
|
|
201
|
+
if (calendar.id != null) {
|
|
202
|
+
const numericId = hashStringToNumber(calendar.id);
|
|
203
|
+
this.idCache.folders.set(numericId, calendar.id);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return calendars.map(mapCalendarToFolderRow);
|
|
207
|
+
}
|
|
208
|
+
listEvents(limit) {
|
|
209
|
+
throw new Error('Use listEventsAsync() for Graph repository');
|
|
210
|
+
}
|
|
211
|
+
async listEventsAsync(limit) {
|
|
212
|
+
const events = await this.client.listEvents(limit);
|
|
213
|
+
for (const event of events) {
|
|
214
|
+
if (event.id != null) {
|
|
215
|
+
const numericId = hashStringToNumber(event.id);
|
|
216
|
+
this.idCache.events.set(numericId, event.id);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return events.map((e) => mapEventToEventRow(e));
|
|
220
|
+
}
|
|
221
|
+
listEventsByFolder(folderId, limit) {
|
|
222
|
+
throw new Error('Use listEventsByFolderAsync() for Graph repository');
|
|
223
|
+
}
|
|
224
|
+
async listEventsByFolderAsync(folderId, limit) {
|
|
225
|
+
const graphCalendarId = this.idCache.folders.get(folderId);
|
|
226
|
+
if (graphCalendarId == null) {
|
|
227
|
+
return this.listEventsAsync(limit);
|
|
228
|
+
}
|
|
229
|
+
const events = await this.client.listEvents(limit, graphCalendarId);
|
|
230
|
+
for (const event of events) {
|
|
231
|
+
if (event.id != null) {
|
|
232
|
+
const numericId = hashStringToNumber(event.id);
|
|
233
|
+
this.idCache.events.set(numericId, event.id);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return events.map((e) => mapEventToEventRow(e, graphCalendarId));
|
|
237
|
+
}
|
|
238
|
+
listEventsByDateRange(startDate, endDate, limit) {
|
|
239
|
+
throw new Error('Use listEventsByDateRangeAsync() for Graph repository');
|
|
240
|
+
}
|
|
241
|
+
async listEventsByDateRangeAsync(startDate, endDate, limit) {
|
|
242
|
+
const start = new Date(startDate * 1000);
|
|
243
|
+
const end = new Date(endDate * 1000);
|
|
244
|
+
const events = await this.client.listEvents(limit, undefined, start, end);
|
|
245
|
+
for (const event of events) {
|
|
246
|
+
if (event.id != null) {
|
|
247
|
+
const numericId = hashStringToNumber(event.id);
|
|
248
|
+
this.idCache.events.set(numericId, event.id);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return events.map((e) => mapEventToEventRow(e));
|
|
252
|
+
}
|
|
253
|
+
getEvent(id) {
|
|
254
|
+
throw new Error('Use getEventAsync() for Graph repository');
|
|
255
|
+
}
|
|
256
|
+
async getEventAsync(id) {
|
|
257
|
+
const graphId = this.idCache.events.get(id);
|
|
258
|
+
if (graphId == null) {
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
const event = await this.client.getEvent(graphId);
|
|
262
|
+
return event != null ? mapEventToEventRow(event) : undefined;
|
|
263
|
+
}
|
|
264
|
+
// ===========================================================================
|
|
265
|
+
// Contacts
|
|
266
|
+
// ===========================================================================
|
|
267
|
+
listContacts(limit, offset) {
|
|
268
|
+
throw new Error('Use listContactsAsync() for Graph repository');
|
|
269
|
+
}
|
|
270
|
+
async listContactsAsync(limit, offset) {
|
|
271
|
+
const contacts = await this.client.listContacts(limit, offset);
|
|
272
|
+
for (const contact of contacts) {
|
|
273
|
+
if (contact.id != null) {
|
|
274
|
+
const numericId = hashStringToNumber(contact.id);
|
|
275
|
+
this.idCache.contacts.set(numericId, contact.id);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return contacts.map(mapContactToContactRow);
|
|
279
|
+
}
|
|
280
|
+
searchContacts(query, limit) {
|
|
281
|
+
throw new Error('Use searchContactsAsync() for Graph repository');
|
|
282
|
+
}
|
|
283
|
+
async searchContactsAsync(query, limit) {
|
|
284
|
+
const contacts = await this.client.searchContacts(query, limit);
|
|
285
|
+
for (const contact of contacts) {
|
|
286
|
+
if (contact.id != null) {
|
|
287
|
+
const numericId = hashStringToNumber(contact.id);
|
|
288
|
+
this.idCache.contacts.set(numericId, contact.id);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return contacts.map(mapContactToContactRow);
|
|
292
|
+
}
|
|
293
|
+
getContact(id) {
|
|
294
|
+
throw new Error('Use getContactAsync() for Graph repository');
|
|
295
|
+
}
|
|
296
|
+
async getContactAsync(id) {
|
|
297
|
+
const graphId = this.idCache.contacts.get(id);
|
|
298
|
+
if (graphId == null) {
|
|
299
|
+
return undefined;
|
|
300
|
+
}
|
|
301
|
+
const contact = await this.client.getContact(graphId);
|
|
302
|
+
return contact != null ? mapContactToContactRow(contact) : undefined;
|
|
303
|
+
}
|
|
304
|
+
// ===========================================================================
|
|
305
|
+
// Tasks
|
|
306
|
+
// ===========================================================================
|
|
307
|
+
listTasks(limit, offset) {
|
|
308
|
+
throw new Error('Use listTasksAsync() for Graph repository');
|
|
309
|
+
}
|
|
310
|
+
async listTasksAsync(limit, offset) {
|
|
311
|
+
const tasks = await this.client.listAllTasks(limit, offset, true);
|
|
312
|
+
for (const task of tasks) {
|
|
313
|
+
if (task.id != null && task.taskListId != null) {
|
|
314
|
+
const numericId = hashStringToNumber(task.id);
|
|
315
|
+
this.idCache.tasks.set(numericId, { taskListId: task.taskListId, taskId: task.id });
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return tasks.map(mapTaskToTaskRow);
|
|
319
|
+
}
|
|
320
|
+
listIncompleteTasks(limit, offset) {
|
|
321
|
+
throw new Error('Use listIncompleteTasksAsync() for Graph repository');
|
|
322
|
+
}
|
|
323
|
+
async listIncompleteTasksAsync(limit, offset) {
|
|
324
|
+
const tasks = await this.client.listAllTasks(limit, offset, false);
|
|
325
|
+
for (const task of tasks) {
|
|
326
|
+
if (task.id != null && task.taskListId != null) {
|
|
327
|
+
const numericId = hashStringToNumber(task.id);
|
|
328
|
+
this.idCache.tasks.set(numericId, { taskListId: task.taskListId, taskId: task.id });
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return tasks.map(mapTaskToTaskRow);
|
|
332
|
+
}
|
|
333
|
+
searchTasks(query, limit) {
|
|
334
|
+
throw new Error('Use searchTasksAsync() for Graph repository');
|
|
335
|
+
}
|
|
336
|
+
async searchTasksAsync(query, limit) {
|
|
337
|
+
const tasks = await this.client.searchTasks(query, limit);
|
|
338
|
+
for (const task of tasks) {
|
|
339
|
+
if (task.id != null && task.taskListId != null) {
|
|
340
|
+
const numericId = hashStringToNumber(task.id);
|
|
341
|
+
this.idCache.tasks.set(numericId, { taskListId: task.taskListId, taskId: task.id });
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return tasks.map(mapTaskToTaskRow);
|
|
345
|
+
}
|
|
346
|
+
getTask(id) {
|
|
347
|
+
throw new Error('Use getTaskAsync() for Graph repository');
|
|
348
|
+
}
|
|
349
|
+
async getTaskAsync(id) {
|
|
350
|
+
const taskInfo = this.idCache.tasks.get(id);
|
|
351
|
+
if (taskInfo == null) {
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
const task = await this.client.getTask(taskInfo.taskListId, taskInfo.taskId);
|
|
355
|
+
if (task == null) {
|
|
356
|
+
return undefined;
|
|
357
|
+
}
|
|
358
|
+
return mapTaskToTaskRow({ ...task, taskListId: taskInfo.taskListId });
|
|
359
|
+
}
|
|
360
|
+
// ===========================================================================
|
|
361
|
+
// Notes (NOT SUPPORTED)
|
|
362
|
+
// ===========================================================================
|
|
363
|
+
listNotes(limit, offset) {
|
|
364
|
+
// Microsoft Graph does not have an API for Outlook Notes
|
|
365
|
+
return [];
|
|
366
|
+
}
|
|
367
|
+
async listNotesAsync(limit, offset) {
|
|
368
|
+
// Microsoft Graph does not have an API for Outlook Notes
|
|
369
|
+
return [];
|
|
370
|
+
}
|
|
371
|
+
getNote(id) {
|
|
372
|
+
// Microsoft Graph does not have an API for Outlook Notes
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
async getNoteAsync(id) {
|
|
376
|
+
// Microsoft Graph does not have an API for Outlook Notes
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
// ===========================================================================
|
|
380
|
+
// Utility Methods
|
|
381
|
+
// ===========================================================================
|
|
382
|
+
/**
|
|
383
|
+
* Gets the Graph client instance for direct access if needed.
|
|
384
|
+
*/
|
|
385
|
+
getClient() {
|
|
386
|
+
return this.client;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Gets the Graph string ID from a numeric ID.
|
|
390
|
+
*/
|
|
391
|
+
getGraphId(type, numericId) {
|
|
392
|
+
switch (type) {
|
|
393
|
+
case 'folder':
|
|
394
|
+
return this.idCache.folders.get(numericId);
|
|
395
|
+
case 'message':
|
|
396
|
+
return this.idCache.messages.get(numericId);
|
|
397
|
+
case 'event':
|
|
398
|
+
return this.idCache.events.get(numericId);
|
|
399
|
+
case 'contact':
|
|
400
|
+
return this.idCache.contacts.get(numericId);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Gets task info from a numeric ID.
|
|
405
|
+
*/
|
|
406
|
+
getTaskInfo(numericId) {
|
|
407
|
+
return this.idCache.tasks.get(numericId);
|
|
408
|
+
}
|
|
409
|
+
// ===========================================================================
|
|
410
|
+
// Write Operations (Async)
|
|
411
|
+
// ===========================================================================
|
|
412
|
+
// Sync versions throw — use async versions from index.ts handler
|
|
413
|
+
moveEmail(_emailId, _destinationFolderId) {
|
|
414
|
+
throw new Error('Use moveEmailAsync() for Graph repository');
|
|
415
|
+
}
|
|
416
|
+
deleteEmail(_emailId) {
|
|
417
|
+
throw new Error('Use deleteEmailAsync() for Graph repository');
|
|
418
|
+
}
|
|
419
|
+
archiveEmail(_emailId) {
|
|
420
|
+
throw new Error('Use archiveEmailAsync() for Graph repository');
|
|
421
|
+
}
|
|
422
|
+
junkEmail(_emailId) {
|
|
423
|
+
throw new Error('Use junkEmailAsync() for Graph repository');
|
|
424
|
+
}
|
|
425
|
+
markEmailRead(_emailId, _isRead) {
|
|
426
|
+
throw new Error('Use markEmailReadAsync() for Graph repository');
|
|
427
|
+
}
|
|
428
|
+
setEmailFlag(_emailId, _flagStatus) {
|
|
429
|
+
throw new Error('Use setEmailFlagAsync() for Graph repository');
|
|
430
|
+
}
|
|
431
|
+
setEmailCategories(_emailId, _categories) {
|
|
432
|
+
throw new Error('Use setEmailCategoriesAsync() for Graph repository');
|
|
433
|
+
}
|
|
434
|
+
createFolder(_name, _parentFolderId) {
|
|
435
|
+
throw new Error('Use createFolderAsync() for Graph repository');
|
|
436
|
+
}
|
|
437
|
+
deleteFolder(_folderId) {
|
|
438
|
+
throw new Error('Use deleteFolderAsync() for Graph repository');
|
|
439
|
+
}
|
|
440
|
+
renameFolder(_folderId, _newName) {
|
|
441
|
+
throw new Error('Use renameFolderAsync() for Graph repository');
|
|
442
|
+
}
|
|
443
|
+
moveFolder(_folderId, _destinationParentId) {
|
|
444
|
+
throw new Error('Use moveFolderAsync() for Graph repository');
|
|
445
|
+
}
|
|
446
|
+
emptyFolder(_folderId) {
|
|
447
|
+
throw new Error('Use emptyFolderAsync() for Graph repository');
|
|
448
|
+
}
|
|
449
|
+
// Async implementations
|
|
450
|
+
async moveEmailAsync(emailId, destinationFolderId) {
|
|
451
|
+
const graphMessageId = this.idCache.messages.get(emailId);
|
|
452
|
+
const graphFolderId = this.idCache.folders.get(destinationFolderId);
|
|
453
|
+
if (graphMessageId == null)
|
|
454
|
+
throw new Error(`Message ID ${emailId} not found in cache`);
|
|
455
|
+
if (graphFolderId == null)
|
|
456
|
+
throw new Error(`Folder ID ${destinationFolderId} not found in cache`);
|
|
457
|
+
await this.client.moveMessage(graphMessageId, graphFolderId);
|
|
458
|
+
}
|
|
459
|
+
async deleteEmailAsync(emailId) {
|
|
460
|
+
const graphId = this.idCache.messages.get(emailId);
|
|
461
|
+
if (graphId == null)
|
|
462
|
+
throw new Error(`Message ID ${emailId} not found in cache`);
|
|
463
|
+
await this.client.deleteMessage(graphId);
|
|
464
|
+
}
|
|
465
|
+
async archiveEmailAsync(emailId) {
|
|
466
|
+
const graphId = this.idCache.messages.get(emailId);
|
|
467
|
+
if (graphId == null)
|
|
468
|
+
throw new Error(`Message ID ${emailId} not found in cache`);
|
|
469
|
+
await this.client.archiveMessage(graphId);
|
|
470
|
+
}
|
|
471
|
+
async junkEmailAsync(emailId) {
|
|
472
|
+
const graphId = this.idCache.messages.get(emailId);
|
|
473
|
+
if (graphId == null)
|
|
474
|
+
throw new Error(`Message ID ${emailId} not found in cache`);
|
|
475
|
+
await this.client.junkMessage(graphId);
|
|
476
|
+
}
|
|
477
|
+
async markEmailReadAsync(emailId, isRead) {
|
|
478
|
+
const graphId = this.idCache.messages.get(emailId);
|
|
479
|
+
if (graphId == null)
|
|
480
|
+
throw new Error(`Message ID ${emailId} not found in cache`);
|
|
481
|
+
await this.client.updateMessage(graphId, { isRead });
|
|
482
|
+
}
|
|
483
|
+
async setEmailFlagAsync(emailId, flagStatus) {
|
|
484
|
+
const graphId = this.idCache.messages.get(emailId);
|
|
485
|
+
if (graphId == null)
|
|
486
|
+
throw new Error(`Message ID ${emailId} not found in cache`);
|
|
487
|
+
const flagStatusMap = {
|
|
488
|
+
0: 'notFlagged',
|
|
489
|
+
1: 'flagged',
|
|
490
|
+
2: 'complete',
|
|
491
|
+
};
|
|
492
|
+
await this.client.updateMessage(graphId, {
|
|
493
|
+
flag: { flagStatus: flagStatusMap[flagStatus] ?? 'notFlagged' },
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
async setEmailCategoriesAsync(emailId, categories) {
|
|
497
|
+
const graphId = this.idCache.messages.get(emailId);
|
|
498
|
+
if (graphId == null)
|
|
499
|
+
throw new Error(`Message ID ${emailId} not found in cache`);
|
|
500
|
+
await this.client.updateMessage(graphId, { categories });
|
|
501
|
+
}
|
|
502
|
+
async createFolderAsync(name, parentFolderId) {
|
|
503
|
+
const graphParentId = parentFolderId != null
|
|
504
|
+
? this.idCache.folders.get(parentFolderId)
|
|
505
|
+
: undefined;
|
|
506
|
+
const folder = await this.client.createMailFolder(name, graphParentId ?? undefined);
|
|
507
|
+
// Update cache with new folder
|
|
508
|
+
if (folder.id != null) {
|
|
509
|
+
const numericId = hashStringToNumber(folder.id);
|
|
510
|
+
this.idCache.folders.set(numericId, folder.id);
|
|
511
|
+
}
|
|
512
|
+
return mapMailFolderToRow(folder);
|
|
513
|
+
}
|
|
514
|
+
async deleteFolderAsync(folderId) {
|
|
515
|
+
const graphId = this.idCache.folders.get(folderId);
|
|
516
|
+
if (graphId == null)
|
|
517
|
+
throw new Error(`Folder ID ${folderId} not found in cache`);
|
|
518
|
+
await this.client.deleteMailFolder(graphId);
|
|
519
|
+
this.idCache.folders.delete(folderId);
|
|
520
|
+
}
|
|
521
|
+
async renameFolderAsync(folderId, newName) {
|
|
522
|
+
const graphId = this.idCache.folders.get(folderId);
|
|
523
|
+
if (graphId == null)
|
|
524
|
+
throw new Error(`Folder ID ${folderId} not found in cache`);
|
|
525
|
+
await this.client.renameMailFolder(graphId, newName);
|
|
526
|
+
}
|
|
527
|
+
async moveFolderAsync(folderId, destinationParentId) {
|
|
528
|
+
const graphFolderId = this.idCache.folders.get(folderId);
|
|
529
|
+
const graphParentId = this.idCache.folders.get(destinationParentId);
|
|
530
|
+
if (graphFolderId == null)
|
|
531
|
+
throw new Error(`Folder ID ${folderId} not found in cache`);
|
|
532
|
+
if (graphParentId == null)
|
|
533
|
+
throw new Error(`Parent folder ID ${destinationParentId} not found in cache`);
|
|
534
|
+
await this.client.moveMailFolder(graphFolderId, graphParentId);
|
|
535
|
+
}
|
|
536
|
+
async emptyFolderAsync(folderId) {
|
|
537
|
+
const graphId = this.idCache.folders.get(folderId);
|
|
538
|
+
if (graphId == null)
|
|
539
|
+
throw new Error(`Folder ID ${folderId} not found in cache`);
|
|
540
|
+
await this.client.emptyMailFolder(graphId);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Creates a Microsoft Graph API repository.
|
|
545
|
+
*/
|
|
546
|
+
export function createGraphRepository(deviceCodeCallback) {
|
|
547
|
+
return new GraphRepository(deviceCodeCallback);
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=repository.js.map
|