@kodelyth/msteams 2026.5.39 → 2026.5.42

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 (208) hide show
  1. package/api.ts +3 -0
  2. package/channel-config-api.ts +1 -0
  3. package/channel-plugin-api.ts +2 -0
  4. package/config-api.ts +4 -0
  5. package/contract-api.ts +4 -0
  6. package/dist/api.js +3 -0
  7. package/dist/channel-BvTXHuGs.js +1161 -0
  8. package/dist/channel-config-api.js +2 -0
  9. package/dist/channel-plugin-api.js +2 -0
  10. package/dist/channel.runtime-NssGKZm5.js +650 -0
  11. package/dist/config-schema-Btk-XCOd.js +43 -0
  12. package/dist/contract-api.js +2 -0
  13. package/dist/graph-users-D-gKCguI.js +1411 -0
  14. package/dist/index.js +22 -0
  15. package/dist/oauth-BUxlphX3.js +114 -0
  16. package/dist/oauth.token-ebId9946.js +116 -0
  17. package/dist/probe-Cj2KsAGF.js +2190 -0
  18. package/dist/runtime-api-BL4DOWXD.js +28 -0
  19. package/dist/runtime-api.js +2 -0
  20. package/dist/secret-contract-Bo7kdUrT.js +35 -0
  21. package/dist/secret-contract-api.js +2 -0
  22. package/dist/setup-entry.js +15 -0
  23. package/dist/setup-plugin-api.js +64 -0
  24. package/dist/setup-surface-COTQDcTQ.js +531 -0
  25. package/dist/src-tvpsGYPV.js +4226 -0
  26. package/dist/test-api.js +2 -0
  27. package/index.ts +20 -0
  28. package/klaw.plugin.json +2 -726
  29. package/package.json +4 -4
  30. package/runtime-api.ts +66 -0
  31. package/secret-contract-api.ts +5 -0
  32. package/setup-entry.ts +13 -0
  33. package/setup-plugin-api.ts +3 -0
  34. package/src/ai-entity.ts +7 -0
  35. package/src/approval-auth.ts +44 -0
  36. package/src/attachments/bot-framework.test.ts +506 -0
  37. package/src/attachments/bot-framework.ts +348 -0
  38. package/src/attachments/download.ts +328 -0
  39. package/src/attachments/graph.test.ts +441 -0
  40. package/src/attachments/graph.ts +489 -0
  41. package/src/attachments/html.ts +122 -0
  42. package/src/attachments/payload.ts +14 -0
  43. package/src/attachments/remote-media.test.ts +187 -0
  44. package/src/attachments/remote-media.ts +86 -0
  45. package/src/attachments/shared.test.ts +547 -0
  46. package/src/attachments/shared.ts +655 -0
  47. package/src/attachments/types.ts +47 -0
  48. package/src/attachments.graph.test.ts +414 -0
  49. package/src/attachments.helpers.test.ts +245 -0
  50. package/src/attachments.test-helpers.ts +17 -0
  51. package/src/attachments.test.ts +754 -0
  52. package/src/attachments.ts +18 -0
  53. package/src/block-streaming-config.test.ts +61 -0
  54. package/src/channel-api.ts +1 -0
  55. package/src/channel.actions.test.ts +797 -0
  56. package/src/channel.directory.test.ts +176 -0
  57. package/src/channel.message-adapter.test.ts +227 -0
  58. package/src/channel.runtime.ts +56 -0
  59. package/src/channel.setup.ts +77 -0
  60. package/src/channel.test.ts +136 -0
  61. package/src/channel.ts +1176 -0
  62. package/src/config-schema.ts +6 -0
  63. package/src/config-ui-hints.ts +40 -0
  64. package/src/conversation-store-fs.test.ts +81 -0
  65. package/src/conversation-store-fs.ts +149 -0
  66. package/src/conversation-store-helpers.test.ts +202 -0
  67. package/src/conversation-store-helpers.ts +105 -0
  68. package/src/conversation-store-memory.ts +51 -0
  69. package/src/conversation-store.shared.test.ts +260 -0
  70. package/src/conversation-store.ts +71 -0
  71. package/src/directory-live.test.ts +156 -0
  72. package/src/directory-live.ts +111 -0
  73. package/src/doctor.ts +27 -0
  74. package/src/errors.test.ts +154 -0
  75. package/src/errors.ts +270 -0
  76. package/src/feedback-reflection-prompt.ts +117 -0
  77. package/src/feedback-reflection-store.ts +113 -0
  78. package/src/feedback-reflection.test.ts +237 -0
  79. package/src/feedback-reflection.ts +268 -0
  80. package/src/file-consent-helpers.test.ts +328 -0
  81. package/src/file-consent-helpers.ts +115 -0
  82. package/src/file-consent-invoke.ts +150 -0
  83. package/src/file-consent.test.ts +378 -0
  84. package/src/file-consent.ts +223 -0
  85. package/src/graph-chat.ts +36 -0
  86. package/src/graph-group-management.test.ts +332 -0
  87. package/src/graph-group-management.ts +168 -0
  88. package/src/graph-members.test.ts +89 -0
  89. package/src/graph-members.ts +48 -0
  90. package/src/graph-messages.actions.test.ts +253 -0
  91. package/src/graph-messages.read.test.ts +391 -0
  92. package/src/graph-messages.search.test.ts +227 -0
  93. package/src/graph-messages.test-helpers.ts +50 -0
  94. package/src/graph-messages.ts +534 -0
  95. package/src/graph-teams.test.ts +222 -0
  96. package/src/graph-teams.ts +114 -0
  97. package/src/graph-thread.test.ts +252 -0
  98. package/src/graph-thread.ts +146 -0
  99. package/src/graph-upload.test.ts +253 -0
  100. package/src/graph-upload.ts +531 -0
  101. package/src/graph-users.ts +29 -0
  102. package/src/graph.test.ts +540 -0
  103. package/src/graph.ts +308 -0
  104. package/src/inbound.test.ts +221 -0
  105. package/src/inbound.ts +148 -0
  106. package/src/index.ts +4 -0
  107. package/src/media-helpers.test.ts +220 -0
  108. package/src/media-helpers.ts +105 -0
  109. package/src/mentions.test.ts +254 -0
  110. package/src/mentions.ts +114 -0
  111. package/src/messenger.test.ts +961 -0
  112. package/src/messenger.ts +608 -0
  113. package/src/monitor-handler/access.ts +136 -0
  114. package/src/monitor-handler/inbound-media.test.ts +314 -0
  115. package/src/monitor-handler/inbound-media.ts +180 -0
  116. package/src/monitor-handler/message-handler-mock-support.test-support.ts +28 -0
  117. package/src/monitor-handler/message-handler.authz.test.ts +739 -0
  118. package/src/monitor-handler/message-handler.dm-media.test.ts +54 -0
  119. package/src/monitor-handler/message-handler.test-support.ts +99 -0
  120. package/src/monitor-handler/message-handler.thread-parent.test.ts +225 -0
  121. package/src/monitor-handler/message-handler.thread-session.test.ts +132 -0
  122. package/src/monitor-handler/message-handler.ts +1003 -0
  123. package/src/monitor-handler/reaction-handler.test.ts +325 -0
  124. package/src/monitor-handler/reaction-handler.ts +122 -0
  125. package/src/monitor-handler/thread-session.ts +30 -0
  126. package/src/monitor-handler.adaptive-card.test.ts +158 -0
  127. package/src/monitor-handler.feedback-authz.test.ts +357 -0
  128. package/src/monitor-handler.file-consent.test.ts +443 -0
  129. package/src/monitor-handler.sso.test.ts +576 -0
  130. package/src/monitor-handler.test-helpers.ts +181 -0
  131. package/src/monitor-handler.ts +538 -0
  132. package/src/monitor-handler.types.ts +27 -0
  133. package/src/monitor-types.ts +6 -0
  134. package/src/monitor.lifecycle.test.ts +457 -0
  135. package/src/monitor.test.ts +119 -0
  136. package/src/monitor.ts +476 -0
  137. package/src/oauth.flow.ts +77 -0
  138. package/src/oauth.shared.ts +37 -0
  139. package/src/oauth.test.ts +350 -0
  140. package/src/oauth.token.ts +162 -0
  141. package/src/oauth.ts +130 -0
  142. package/src/outbound.test.ts +400 -0
  143. package/src/outbound.ts +198 -0
  144. package/src/pending-uploads-fs.test.ts +261 -0
  145. package/src/pending-uploads-fs.ts +235 -0
  146. package/src/pending-uploads.test.ts +186 -0
  147. package/src/pending-uploads.ts +121 -0
  148. package/src/policy.test.ts +156 -0
  149. package/src/policy.ts +245 -0
  150. package/src/polls-store-memory.ts +32 -0
  151. package/src/polls.test.ts +169 -0
  152. package/src/polls.ts +312 -0
  153. package/src/presentation.ts +93 -0
  154. package/src/probe.test.ts +79 -0
  155. package/src/probe.ts +132 -0
  156. package/src/reply-dispatcher.test.ts +543 -0
  157. package/src/reply-dispatcher.ts +523 -0
  158. package/src/reply-stream-controller.test.ts +424 -0
  159. package/src/reply-stream-controller.ts +334 -0
  160. package/src/resolve-allowlist.test.ts +253 -0
  161. package/src/resolve-allowlist.ts +309 -0
  162. package/src/revoked-context.ts +17 -0
  163. package/src/runtime.ts +12 -0
  164. package/src/sdk-types.ts +59 -0
  165. package/src/sdk.test.ts +727 -0
  166. package/src/sdk.ts +916 -0
  167. package/src/secret-contract.ts +49 -0
  168. package/src/secret-input.ts +7 -0
  169. package/src/send-context.test.ts +93 -0
  170. package/src/send-context.ts +269 -0
  171. package/src/send.test.ts +588 -0
  172. package/src/send.ts +697 -0
  173. package/src/sent-message-cache.test.ts +106 -0
  174. package/src/sent-message-cache.ts +174 -0
  175. package/src/session-route.ts +40 -0
  176. package/src/setup-core.ts +162 -0
  177. package/src/setup-surface.test.ts +175 -0
  178. package/src/setup-surface.ts +319 -0
  179. package/src/sso-token-store.test.ts +74 -0
  180. package/src/sso-token-store.ts +166 -0
  181. package/src/sso.ts +300 -0
  182. package/src/storage.ts +25 -0
  183. package/src/store-fs.ts +42 -0
  184. package/src/streaming-message.test.ts +323 -0
  185. package/src/streaming-message.ts +327 -0
  186. package/src/test-runtime.ts +16 -0
  187. package/src/thread-parent-context.test.ts +224 -0
  188. package/src/thread-parent-context.ts +159 -0
  189. package/src/token-response.ts +11 -0
  190. package/src/token.test.ts +268 -0
  191. package/src/token.ts +194 -0
  192. package/src/user-agent.test.ts +121 -0
  193. package/src/user-agent.ts +53 -0
  194. package/src/webhook-timeouts.ts +27 -0
  195. package/src/welcome-card.test.ts +104 -0
  196. package/src/welcome-card.ts +57 -0
  197. package/test-api.ts +1 -0
  198. package/tsconfig.json +16 -0
  199. package/api.js +0 -7
  200. package/channel-config-api.js +0 -7
  201. package/channel-plugin-api.js +0 -7
  202. package/contract-api.js +0 -7
  203. package/index.js +0 -7
  204. package/runtime-api.js +0 -7
  205. package/secret-contract-api.js +0 -7
  206. package/setup-entry.js +0 -7
  207. package/setup-plugin-api.js +0 -7
  208. package/test-api.js +0 -7
@@ -0,0 +1,227 @@
1
+ import { beforeAll, describe, expect, it } from "vitest";
2
+ import type { KlawConfig } from "../runtime-api.js";
3
+ import {
4
+ CHANNEL_TO,
5
+ CHAT_ID,
6
+ type GraphMessagesTestModule,
7
+ getGraphMessagesMockState,
8
+ installGraphMessagesMockDefaults,
9
+ loadGraphMessagesTestModule,
10
+ } from "./graph-messages.test-helpers.js";
11
+
12
+ const mockState = getGraphMessagesMockState();
13
+ installGraphMessagesMockDefaults();
14
+ let searchMessagesMSTeams: GraphMessagesTestModule["searchMessagesMSTeams"];
15
+
16
+ beforeAll(async () => {
17
+ ({ searchMessagesMSTeams } = await loadGraphMessagesTestModule());
18
+ });
19
+
20
+ function readFirstGraphPath(): string {
21
+ const [call] = mockState.fetchGraphJson.mock.calls;
22
+ if (!call) {
23
+ throw new Error("Expected Graph fetch call");
24
+ }
25
+ const [request] = call;
26
+ if (!request || typeof request !== "object" || typeof request.path !== "string") {
27
+ throw new Error("Expected Graph fetch request path");
28
+ }
29
+ return request.path;
30
+ }
31
+
32
+ describe("searchMessagesMSTeams", () => {
33
+ it("searches chat messages with query string", async () => {
34
+ mockState.fetchGraphJson.mockResolvedValue({
35
+ value: [
36
+ {
37
+ id: "msg-1",
38
+ body: { content: "Meeting notes from Monday" },
39
+ from: { user: { id: "u1", displayName: "Alice" } },
40
+ createdDateTime: "2026-03-25T10:00:00Z",
41
+ },
42
+ ],
43
+ });
44
+
45
+ const result = await searchMessagesMSTeams({
46
+ cfg: {} as KlawConfig,
47
+ to: CHAT_ID,
48
+ query: "meeting notes",
49
+ });
50
+
51
+ expect(result.messages).toEqual([
52
+ {
53
+ id: "msg-1",
54
+ text: "Meeting notes from Monday",
55
+ from: { user: { id: "u1", displayName: "Alice" } },
56
+ createdAt: "2026-03-25T10:00:00Z",
57
+ },
58
+ ]);
59
+ const calledPath = readFirstGraphPath();
60
+ expect(calledPath).toContain(`/chats/${encodeURIComponent(CHAT_ID)}/messages?`);
61
+ expect(calledPath).toContain("$search=");
62
+ expect(calledPath).toContain("$top=25");
63
+ const decoded = decodeURIComponent(calledPath);
64
+ expect(decoded).toContain('$search="meeting notes"');
65
+ });
66
+
67
+ it("searches channel messages", async () => {
68
+ mockState.fetchGraphJson.mockResolvedValue({
69
+ value: [
70
+ {
71
+ id: "msg-2",
72
+ body: { content: "Sprint review" },
73
+ from: { user: { id: "u2", displayName: "Bob" } },
74
+ createdDateTime: "2026-03-25T11:00:00Z",
75
+ },
76
+ ],
77
+ });
78
+
79
+ const result = await searchMessagesMSTeams({
80
+ cfg: {} as KlawConfig,
81
+ to: CHANNEL_TO,
82
+ query: "sprint",
83
+ });
84
+
85
+ expect(result.messages).toHaveLength(1);
86
+ const calledPath = readFirstGraphPath();
87
+ expect(calledPath).toContain("/teams/team-id-1/channels/channel-id-1/messages?");
88
+ });
89
+
90
+ it("applies limit parameter", async () => {
91
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
92
+
93
+ await searchMessagesMSTeams({
94
+ cfg: {} as KlawConfig,
95
+ to: CHAT_ID,
96
+ query: "test",
97
+ limit: 10,
98
+ });
99
+
100
+ const calledPath = readFirstGraphPath();
101
+ expect(calledPath).toContain("$top=10");
102
+ });
103
+
104
+ it("clamps limit to max 50", async () => {
105
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
106
+
107
+ await searchMessagesMSTeams({
108
+ cfg: {} as KlawConfig,
109
+ to: CHAT_ID,
110
+ query: "test",
111
+ limit: 100,
112
+ });
113
+
114
+ const calledPath = readFirstGraphPath();
115
+ expect(calledPath).toContain("$top=50");
116
+ });
117
+
118
+ it("clamps limit to min 1", async () => {
119
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
120
+
121
+ await searchMessagesMSTeams({
122
+ cfg: {} as KlawConfig,
123
+ to: CHAT_ID,
124
+ query: "test",
125
+ limit: 0,
126
+ });
127
+
128
+ const calledPath = readFirstGraphPath();
129
+ expect(calledPath).toContain("$top=1");
130
+ });
131
+
132
+ it("applies from filter", async () => {
133
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
134
+
135
+ await searchMessagesMSTeams({
136
+ cfg: {} as KlawConfig,
137
+ to: CHAT_ID,
138
+ query: "budget",
139
+ from: "Alice",
140
+ });
141
+
142
+ const calledPath = readFirstGraphPath();
143
+ expect(calledPath).toContain("$filter=");
144
+ const decoded = decodeURIComponent(calledPath);
145
+ expect(decoded).toContain("from/user/displayName eq 'Alice'");
146
+ });
147
+
148
+ it("escapes single quotes in from filter", async () => {
149
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
150
+
151
+ await searchMessagesMSTeams({
152
+ cfg: {} as KlawConfig,
153
+ to: CHAT_ID,
154
+ query: "test",
155
+ from: "O'Brien",
156
+ });
157
+
158
+ const calledPath = readFirstGraphPath();
159
+ const decoded = decodeURIComponent(calledPath);
160
+ expect(decoded).toContain("O''Brien");
161
+ });
162
+
163
+ it("strips double quotes from query to prevent injection", async () => {
164
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
165
+
166
+ await searchMessagesMSTeams({
167
+ cfg: {} as KlawConfig,
168
+ to: CHAT_ID,
169
+ query: 'say "hello" world',
170
+ });
171
+
172
+ const calledPath = readFirstGraphPath();
173
+ const decoded = decodeURIComponent(calledPath);
174
+ expect(decoded).toContain('$search="say hello world"');
175
+ expect(decoded).not.toContain('""');
176
+ });
177
+
178
+ it("passes ConsistencyLevel: eventual header", async () => {
179
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
180
+
181
+ await searchMessagesMSTeams({
182
+ cfg: {} as KlawConfig,
183
+ to: CHAT_ID,
184
+ query: "test",
185
+ });
186
+
187
+ expect(mockState.fetchGraphJson).toHaveBeenCalledWith({
188
+ token: "test-graph-token",
189
+ path: `/chats/${encodeURIComponent(CHAT_ID)}/messages?$search=${encodeURIComponent(
190
+ '"test"',
191
+ )}&$top=25`,
192
+ headers: { ConsistencyLevel: "eventual" },
193
+ });
194
+ });
195
+
196
+ it("returns empty array when no messages match", async () => {
197
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
198
+
199
+ const result = await searchMessagesMSTeams({
200
+ cfg: {} as KlawConfig,
201
+ to: CHAT_ID,
202
+ query: "nonexistent",
203
+ });
204
+
205
+ expect(result.messages).toStrictEqual([]);
206
+ });
207
+
208
+ it("resolves user: target through conversation store", async () => {
209
+ mockState.findPreferredDmByUserId.mockResolvedValue({
210
+ conversationId: "a:bot-id",
211
+ reference: { graphChatId: "19:dm-chat@thread.tacv2" },
212
+ });
213
+ mockState.fetchGraphJson.mockResolvedValue({ value: [] });
214
+
215
+ await searchMessagesMSTeams({
216
+ cfg: {} as KlawConfig,
217
+ to: "user:aad-user-1",
218
+ query: "hello",
219
+ });
220
+
221
+ expect(mockState.findPreferredDmByUserId).toHaveBeenCalledWith("aad-user-1");
222
+ const calledPath = readFirstGraphPath();
223
+ expect(calledPath).toContain(
224
+ `/chats/${encodeURIComponent("19:dm-chat@thread.tacv2")}/messages?`,
225
+ );
226
+ });
227
+ });
@@ -0,0 +1,50 @@
1
+ import { beforeEach, vi } from "vitest";
2
+
3
+ const graphMessagesMockState = vi.hoisted(() => ({
4
+ resolveGraphToken: vi.fn(),
5
+ fetchGraphJson: vi.fn(),
6
+ fetchGraphAbsoluteUrl: vi.fn(),
7
+ postGraphJson: vi.fn(),
8
+ postGraphBetaJson: vi.fn(),
9
+ deleteGraphRequest: vi.fn(),
10
+ findPreferredDmByUserId: vi.fn(),
11
+ }));
12
+
13
+ vi.mock("./graph.js", () => {
14
+ return {
15
+ resolveGraphToken: graphMessagesMockState.resolveGraphToken,
16
+ fetchGraphJson: graphMessagesMockState.fetchGraphJson,
17
+ fetchGraphAbsoluteUrl: graphMessagesMockState.fetchGraphAbsoluteUrl,
18
+ postGraphJson: graphMessagesMockState.postGraphJson,
19
+ postGraphBetaJson: graphMessagesMockState.postGraphBetaJson,
20
+ deleteGraphRequest: graphMessagesMockState.deleteGraphRequest,
21
+ escapeOData: vi.fn((value: string) => value.replaceAll("'", "''")),
22
+ };
23
+ });
24
+
25
+ vi.mock("./conversation-store-fs.js", () => ({
26
+ createMSTeamsConversationStoreFs: () => ({
27
+ findPreferredDmByUserId: graphMessagesMockState.findPreferredDmByUserId,
28
+ }),
29
+ }));
30
+
31
+ export const TOKEN = "test-graph-token";
32
+ export const CHAT_ID = "19:abc@thread.tacv2";
33
+ export const CHANNEL_TO = "team-id-1/channel-id-1";
34
+
35
+ export function getGraphMessagesMockState(): typeof graphMessagesMockState {
36
+ return graphMessagesMockState;
37
+ }
38
+
39
+ export type GraphMessagesTestModule = typeof import("./graph-messages.js");
40
+
41
+ export function loadGraphMessagesTestModule(): Promise<GraphMessagesTestModule> {
42
+ return import("./graph-messages.js");
43
+ }
44
+
45
+ export function installGraphMessagesMockDefaults(): void {
46
+ beforeEach(() => {
47
+ vi.clearAllMocks();
48
+ graphMessagesMockState.resolveGraphToken.mockResolvedValue(TOKEN);
49
+ });
50
+ }