microsoft-graph-client 1.0.1

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.
Files changed (117) hide show
  1. package/dist/api/base.d.ts +10 -0
  2. package/dist/api/base.d.ts.map +1 -0
  3. package/dist/api/base.js +11 -0
  4. package/dist/api/base.js.map +1 -0
  5. package/dist/api/calendar.d.ts +24 -0
  6. package/dist/api/calendar.d.ts.map +1 -0
  7. package/dist/api/calendar.js +117 -0
  8. package/dist/api/calendar.js.map +1 -0
  9. package/dist/api/chats.d.ts +20 -0
  10. package/dist/api/chats.d.ts.map +1 -0
  11. package/dist/api/chats.js +71 -0
  12. package/dist/api/chats.js.map +1 -0
  13. package/dist/api/files.d.ts +24 -0
  14. package/dist/api/files.d.ts.map +1 -0
  15. package/dist/api/files.js +77 -0
  16. package/dist/api/files.js.map +1 -0
  17. package/dist/api/index.d.ts +9 -0
  18. package/dist/api/index.d.ts.map +1 -0
  19. package/dist/api/index.js +9 -0
  20. package/dist/api/index.js.map +1 -0
  21. package/dist/api/mail.d.ts +16 -0
  22. package/dist/api/mail.d.ts.map +1 -0
  23. package/dist/api/mail.js +74 -0
  24. package/dist/api/mail.js.map +1 -0
  25. package/dist/api/messages.d.ts +36 -0
  26. package/dist/api/messages.d.ts.map +1 -0
  27. package/dist/api/messages.js +227 -0
  28. package/dist/api/messages.js.map +1 -0
  29. package/dist/api/transcripts.d.ts +20 -0
  30. package/dist/api/transcripts.d.ts.map +1 -0
  31. package/dist/api/transcripts.js +53 -0
  32. package/dist/api/transcripts.js.map +1 -0
  33. package/dist/api/users.d.ts +25 -0
  34. package/dist/api/users.d.ts.map +1 -0
  35. package/dist/api/users.js +39 -0
  36. package/dist/api/users.js.map +1 -0
  37. package/dist/auth/authenticator.d.ts +48 -0
  38. package/dist/auth/authenticator.d.ts.map +1 -0
  39. package/dist/auth/authenticator.js +159 -0
  40. package/dist/auth/authenticator.js.map +1 -0
  41. package/dist/auth/index.d.ts +2 -0
  42. package/dist/auth/index.d.ts.map +1 -0
  43. package/dist/auth/index.js +2 -0
  44. package/dist/auth/index.js.map +1 -0
  45. package/dist/client.d.ts +100 -0
  46. package/dist/client.d.ts.map +1 -0
  47. package/dist/client.js +161 -0
  48. package/dist/client.js.map +1 -0
  49. package/dist/index.d.ts +9 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +10 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/types/calendar.d.ts +42 -0
  54. package/dist/types/calendar.d.ts.map +1 -0
  55. package/dist/types/calendar.js +2 -0
  56. package/dist/types/calendar.js.map +1 -0
  57. package/dist/types/chat.d.ts +21 -0
  58. package/dist/types/chat.d.ts.map +1 -0
  59. package/dist/types/chat.js +2 -0
  60. package/dist/types/chat.js.map +1 -0
  61. package/dist/types/common.d.ts +77 -0
  62. package/dist/types/common.d.ts.map +1 -0
  63. package/dist/types/common.js +19 -0
  64. package/dist/types/common.js.map +1 -0
  65. package/dist/types/file.d.ts +34 -0
  66. package/dist/types/file.d.ts.map +1 -0
  67. package/dist/types/file.js +5 -0
  68. package/dist/types/file.js.map +1 -0
  69. package/dist/types/index.d.ts +11 -0
  70. package/dist/types/index.d.ts.map +1 -0
  71. package/dist/types/index.js +2 -0
  72. package/dist/types/index.js.map +1 -0
  73. package/dist/types/mail.d.ts +25 -0
  74. package/dist/types/mail.d.ts.map +1 -0
  75. package/dist/types/mail.js +2 -0
  76. package/dist/types/mail.js.map +1 -0
  77. package/dist/types/message.d.ts +90 -0
  78. package/dist/types/message.d.ts.map +1 -0
  79. package/dist/types/message.js +2 -0
  80. package/dist/types/message.js.map +1 -0
  81. package/dist/types/presence.d.ts +15 -0
  82. package/dist/types/presence.d.ts.map +1 -0
  83. package/dist/types/presence.js +5 -0
  84. package/dist/types/presence.js.map +1 -0
  85. package/dist/types/transcript.d.ts +12 -0
  86. package/dist/types/transcript.d.ts.map +1 -0
  87. package/dist/types/transcript.js +2 -0
  88. package/dist/types/transcript.js.map +1 -0
  89. package/dist/types/user.d.ts +9 -0
  90. package/dist/types/user.d.ts.map +1 -0
  91. package/dist/types/user.js +2 -0
  92. package/dist/types/user.js.map +1 -0
  93. package/dist/utils/index.d.ts +7 -0
  94. package/dist/utils/index.d.ts.map +1 -0
  95. package/dist/utils/index.js +6 -0
  96. package/dist/utils/index.js.map +1 -0
  97. package/dist/utils/markdown.d.ts +13 -0
  98. package/dist/utils/markdown.d.ts.map +1 -0
  99. package/dist/utils/markdown.js +106 -0
  100. package/dist/utils/markdown.js.map +1 -0
  101. package/dist/utils/odata.d.ts +17 -0
  102. package/dist/utils/odata.d.ts.map +1 -0
  103. package/dist/utils/odata.js +19 -0
  104. package/dist/utils/odata.js.map +1 -0
  105. package/dist/utils/sharepoint.d.ts +11 -0
  106. package/dist/utils/sharepoint.d.ts.map +1 -0
  107. package/dist/utils/sharepoint.js +17 -0
  108. package/dist/utils/sharepoint.js.map +1 -0
  109. package/dist/utils/teams.d.ts +34 -0
  110. package/dist/utils/teams.d.ts.map +1 -0
  111. package/dist/utils/teams.js +67 -0
  112. package/dist/utils/teams.js.map +1 -0
  113. package/dist/utils/vtt.d.ts +7 -0
  114. package/dist/utils/vtt.d.ts.map +1 -0
  115. package/dist/utils/vtt.js +43 -0
  116. package/dist/utils/vtt.js.map +1 -0
  117. package/package.json +54 -0
@@ -0,0 +1,227 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { BaseApi } from './base.js';
3
+ import { markdownToHtml } from '../utils/markdown.js';
4
+ /**
5
+ * API for message operations.
6
+ */
7
+ export class MessagesApi extends BaseApi {
8
+ /**
9
+ * Get messages from a chat.
10
+ */
11
+ async getChatMessages(params) {
12
+ let query = this.client
13
+ .api(`/me/chats/${params.chatId}/messages`)
14
+ .top(params.limit || 20)
15
+ .orderby('createdDateTime desc');
16
+ if (params.fromUser) {
17
+ query = query.filter(`from/user/id eq '${params.fromUser}'`);
18
+ }
19
+ const response = (await query.get());
20
+ let messages = response?.value || [];
21
+ // Client-side filtering for date ranges
22
+ if ((params.from || params.to) && messages.length > 0) {
23
+ messages = messages.filter((message) => {
24
+ if (!message.createdDateTime)
25
+ return true;
26
+ const messageDate = new Date(message.createdDateTime);
27
+ if (params.from) {
28
+ const fromDate = new Date(params.from);
29
+ if (messageDate <= fromDate)
30
+ return false;
31
+ }
32
+ if (params.to) {
33
+ const toDate = new Date(params.to);
34
+ if (messageDate >= toDate)
35
+ return false;
36
+ }
37
+ return true;
38
+ });
39
+ }
40
+ return messages;
41
+ }
42
+ /**
43
+ * Send a message to a chat.
44
+ */
45
+ async sendChatMessage(params) {
46
+ // Process inline @email mentions FIRST (before markdown mangles them)
47
+ const mentionResult = await this.processInlineMentions(params.message);
48
+ // Then handle markdown conversion
49
+ let content;
50
+ if (params.format === 'markdown') {
51
+ content = await markdownToHtml(mentionResult.content);
52
+ }
53
+ else {
54
+ content = mentionResult.content;
55
+ }
56
+ // Build attachments array if provided
57
+ let attachments;
58
+ if (params.attachments && params.attachments.length > 0) {
59
+ attachments = params.attachments.map((contentUrl) => ({
60
+ id: randomUUID(),
61
+ contentType: 'reference',
62
+ contentUrl,
63
+ }));
64
+ }
65
+ const body = {
66
+ content,
67
+ contentType: params.format === 'markdown' ? 'html' : mentionResult.contentType,
68
+ };
69
+ const mentions = mentionResult.mentions.length > 0 ? mentionResult.mentions : undefined;
70
+ // Reply to a message using beta replyWithQuote endpoint
71
+ if (params.replyToId) {
72
+ const replyPayload = {
73
+ messageIds: [params.replyToId],
74
+ replyMessage: {
75
+ body,
76
+ importance: params.importance || 'normal',
77
+ mentions,
78
+ attachments,
79
+ },
80
+ };
81
+ return this.client
82
+ .api(`/chats/${params.chatId}/messages/replyWithQuote`)
83
+ .version('beta')
84
+ .post(replyPayload);
85
+ }
86
+ // Regular message
87
+ const messagePayload = {
88
+ body,
89
+ importance: params.importance || 'normal',
90
+ mentions,
91
+ attachments,
92
+ };
93
+ return this.client.api(`/me/chats/${params.chatId}/messages`).post(messagePayload);
94
+ }
95
+ /**
96
+ * Update an existing chat message.
97
+ */
98
+ async updateChatMessage(params) {
99
+ // Process inline @email mentions FIRST (before markdown mangles them)
100
+ const mentionResult = await this.processInlineMentions(params.message);
101
+ // Then handle markdown conversion
102
+ let content;
103
+ if (params.format === 'markdown') {
104
+ content = await markdownToHtml(mentionResult.content);
105
+ }
106
+ else {
107
+ content = mentionResult.content;
108
+ }
109
+ const messagePayload = {
110
+ body: {
111
+ content,
112
+ contentType: params.format === 'markdown' ? 'html' : mentionResult.contentType,
113
+ },
114
+ };
115
+ if (params.importance) {
116
+ messagePayload.importance = params.importance;
117
+ }
118
+ if (mentionResult.mentions.length > 0) {
119
+ messagePayload.mentions = mentionResult.mentions;
120
+ }
121
+ await this.client.api(`/chats/${params.chatId}/messages/${params.messageId}`).patch(messagePayload);
122
+ }
123
+ /**
124
+ * Search messages across chats and channels.
125
+ */
126
+ async search(params) {
127
+ const queryParts = [];
128
+ if (params.query) {
129
+ queryParts.push(params.query);
130
+ }
131
+ if (params.mentions) {
132
+ queryParts.push(`mentions:${params.mentions}`);
133
+ }
134
+ if (params.from) {
135
+ const dateOnly = params.from.split('T')[0];
136
+ queryParts.push(`sent>=${dateOnly}`);
137
+ }
138
+ if (params.fromUser) {
139
+ queryParts.push(`from:${params.fromUser}`);
140
+ }
141
+ let enhancedQuery = queryParts.length > 0 ? queryParts.join(' AND ') : '*';
142
+ const scope = params.scope || 'all';
143
+ if (scope === 'channels') {
144
+ enhancedQuery = `${enhancedQuery} AND (channelIdentity/channelId:*)`;
145
+ }
146
+ else if (scope === 'chats') {
147
+ enhancedQuery = `${enhancedQuery} AND (chatId:* AND NOT channelIdentity/channelId:*)`;
148
+ }
149
+ const searchRequest = {
150
+ entityTypes: ['chatMessage'],
151
+ query: {
152
+ queryString: enhancedQuery,
153
+ },
154
+ from: 0,
155
+ size: params.limit || 25,
156
+ enableTopResults: params.enableTopResults !== undefined ? params.enableTopResults : true,
157
+ };
158
+ return this.client.api('/search/query').post({ requests: [searchRequest] });
159
+ }
160
+ /**
161
+ * Set a reaction on a message.
162
+ */
163
+ async setReaction(params) {
164
+ await this.client
165
+ .api(`/chats/${params.chatId}/messages/${params.messageId}/setReaction`)
166
+ .post({ reactionType: params.reactionType });
167
+ }
168
+ /**
169
+ * Remove a reaction from a message.
170
+ */
171
+ async unsetReaction(params) {
172
+ await this.client
173
+ .api(`/chats/${params.chatId}/messages/${params.messageId}/unsetReaction`)
174
+ .post({ reactionType: params.reactionType });
175
+ }
176
+ /**
177
+ * Process inline @email mentions in message text.
178
+ */
179
+ async processInlineMentions(message) {
180
+ const emailMentionRegex = /@([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/g;
181
+ const matches = [...message.matchAll(emailMentionRegex)];
182
+ if (matches.length === 0) {
183
+ return { content: message, mentions: [], contentType: 'text' };
184
+ }
185
+ // Resolve unique emails to user info
186
+ const uniqueEmails = [...new Set(matches.map((m) => m[1]))];
187
+ const userMap = new Map();
188
+ for (const email of uniqueEmails) {
189
+ try {
190
+ const user = (await this.client.api(`/users/${email}`).select('id,displayName').get());
191
+ userMap.set(email, { id: user.id, displayName: user.displayName || email });
192
+ }
193
+ catch {
194
+ userMap.set(email, null);
195
+ }
196
+ }
197
+ // Assign IDs to resolvable mentions in forward order
198
+ const mentionData = [];
199
+ let mentionId = 0;
200
+ for (const match of matches) {
201
+ const userInfo = userMap.get(match[1]);
202
+ if (userInfo) {
203
+ mentionData.push({ match, userInfo, mentionId });
204
+ mentionId++;
205
+ }
206
+ }
207
+ // Build mentions array
208
+ const mentions = mentionData.map((data) => ({
209
+ id: data.mentionId,
210
+ mentionText: data.userInfo.displayName,
211
+ mentioned: {
212
+ user: { id: data.userInfo.id, displayName: data.userInfo.displayName },
213
+ },
214
+ }));
215
+ // Process string replacements in reverse order to maintain correct positions
216
+ let processedContent = message;
217
+ const reversedData = [...mentionData].sort((a, b) => (b.match.index ?? 0) - (a.match.index ?? 0));
218
+ for (const data of reversedData) {
219
+ const atTag = `<at id="${data.mentionId}">${data.userInfo.displayName}</at>`;
220
+ const startIndex = data.match.index ?? 0;
221
+ processedContent =
222
+ processedContent.slice(0, startIndex) + atTag + processedContent.slice(startIndex + data.match[0].length);
223
+ }
224
+ return { content: processedContent, mentions, contentType: mentions.length > 0 ? 'html' : 'text' };
225
+ }
226
+ }
227
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/api/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { BaseApi } from './base.js';
2
+ import type { CallTranscript, GetMeetingByJoinUrlParams, GetTranscriptContentParams, ListTranscriptsParams, OnlineMeeting } from '../types/index.js';
3
+ /**
4
+ * API for meeting transcript operations.
5
+ */
6
+ export declare class TranscriptsApi extends BaseApi {
7
+ /**
8
+ * Get a meeting by its join URL.
9
+ */
10
+ getMeetingByJoinUrl(params: GetMeetingByJoinUrlParams): Promise<OnlineMeeting | null>;
11
+ /**
12
+ * List transcripts for a meeting.
13
+ */
14
+ list(params: ListTranscriptsParams): Promise<CallTranscript[]>;
15
+ /**
16
+ * Get the content of a transcript as VTT text.
17
+ */
18
+ getContent(params: GetTranscriptContentParams): Promise<string>;
19
+ }
20
+ //# sourceMappingURL=transcripts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcripts.d.ts","sourceRoot":"","sources":["../../src/api/transcripts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EACd,yBAAyB,EACzB,0BAA0B,EAE1B,qBAAqB,EACrB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,qBAAa,cAAe,SAAQ,OAAO;IACzC;;OAEG;IACU,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IASlG;;OAEG;IACU,IAAI,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAQ3E;;OAEG;IACU,UAAU,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;CAyB7E"}
@@ -0,0 +1,53 @@
1
+ import { BaseApi } from './base.js';
2
+ /**
3
+ * API for meeting transcript operations.
4
+ */
5
+ export class TranscriptsApi extends BaseApi {
6
+ /**
7
+ * Get a meeting by its join URL.
8
+ */
9
+ async getMeetingByJoinUrl(params) {
10
+ const response = (await this.client
11
+ .api('/me/onlineMeetings')
12
+ .filter(`JoinWebUrl eq '${params.joinWebUrl}'`)
13
+ .get());
14
+ return response.value?.[0] || null;
15
+ }
16
+ /**
17
+ * List transcripts for a meeting.
18
+ */
19
+ async list(params) {
20
+ const response = (await this.client
21
+ .api(`/me/onlineMeetings/${params.meetingId}/transcripts`)
22
+ .get());
23
+ return response.value || [];
24
+ }
25
+ /**
26
+ * Get the content of a transcript as VTT text.
27
+ */
28
+ async getContent(params) {
29
+ const stream = (await this.client
30
+ .api(`/me/onlineMeetings/${params.meetingId}/transcripts/${params.transcriptId}/content`)
31
+ .query({ $format: 'text/vtt' })
32
+ .get());
33
+ // Convert stream to text
34
+ const reader = stream.getReader();
35
+ const chunks = [];
36
+ while (true) {
37
+ const { done, value } = await reader.read();
38
+ if (done)
39
+ break;
40
+ if (value)
41
+ chunks.push(value);
42
+ }
43
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
44
+ const combined = new Uint8Array(totalLength);
45
+ let offset = 0;
46
+ for (const chunk of chunks) {
47
+ combined.set(chunk, offset);
48
+ offset += chunk.length;
49
+ }
50
+ return new TextDecoder('utf-8').decode(combined);
51
+ }
52
+ }
53
+ //# sourceMappingURL=transcripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcripts.js","sourceRoot":"","sources":["../../src/api/transcripts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,OAAO;IACzC;;OAEG;IACI,KAAK,CAAC,mBAAmB,CAAC,MAAiC;QAChE,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM;aAChC,GAAG,CAAC,oBAAoB,CAAC;aACzB,MAAM,CAAC,kBAAkB,MAAM,CAAC,UAAU,GAAG,CAAC;aAC9C,GAAG,EAAE,CAAoC,CAAC;QAE7C,OAAO,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACrC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAAC,MAA6B;QAC7C,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM;aAChC,GAAG,CAAC,sBAAsB,MAAM,CAAC,SAAS,cAAc,CAAC;aACzD,GAAG,EAAE,CAAqC,CAAC;QAE9C,OAAO,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,UAAU,CAAC,MAAkC;QACxD,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM;aAC9B,GAAG,CAAC,sBAAsB,MAAM,CAAC,SAAS,gBAAgB,MAAM,CAAC,YAAY,UAAU,CAAC;aACxF,KAAK,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;aAC9B,GAAG,EAAE,CAA+B,CAAC;QAExC,yBAAyB;QACzB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QAClC,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,IAAI,KAAK;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import { BaseApi } from './base.js';
2
+ import type { GetUserParams, SearchUsersParams, User } from '../types/index.js';
3
+ import type { SetPreferredPresenceParams } from '../types/presence.js';
4
+ /**
5
+ * API for user operations.
6
+ */
7
+ export declare class UsersApi extends BaseApi {
8
+ /**
9
+ * Get the current authenticated user.
10
+ */
11
+ getCurrentUser(): Promise<User>;
12
+ /**
13
+ * Get a user by ID or userPrincipalName.
14
+ */
15
+ get(params: GetUserParams): Promise<User>;
16
+ /**
17
+ * Search for users by name or email.
18
+ */
19
+ search(params: SearchUsersParams): Promise<User[]>;
20
+ /**
21
+ * Set the user's preferred presence status.
22
+ */
23
+ setPreferredPresence(params: SetPreferredPresenceParams): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/api/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAoB,aAAa,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAClG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAEvE;;GAEG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;IACU,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD;;OAEG;IACU,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAS/D;;OAEG;IACU,oBAAoB,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CAOrF"}
@@ -0,0 +1,39 @@
1
+ import { BaseApi } from './base.js';
2
+ /**
3
+ * API for user operations.
4
+ */
5
+ export class UsersApi extends BaseApi {
6
+ /**
7
+ * Get the current authenticated user.
8
+ */
9
+ async getCurrentUser() {
10
+ return this.client.api('/me').get();
11
+ }
12
+ /**
13
+ * Get a user by ID or userPrincipalName.
14
+ */
15
+ async get(params) {
16
+ return this.client.api(`/users/${params.userId}`).get();
17
+ }
18
+ /**
19
+ * Search for users by name or email.
20
+ */
21
+ async search(params) {
22
+ const response = (await this.client
23
+ .api('/users?ConsistencyLevel=eventual')
24
+ .search(`"mail:${params.query}" OR "displayName:${params.query}"`)
25
+ .get());
26
+ return response.value ?? [];
27
+ }
28
+ /**
29
+ * Set the user's preferred presence status.
30
+ */
31
+ async setPreferredPresence(params) {
32
+ await this.client.api('/me/presence/setUserPreferredPresence').post({
33
+ availability: params.availability,
34
+ activity: params.activity || params.availability,
35
+ expirationDuration: params.expirationDuration,
36
+ });
37
+ }
38
+ }
39
+ //# sourceMappingURL=users.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/api/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,OAAO;IACnC;;OAEG;IACI,KAAK,CAAC,cAAc;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAmB,CAAC;IACvD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,GAAG,CAAC,MAAqB;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAmB,CAAC;IAC3E,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CAAC,MAAyB;QAC3C,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM;aAChC,GAAG,CAAC,kCAAkC,CAAC;aACvC,MAAM,CAAC,SAAS,MAAM,CAAC,KAAK,qBAAqB,MAAM,CAAC,KAAK,GAAG,CAAC;aACjE,GAAG,EAAE,CAA2B,CAAC;QAEpC,OAAO,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,oBAAoB,CAAC,MAAkC;QAClE,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC,IAAI,CAAC;YAClE,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,YAAY;YAChD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;SAC9C,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ import { Client } from '@microsoft/microsoft-graph-client';
2
+ import type { AuthResult, GraphClientConfig } from '../types/common.js';
3
+ /**
4
+ * Authenticator handles Microsoft Graph authentication.
5
+ *
6
+ * Supports two modes:
7
+ * 1. Device Code Auth - Interactive authentication that persists to disk
8
+ * 2. Pre-seeded Auth - Non-interactive using a previously obtained auth record
9
+ *
10
+ * Uses DeviceCodeCredential with persistent token caching:
11
+ * - Access tokens refresh automatically when they expire (~1 hour)
12
+ * - Refresh tokens valid for ~90 days
13
+ * - Silent re-authentication (no device code prompt after initial auth)
14
+ */
15
+ export declare class Authenticator {
16
+ private config;
17
+ private credential;
18
+ private authRecord;
19
+ private sdkClient;
20
+ constructor(config: GraphClientConfig);
21
+ /**
22
+ * Get the Microsoft Graph SDK client.
23
+ * Creates the client on first call, reuses on subsequent calls.
24
+ */
25
+ getClient(): Promise<Client>;
26
+ /**
27
+ * Perform interactive device code authentication.
28
+ * This is typically run once to obtain an auth record that can be persisted.
29
+ *
30
+ * @param onDeviceCode - Callback to display the device code to the user
31
+ * @returns The authentication result with serialized auth record
32
+ */
33
+ authenticate(onDeviceCode?: (info: {
34
+ userCode: string;
35
+ verificationUri: string;
36
+ message: string;
37
+ }) => void): Promise<AuthResult>;
38
+ /**
39
+ * Clear the cached client (forces recreation on next getClient call).
40
+ * Useful for testing or when you want to force token refresh.
41
+ */
42
+ clearCache(): void;
43
+ /**
44
+ * Load the AuthenticationRecord from disk or pre-seeded config.
45
+ */
46
+ private loadAuthRecord;
47
+ }
48
+ //# sourceMappingURL=authenticator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticator.d.ts","sourceRoot":"","sources":["../../src/auth/authenticator.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAKxE;;;;;;;;;;;GAWG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,SAAS,CAAuB;gBAErB,MAAM,EAAE,iBAAiB;IAI5C;;;OAGG;IACU,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAmDzC;;;;;;OAMG;IACU,YAAY,CACvB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAC5F,OAAO,CAAC,UAAU,CAAC;IAkDtB;;;OAGG;IACI,UAAU,IAAI,IAAI;IAKzB;;OAEG;YACW,cAAc;CAsB7B"}
@@ -0,0 +1,159 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { DeviceCodeCredential, deserializeAuthenticationRecord, serializeAuthenticationRecord, useIdentityPlugin, } from '@azure/identity';
5
+ import { cachePersistencePlugin } from '@azure/identity-cache-persistence';
6
+ import { Client } from '@microsoft/microsoft-graph-client';
7
+ import { DEFAULT_SCOPES } from '../types/common.js';
8
+ // Register the persistent cache plugin (must be done once at module load)
9
+ useIdentityPlugin(cachePersistencePlugin);
10
+ /**
11
+ * Authenticator handles Microsoft Graph authentication.
12
+ *
13
+ * Supports two modes:
14
+ * 1. Device Code Auth - Interactive authentication that persists to disk
15
+ * 2. Pre-seeded Auth - Non-interactive using a previously obtained auth record
16
+ *
17
+ * Uses DeviceCodeCredential with persistent token caching:
18
+ * - Access tokens refresh automatically when they expire (~1 hour)
19
+ * - Refresh tokens valid for ~90 days
20
+ * - Silent re-authentication (no device code prompt after initial auth)
21
+ */
22
+ export class Authenticator {
23
+ config;
24
+ credential = null;
25
+ authRecord = null;
26
+ sdkClient = null;
27
+ constructor(config) {
28
+ this.config = config;
29
+ }
30
+ /**
31
+ * Get the Microsoft Graph SDK client.
32
+ * Creates the client on first call, reuses on subsequent calls.
33
+ */
34
+ async getClient() {
35
+ if (this.sdkClient) {
36
+ return this.sdkClient;
37
+ }
38
+ // Try to load auth record
39
+ await this.loadAuthRecord();
40
+ // Create DeviceCodeCredential with persistent cache
41
+ this.credential = new DeviceCodeCredential({
42
+ clientId: this.config.clientId,
43
+ tenantId: this.config.tenantId,
44
+ tokenCachePersistenceOptions: {
45
+ enabled: true,
46
+ name: this.config.cacheName || 'microsoft-graph-client',
47
+ unsafeAllowUnencryptedStorage: true, // Allow unencrypted storage if keychain unavailable
48
+ },
49
+ // Pass the AuthenticationRecord to enable silent authentication
50
+ authenticationRecord: this.authRecord || undefined,
51
+ });
52
+ const scopes = this.config.scopes || DEFAULT_SCOPES;
53
+ // Create Graph client with auth provider
54
+ this.sdkClient = Client.initWithMiddleware({
55
+ authProvider: {
56
+ getAccessToken: async () => {
57
+ try {
58
+ const tokenResponse = await this.credential?.getToken(scopes);
59
+ if (!tokenResponse) {
60
+ throw new Error('Failed to obtain token. Run: authenticate() first');
61
+ }
62
+ return tokenResponse.token;
63
+ }
64
+ catch (_error) {
65
+ throw new Error('Authentication failed. This could mean:\n' +
66
+ " 1. You haven't authenticated yet\n" +
67
+ ' 2. Your refresh token expired (after ~90 days)\n' +
68
+ ' 3. Your credentials were revoked\n\n' +
69
+ 'Solution: Run the authenticate() method');
70
+ }
71
+ },
72
+ },
73
+ });
74
+ return this.sdkClient;
75
+ }
76
+ /**
77
+ * Perform interactive device code authentication.
78
+ * This is typically run once to obtain an auth record that can be persisted.
79
+ *
80
+ * @param onDeviceCode - Callback to display the device code to the user
81
+ * @returns The authentication result with serialized auth record
82
+ */
83
+ async authenticate(onDeviceCode) {
84
+ const scopes = this.config.scopes || DEFAULT_SCOPES;
85
+ // Create credential with device code callback
86
+ const credential = new DeviceCodeCredential({
87
+ clientId: this.config.clientId,
88
+ tenantId: this.config.tenantId,
89
+ tokenCachePersistenceOptions: {
90
+ enabled: true,
91
+ name: this.config.cacheName || 'microsoft-graph-client',
92
+ unsafeAllowUnencryptedStorage: true,
93
+ },
94
+ userPromptCallback: (info) => {
95
+ if (onDeviceCode) {
96
+ onDeviceCode({
97
+ userCode: info.userCode,
98
+ verificationUri: info.verificationUri,
99
+ message: info.message,
100
+ });
101
+ }
102
+ else {
103
+ // Default: print to console
104
+ console.log(`\n${info.message}`);
105
+ }
106
+ },
107
+ });
108
+ // Trigger authentication by getting a token
109
+ await credential.getToken(scopes);
110
+ // Get the authentication record
111
+ const record = await credential.authenticate(scopes);
112
+ if (!record) {
113
+ throw new Error('Authentication failed: No authentication record obtained');
114
+ }
115
+ const serialized = serializeAuthenticationRecord(record);
116
+ // Save to disk if path is configured
117
+ if (this.config.authRecordPath) {
118
+ await fs.writeFile(this.config.authRecordPath, serialized, 'utf-8');
119
+ }
120
+ // Store for future use
121
+ this.authRecord = record;
122
+ this.credential = credential;
123
+ return { record, serialized };
124
+ }
125
+ /**
126
+ * Clear the cached client (forces recreation on next getClient call).
127
+ * Useful for testing or when you want to force token refresh.
128
+ */
129
+ clearCache() {
130
+ this.sdkClient = null;
131
+ this.credential = null;
132
+ }
133
+ /**
134
+ * Load the AuthenticationRecord from disk or pre-seeded config.
135
+ */
136
+ async loadAuthRecord() {
137
+ // Option 1: Pre-seeded auth record from config
138
+ if (this.config.authRecord) {
139
+ try {
140
+ this.authRecord = deserializeAuthenticationRecord(this.config.authRecord);
141
+ return;
142
+ }
143
+ catch {
144
+ // Invalid auth record, continue to try file
145
+ }
146
+ }
147
+ // Option 2: Load from file path
148
+ const authRecordPath = this.config.authRecordPath || join(homedir(), '.microsoft-graph-client-auth-record.json');
149
+ try {
150
+ const content = await fs.readFile(authRecordPath, 'utf-8');
151
+ this.authRecord = deserializeAuthenticationRecord(content);
152
+ }
153
+ catch {
154
+ // Auth record doesn't exist or can't be read - user needs to authenticate
155
+ this.authRecord = null;
156
+ }
157
+ }
158
+ }
159
+ //# sourceMappingURL=authenticator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticator.js","sourceRoot":"","sources":["../../src/auth/authenticator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { Authenticator } from './authenticator.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Authenticator } from './authenticator.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}