@photon-ai/advanced-imessage-kit 1.1.4 → 1.2.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/README.md +8 -5
  2. package/dist/index.cjs +885 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +639 -0
  5. package/dist/index.d.ts +639 -6
  6. package/dist/index.js +821 -5
  7. package/dist/index.js.map +1 -1
  8. package/package.json +13 -6
  9. package/dist/events.d.ts +0 -32
  10. package/dist/events.d.ts.map +0 -1
  11. package/dist/events.js +0 -32
  12. package/dist/events.js.map +0 -1
  13. package/dist/index.d.ts.map +0 -1
  14. package/dist/lib/Loggable.d.ts +0 -16
  15. package/dist/lib/Loggable.d.ts.map +0 -1
  16. package/dist/lib/Loggable.js +0 -34
  17. package/dist/lib/Loggable.js.map +0 -1
  18. package/dist/lib/Logger.d.ts +0 -18
  19. package/dist/lib/Logger.d.ts.map +0 -1
  20. package/dist/lib/Logger.js +0 -77
  21. package/dist/lib/Logger.js.map +0 -1
  22. package/dist/mobai.d.ts +0 -44
  23. package/dist/mobai.d.ts.map +0 -1
  24. package/dist/mobai.js +0 -176
  25. package/dist/mobai.js.map +0 -1
  26. package/dist/modules/attachment.d.ts +0 -24
  27. package/dist/modules/attachment.d.ts.map +0 -1
  28. package/dist/modules/attachment.js +0 -88
  29. package/dist/modules/attachment.js.map +0 -1
  30. package/dist/modules/chat.d.ts +0 -55
  31. package/dist/modules/chat.d.ts.map +0 -1
  32. package/dist/modules/chat.js +0 -100
  33. package/dist/modules/chat.js.map +0 -1
  34. package/dist/modules/contact.d.ts +0 -10
  35. package/dist/modules/contact.d.ts.map +0 -1
  36. package/dist/modules/contact.js +0 -23
  37. package/dist/modules/contact.js.map +0 -1
  38. package/dist/modules/facetime.d.ts +0 -7
  39. package/dist/modules/facetime.d.ts.map +0 -1
  40. package/dist/modules/facetime.js +0 -10
  41. package/dist/modules/facetime.js.map +0 -1
  42. package/dist/modules/handle.d.ts +0 -24
  43. package/dist/modules/handle.d.ts.map +0 -1
  44. package/dist/modules/handle.js +0 -40
  45. package/dist/modules/handle.js.map +0 -1
  46. package/dist/modules/icloud.d.ts +0 -10
  47. package/dist/modules/icloud.d.ts.map +0 -1
  48. package/dist/modules/icloud.js +0 -20
  49. package/dist/modules/icloud.js.map +0 -1
  50. package/dist/modules/index.d.ts +0 -10
  51. package/dist/modules/index.d.ts.map +0 -1
  52. package/dist/modules/index.js +0 -10
  53. package/dist/modules/index.js.map +0 -1
  54. package/dist/modules/message.d.ts +0 -72
  55. package/dist/modules/message.d.ts.map +0 -1
  56. package/dist/modules/message.js +0 -108
  57. package/dist/modules/message.js.map +0 -1
  58. package/dist/modules/scheduled.d.ts +0 -10
  59. package/dist/modules/scheduled.d.ts.map +0 -1
  60. package/dist/modules/scheduled.js +0 -21
  61. package/dist/modules/scheduled.js.map +0 -1
  62. package/dist/modules/server.d.ts +0 -17
  63. package/dist/modules/server.d.ts.map +0 -1
  64. package/dist/modules/server.js +0 -46
  65. package/dist/modules/server.js.map +0 -1
  66. package/dist/types/attachment.d.ts +0 -37
  67. package/dist/types/attachment.d.ts.map +0 -1
  68. package/dist/types/attachment.js +0 -2
  69. package/dist/types/attachment.js.map +0 -1
  70. package/dist/types/chat.d.ts +0 -25
  71. package/dist/types/chat.d.ts.map +0 -1
  72. package/dist/types/chat.js +0 -2
  73. package/dist/types/chat.js.map +0 -1
  74. package/dist/types/client.d.ts +0 -5
  75. package/dist/types/client.d.ts.map +0 -1
  76. package/dist/types/client.js +0 -2
  77. package/dist/types/client.js.map +0 -1
  78. package/dist/types/events.d.ts +0 -71
  79. package/dist/types/events.d.ts.map +0 -1
  80. package/dist/types/events.js +0 -2
  81. package/dist/types/events.js.map +0 -1
  82. package/dist/types/facetime.d.ts +0 -16
  83. package/dist/types/facetime.d.ts.map +0 -1
  84. package/dist/types/facetime.js +0 -2
  85. package/dist/types/facetime.js.map +0 -1
  86. package/dist/types/findmy.d.ts +0 -12
  87. package/dist/types/findmy.d.ts.map +0 -1
  88. package/dist/types/findmy.js +0 -2
  89. package/dist/types/findmy.js.map +0 -1
  90. package/dist/types/handle.d.ts +0 -16
  91. package/dist/types/handle.d.ts.map +0 -1
  92. package/dist/types/handle.js +0 -2
  93. package/dist/types/handle.js.map +0 -1
  94. package/dist/types/index.d.ts +0 -13
  95. package/dist/types/index.d.ts.map +0 -1
  96. package/dist/types/index.js +0 -13
  97. package/dist/types/index.js.map +0 -1
  98. package/dist/types/message.d.ts +0 -101
  99. package/dist/types/message.d.ts.map +0 -1
  100. package/dist/types/message.js +0 -2
  101. package/dist/types/message.js.map +0 -1
  102. package/dist/types/scheduled.d.ts +0 -10
  103. package/dist/types/scheduled.d.ts.map +0 -1
  104. package/dist/types/scheduled.js +0 -2
  105. package/dist/types/scheduled.js.map +0 -1
  106. package/dist/types/server.d.ts +0 -24
  107. package/dist/types/server.d.ts.map +0 -1
  108. package/dist/types/server.js +0 -2
  109. package/dist/types/server.js.map +0 -1
  110. package/dist/types/sticker.d.ts +0 -7
  111. package/dist/types/sticker.d.ts.map +0 -1
  112. package/dist/types/sticker.js +0 -2
  113. package/dist/types/sticker.js.map +0 -1
  114. package/dist/types/tapback.d.ts +0 -3
  115. package/dist/types/tapback.d.ts.map +0 -1
  116. package/dist/types/tapback.js +0 -2
  117. package/dist/types/tapback.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,6 +1,822 @@
1
- import "reflect-metadata";
2
- export * from "./events";
3
- export { getLogger, setGlobalLogLevel } from "./lib/Loggable";
4
- export { AdvancedIMessageKit, SDK } from "./mobai";
5
- export * from "./types";
1
+ import 'reflect-metadata';
2
+ import EventEmitter$1, { EventEmitter } from 'events';
3
+ import axios from 'axios';
4
+ import io from 'socket.io-client';
5
+ import * as fs from 'fs';
6
+ import * as os from 'os';
7
+ import * as path from 'path';
8
+ import path__default from 'path';
9
+ import { randomUUID } from 'crypto';
10
+ import { readFile } from 'fs/promises';
11
+ import FormData from 'form-data';
12
+
13
+ var __defProp = Object.defineProperty;
14
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
16
+ var Logger = class extends EventEmitter$1 {
17
+ constructor(tag, level = "info", logToFile = true) {
18
+ super();
19
+ __publicField(this, "tag");
20
+ __publicField(this, "logLevel", "info");
21
+ __publicField(this, "logFile");
22
+ this.tag = tag;
23
+ this.logLevel = level;
24
+ if (logToFile) {
25
+ const logDir = path.join(os.homedir(), "Library", "Logs", "AdvancedIMessageKit");
26
+ if (!fs.existsSync(logDir)) {
27
+ fs.mkdirSync(logDir, { recursive: true });
28
+ }
29
+ this.logFile = path.join(logDir, "sdk.log");
30
+ }
31
+ }
32
+ setLogLevel(level) {
33
+ this.logLevel = level;
34
+ }
35
+ shouldLog(level) {
36
+ const levels = ["debug", "info", "warn", "error"];
37
+ const currentIndex = levels.indexOf(this.logLevel);
38
+ const messageIndex = levels.indexOf(level);
39
+ return messageIndex >= currentIndex;
40
+ }
41
+ formatMessage(level, message) {
42
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
43
+ return `[${timestamp}][${level.toUpperCase()}][${this.tag}] ${message}`;
44
+ }
45
+ writeLog(level, message) {
46
+ if (!this.shouldLog(level)) return;
47
+ const formatted = this.formatMessage(level, message);
48
+ switch (level) {
49
+ case "error":
50
+ console.error(formatted);
51
+ break;
52
+ case "warn":
53
+ console.warn(formatted);
54
+ break;
55
+ case "debug":
56
+ console.debug(formatted);
57
+ break;
58
+ default:
59
+ console.log(formatted);
60
+ }
61
+ if (this.logFile) {
62
+ try {
63
+ fs.appendFileSync(this.logFile, `${formatted}
64
+ `);
65
+ } catch {
66
+ }
67
+ }
68
+ this.emit("log", { level, message, tag: this.tag });
69
+ }
70
+ info(message) {
71
+ this.writeLog("info", message);
72
+ }
73
+ debug(message) {
74
+ this.writeLog("debug", message);
75
+ }
76
+ error(message) {
77
+ const msg = message instanceof Error ? message.message : message;
78
+ this.writeLog("error", msg);
79
+ if (message instanceof Error && message.stack) {
80
+ this.writeLog("error", message.stack);
81
+ }
82
+ }
83
+ warn(message) {
84
+ this.writeLog("warn", message);
85
+ }
86
+ log(message, level = "info") {
87
+ this.writeLog(level, message);
88
+ }
89
+ };
90
+
91
+ // lib/Loggable.ts
92
+ var loggers = {};
93
+ var globalLogLevel = "info";
94
+ var setGlobalLogLevel = (level) => {
95
+ globalLogLevel = level;
96
+ Object.values(loggers).forEach((logger) => {
97
+ logger.setLogLevel(level);
98
+ });
99
+ };
100
+ var getLogger = (tag) => {
101
+ let logger = loggers[tag];
102
+ if (!logger) {
103
+ logger = new Logger(tag, globalLogLevel);
104
+ loggers[tag] = logger;
105
+ }
106
+ return logger;
107
+ };
108
+ var AttachmentModule = class {
109
+ constructor(http, enqueueSend = (task) => task()) {
110
+ this.http = http;
111
+ this.enqueueSend = enqueueSend;
112
+ }
113
+ async getAttachmentCount() {
114
+ const response = await this.http.get("/api/v1/attachment/count");
115
+ return response.data.data.total;
116
+ }
117
+ async getAttachment(guid) {
118
+ const response = await this.http.get(`/api/v1/attachment/${guid}`);
119
+ return response.data.data;
120
+ }
121
+ async downloadAttachment(guid, options) {
122
+ const params = {};
123
+ if (options?.original !== void 0) params.original = options.original;
124
+ if (options?.force !== void 0) params.force = options.force;
125
+ if (options?.height !== void 0) params.height = options.height;
126
+ if (options?.width !== void 0) params.width = options.width;
127
+ if (options?.quality !== void 0) params.quality = options.quality;
128
+ const response = await this.http.get(`/api/v1/attachment/${guid}/download`, {
129
+ params,
130
+ responseType: "arraybuffer"
131
+ });
132
+ return Buffer.from(response.data);
133
+ }
134
+ async downloadAttachmentLive(guid) {
135
+ const response = await this.http.get(`/api/v1/attachment/${guid}/live`, {
136
+ responseType: "arraybuffer"
137
+ });
138
+ return Buffer.from(response.data);
139
+ }
140
+ async getAttachmentBlurhash(guid, options) {
141
+ const params = {};
142
+ if (options?.height !== void 0) params.height = options.height;
143
+ if (options?.width !== void 0) params.width = options.width;
144
+ if (options?.quality !== void 0) params.quality = options.quality;
145
+ const response = await this.http.get(`/api/v1/attachment/${guid}/blurhash`, {
146
+ params
147
+ });
148
+ return response.data.data.blurhash;
149
+ }
150
+ async sendAttachment(options) {
151
+ return this.enqueueSend(async () => {
152
+ const fileBuffer = await readFile(options.filePath);
153
+ const fileName = options.fileName || path__default.basename(options.filePath);
154
+ const form = new FormData();
155
+ form.append("chatGuid", options.chatGuid);
156
+ form.append("attachment", fileBuffer, fileName);
157
+ form.append("name", fileName);
158
+ form.append("tempGuid", randomUUID());
159
+ if (options.isAudioMessage !== void 0) {
160
+ form.append("isAudioMessage", options.isAudioMessage.toString());
161
+ if (options.isAudioMessage) {
162
+ form.append("method", "private-api");
163
+ }
164
+ }
165
+ const response = await this.http.post("/api/v1/message/attachment", form, {
166
+ headers: form.getHeaders()
167
+ });
168
+ return response.data.data;
169
+ });
170
+ }
171
+ async sendSticker(options) {
172
+ return this.enqueueSend(async () => {
173
+ const fileName = options.fileName || path__default.basename(options.filePath);
174
+ const form = new FormData();
175
+ form.append("attachment", await readFile(options.filePath), fileName);
176
+ const { data } = await this.http.post("/api/v1/attachment/upload", form, {
177
+ headers: form.getHeaders()
178
+ });
179
+ const response = await this.http.post("/api/v1/message/multipart", {
180
+ chatGuid: options.chatGuid,
181
+ selectedMessageGuid: options.selectedMessageGuid,
182
+ parts: [{ partIndex: 0, attachment: data.data.path, name: fileName }]
183
+ });
184
+ return response.data.data;
185
+ });
186
+ }
187
+ };
188
+ var ChatModule = class {
189
+ constructor(http) {
190
+ this.http = http;
191
+ }
192
+ async getChats(options) {
193
+ const response = await this.http.post("/api/v1/chat/query", options ?? {});
194
+ return response.data.data;
195
+ }
196
+ async createChat(options) {
197
+ const response = await this.http.post("/api/v1/chat/new", options);
198
+ return response.data.data;
199
+ }
200
+ async getChat(guid, options) {
201
+ const response = await this.http.get(`/api/v1/chat/${guid}`, {
202
+ params: options?.with ? { with: options.with.join(",") } : {}
203
+ });
204
+ return response.data.data;
205
+ }
206
+ async updateChat(guid, options) {
207
+ const response = await this.http.put(`/api/v1/chat/${guid}`, options);
208
+ return response.data.data;
209
+ }
210
+ async deleteChat(guid) {
211
+ await this.http.delete(`/api/v1/chat/${guid}`);
212
+ }
213
+ async markChatRead(guid) {
214
+ await this.http.post(`/api/v1/chat/${guid}/read`);
215
+ }
216
+ async markChatUnread(guid) {
217
+ await this.http.post(`/api/v1/chat/${guid}/unread`);
218
+ }
219
+ async leaveChat(guid) {
220
+ await this.http.post(`/api/v1/chat/${guid}/leave`);
221
+ }
222
+ async addParticipant(chatGuid, address) {
223
+ const response = await this.http.post(`/api/v1/chat/${chatGuid}/participant`, {
224
+ address
225
+ });
226
+ return response.data.data;
227
+ }
228
+ async removeParticipant(chatGuid, address) {
229
+ const response = await this.http.delete(`/api/v1/chat/${chatGuid}/participant`, {
230
+ data: { address }
231
+ });
232
+ return response.data.data;
233
+ }
234
+ async getChatMessages(chatGuid, options) {
235
+ const params = {};
236
+ if (options?.offset !== void 0) params.offset = options.offset;
237
+ if (options?.limit !== void 0) params.limit = options.limit;
238
+ if (options?.sort) params.sort = options.sort;
239
+ if (options?.before !== void 0) params.before = options.before;
240
+ if (options?.after !== void 0) params.after = options.after;
241
+ if (options?.with) params.with = options.with.join(",");
242
+ const response = await this.http.get(`/api/v1/chat/${chatGuid}/message`, {
243
+ params
244
+ });
245
+ return response.data.data;
246
+ }
247
+ async setGroupIcon(chatGuid, filePath) {
248
+ const fileBuffer = await readFile(filePath);
249
+ const fileName = path__default.basename(filePath);
250
+ const form = new FormData();
251
+ form.append("icon", fileBuffer, fileName);
252
+ await this.http.post(`/api/v1/chat/${chatGuid}/icon`, form, {
253
+ headers: form.getHeaders()
254
+ });
255
+ }
256
+ async removeGroupIcon(chatGuid) {
257
+ await this.http.delete(`/api/v1/chat/${chatGuid}/icon`);
258
+ }
259
+ async getGroupIcon(chatGuid) {
260
+ const response = await this.http.get(`/api/v1/chat/${chatGuid}/icon`, {
261
+ responseType: "arraybuffer"
262
+ });
263
+ return Buffer.from(response.data);
264
+ }
265
+ async getChatCount(options) {
266
+ const response = await this.http.get("/api/v1/chat/count", {
267
+ params: options?.includeArchived !== void 0 ? { includeArchived: options.includeArchived } : {}
268
+ });
269
+ return response.data.data;
270
+ }
271
+ async startTyping(chatGuid) {
272
+ await this.http.post(`/api/v1/chat/${chatGuid}/typing`);
273
+ }
274
+ async stopTyping(chatGuid) {
275
+ await this.http.delete(`/api/v1/chat/${chatGuid}/typing`);
276
+ }
277
+ };
278
+
279
+ // modules/contact.ts
280
+ var ContactModule = class {
281
+ constructor(http) {
282
+ this.http = http;
283
+ }
284
+ async getContacts() {
285
+ const response = await this.http.get("/api/v1/contact");
286
+ return response.data.data;
287
+ }
288
+ async getContactCard(address) {
289
+ const response = await this.http.get("/api/v1/icloud/contact", {
290
+ params: { address }
291
+ });
292
+ return response.data.data;
293
+ }
294
+ async shareContactCard(chatGuid) {
295
+ await this.http.post(`/api/v1/chat/${chatGuid}/share/contact`);
296
+ }
297
+ async shouldShareContact(chatGuid) {
298
+ const response = await this.http.get(`/api/v1/chat/${chatGuid}/share/contact/status`);
299
+ return response.data.data;
300
+ }
301
+ };
302
+
303
+ // modules/facetime.ts
304
+ var FaceTimeModule = class {
305
+ constructor(http) {
306
+ this.http = http;
307
+ }
308
+ async createFaceTimeLink() {
309
+ const response = await this.http.post("/api/v1/facetime/session");
310
+ return response.data.data;
311
+ }
312
+ };
313
+
314
+ // modules/handle.ts
315
+ var HandleModule = class {
316
+ constructor(http) {
317
+ this.http = http;
318
+ }
319
+ async getHandleCount() {
320
+ const response = await this.http.get("/api/v1/handle/count");
321
+ return response.data.data.total;
322
+ }
323
+ async queryHandles(options) {
324
+ const body = {};
325
+ if (options?.address) body.address = options.address;
326
+ if (options?.with) body.with = options.with.join(",");
327
+ if (options?.offset !== void 0) body.offset = options.offset;
328
+ if (options?.limit !== void 0) body.limit = options.limit;
329
+ const response = await this.http.post("/api/v1/handle/query", body);
330
+ return {
331
+ data: response.data.data,
332
+ metadata: response.data.metadata
333
+ };
334
+ }
335
+ async getHandle(guid) {
336
+ const response = await this.http.get(`/api/v1/handle/${guid}`);
337
+ return response.data.data;
338
+ }
339
+ async getHandleAvailability(address, type) {
340
+ const response = await this.http.get(`/api/v1/handle/availability/${type}`, {
341
+ params: { address }
342
+ });
343
+ return response.data.data.available;
344
+ }
345
+ async getHandleFocusStatus(guid) {
346
+ const response = await this.http.get(`/api/v1/handle/${guid}/focus`);
347
+ return response.data.data.status;
348
+ }
349
+ };
350
+
351
+ // modules/icloud.ts
352
+ var ICloudModule = class {
353
+ constructor(http) {
354
+ this.http = http;
355
+ }
356
+ async getFindMyFriends() {
357
+ const response = await this.http.get("/api/v1/icloud/findmy/friends");
358
+ return response.data.data;
359
+ }
360
+ async refreshFindMyFriends() {
361
+ await this.http.post("/api/v1/icloud/findmy/friends/refresh");
362
+ }
363
+ };
364
+
365
+ // lib/auto-create-chat.ts
366
+ function isChatNotExistError(error) {
367
+ const axiosError = error;
368
+ const errorMsg = axiosError?.response?.data?.error?.message || axiosError?.response?.data?.message || "";
369
+ const lowerMsg = errorMsg.toLowerCase();
370
+ return lowerMsg.includes("chat does not exist") || lowerMsg.includes("chat not found");
371
+ }
372
+ function extractAddress(chatGuid) {
373
+ const parts = chatGuid.split(";-;");
374
+ if (parts.length !== 2 || !parts[1]) {
375
+ return void 0;
376
+ }
377
+ return parts[1];
378
+ }
379
+ async function createChatWithMessage(options) {
380
+ const { http, address, message, tempGuid, subject, effectId } = options;
381
+ try {
382
+ const response = await http.post("/api/v1/chat/new", {
383
+ addresses: [address],
384
+ message,
385
+ tempGuid,
386
+ subject,
387
+ effectId
388
+ });
389
+ return response.data.data?.guid;
390
+ } catch (error) {
391
+ throw new Error(
392
+ `Failed to create chat with address "${address}": ${error instanceof Error ? error.message : String(error)}`
393
+ );
394
+ }
395
+ }
396
+
397
+ // modules/message.ts
398
+ var MessageModule = class {
399
+ constructor(http, enqueueSend = (task) => task()) {
400
+ this.http = http;
401
+ this.enqueueSend = enqueueSend;
402
+ }
403
+ async sendMessage(options) {
404
+ return this.enqueueSend(async () => {
405
+ const tempGuid = options.tempGuid || randomUUID();
406
+ const payload = { ...options, tempGuid };
407
+ try {
408
+ const response = await this.http.post("/api/v1/message/text", payload);
409
+ return response.data.data;
410
+ } catch (error) {
411
+ if (!isChatNotExistError(error)) throw error;
412
+ const address = extractAddress(options.chatGuid);
413
+ if (!address) throw error;
414
+ await createChatWithMessage({
415
+ http: this.http,
416
+ address,
417
+ message: options.message,
418
+ tempGuid,
419
+ subject: options.subject,
420
+ effectId: options.effectId
421
+ });
422
+ return { guid: tempGuid, text: options.message, dateCreated: Date.now() };
423
+ }
424
+ });
425
+ }
426
+ async getMessage(guid, options) {
427
+ const response = await this.http.get(`/api/v1/message/${guid}`, {
428
+ params: options?.with ? { with: options.with.join(",") } : {}
429
+ });
430
+ return response.data.data;
431
+ }
432
+ async getMessages(options) {
433
+ const response = await this.http.post("/api/v1/message/query", options ?? {});
434
+ return response.data.data;
435
+ }
436
+ async getMessageCount(options) {
437
+ const params = {};
438
+ if (options?.after !== void 0) params.after = options.after;
439
+ if (options?.before !== void 0) params.before = options.before;
440
+ if (options?.chatGuid) params.chatGuid = options.chatGuid;
441
+ if (options?.minRowId !== void 0) params.minRowId = options.minRowId;
442
+ if (options?.maxRowId !== void 0) params.maxRowId = options.maxRowId;
443
+ const response = await this.http.get("/api/v1/message/count", { params });
444
+ return response.data.data.total;
445
+ }
446
+ async getUpdatedMessageCount(options) {
447
+ const params = {};
448
+ if (options?.after !== void 0) params.after = options.after;
449
+ if (options?.before !== void 0) params.before = options.before;
450
+ if (options?.chatGuid) params.chatGuid = options.chatGuid;
451
+ if (options?.minRowId !== void 0) params.minRowId = options.minRowId;
452
+ if (options?.maxRowId !== void 0) params.maxRowId = options.maxRowId;
453
+ const response = await this.http.get("/api/v1/message/count/updated", {
454
+ params
455
+ });
456
+ return response.data.data.total;
457
+ }
458
+ async getSentMessageCount(options) {
459
+ const params = {};
460
+ if (options?.after !== void 0) params.after = options.after;
461
+ if (options?.before !== void 0) params.before = options.before;
462
+ if (options?.chatGuid) params.chatGuid = options.chatGuid;
463
+ if (options?.minRowId !== void 0) params.minRowId = options.minRowId;
464
+ if (options?.maxRowId !== void 0) params.maxRowId = options.maxRowId;
465
+ const response = await this.http.get("/api/v1/message/count/me", {
466
+ params
467
+ });
468
+ return response.data.data.total;
469
+ }
470
+ async editMessage(options) {
471
+ return this.enqueueSend(async () => {
472
+ const response = await this.http.post(`/api/v1/message/${options.messageGuid}/edit`, {
473
+ editedMessage: options.editedMessage,
474
+ backwardsCompatibilityMessage: options.backwardsCompatibilityMessage || options.editedMessage,
475
+ partIndex: options.partIndex ?? 0
476
+ });
477
+ return response.data.data;
478
+ });
479
+ }
480
+ async sendReaction(options) {
481
+ return this.enqueueSend(async () => {
482
+ const response = await this.http.post("/api/v1/message/react", {
483
+ chatGuid: options.chatGuid,
484
+ selectedMessageGuid: options.messageGuid,
485
+ reaction: options.reaction,
486
+ partIndex: options.partIndex ?? 0
487
+ });
488
+ return response.data.data;
489
+ });
490
+ }
491
+ async unsendMessage(options) {
492
+ return this.enqueueSend(async () => {
493
+ const response = await this.http.post(`/api/v1/message/${options.messageGuid}/unsend`, {
494
+ partIndex: options.partIndex ?? 0
495
+ });
496
+ return response.data.data;
497
+ });
498
+ }
499
+ async notifyMessage(guid) {
500
+ await this.http.post(`/api/v1/message/${guid}/notify`);
501
+ }
502
+ async getEmbeddedMedia(guid) {
503
+ const response = await this.http.get(`/api/v1/message/${guid}/embedded-media`);
504
+ return response.data.data;
505
+ }
506
+ async searchMessages(options) {
507
+ const response = await this.http.post("/api/v1/message/search", options);
508
+ return response.data.data;
509
+ }
510
+ };
511
+
512
+ // modules/scheduled.ts
513
+ var ScheduledMessageModule = class {
514
+ constructor(http) {
515
+ this.http = http;
516
+ }
517
+ async createScheduledMessage(options) {
518
+ const response = await this.http.post("/api/v1/message/schedule", options);
519
+ return response.data.data;
520
+ }
521
+ async getScheduledMessages() {
522
+ const response = await this.http.get("/api/v1/message/schedule");
523
+ return response.data.data;
524
+ }
525
+ async updateScheduledMessage(id, options) {
526
+ const response = await this.http.put(`/api/v1/message/schedule/${id}`, options);
527
+ return response.data.data;
528
+ }
529
+ async deleteScheduledMessage(id) {
530
+ await this.http.delete(`/api/v1/message/schedule/${id}`);
531
+ }
532
+ };
533
+
534
+ // modules/server.ts
535
+ var ServerModule = class {
536
+ constructor(http) {
537
+ this.http = http;
538
+ }
539
+ async getServerInfo() {
540
+ const response = await this.http.get("/api/v1/server/info");
541
+ return response.data.data;
542
+ }
543
+ async getMessageStats() {
544
+ const response = await this.http.get("/api/v1/server/statistics/totals");
545
+ return response.data.data;
546
+ }
547
+ async getServerLogs(count) {
548
+ const response = await this.http.get("/api/v1/server/logs", {
549
+ params: count !== void 0 ? { count } : {}
550
+ });
551
+ return response.data.data;
552
+ }
553
+ async getAlerts() {
554
+ const response = await this.http.get("/api/v1/server/alert");
555
+ return response.data.data;
556
+ }
557
+ async markAlertAsRead(ids) {
558
+ const response = await this.http.post("/api/v1/server/alert/read", { ids });
559
+ return response.data.data;
560
+ }
561
+ async getMediaStatistics(options) {
562
+ const params = {};
563
+ if (options?.only) params.only = options.only.join(",");
564
+ const response = await this.http.get("/api/v1/server/statistics/media", {
565
+ params
566
+ });
567
+ return response.data.data;
568
+ }
569
+ async getMediaStatisticsByChat(options) {
570
+ const params = {};
571
+ if (options?.only) params.only = options.only.join(",");
572
+ const response = await this.http.get("/api/v1/server/statistics/media/chat", {
573
+ params
574
+ });
575
+ return response.data.data;
576
+ }
577
+ };
578
+
579
+ // client.ts
580
+ var _AdvancedIMessageKit = class _AdvancedIMessageKit extends EventEmitter {
581
+ constructor(config = {}) {
582
+ super();
583
+ // Core
584
+ __publicField(this, "config");
585
+ __publicField(this, "logger", getLogger("AdvancedIMessageKit"));
586
+ __publicField(this, "http");
587
+ __publicField(this, "socket");
588
+ __publicField(this, "attachments");
589
+ __publicField(this, "messages");
590
+ __publicField(this, "chats");
591
+ __publicField(this, "contacts");
592
+ __publicField(this, "handles");
593
+ __publicField(this, "facetime");
594
+ __publicField(this, "icloud");
595
+ __publicField(this, "scheduledMessages");
596
+ __publicField(this, "server");
597
+ // Message deduplication feature
598
+ //
599
+ // Purpose: Prevent message reply loops caused by server repeatedly pushing
600
+ // the same message content with different GUIDs due to unstable Socket.IO connections.
601
+ // This is especially problematic when the polling transport causes connection issues.
602
+ __publicField(this, "processedMessages", /* @__PURE__ */ new Set());
603
+ // Send queue for sequential message delivery
604
+ //
605
+ // Purpose: Ensure all outgoing messages (text, attachments, stickers, etc.) from
606
+ // a single user/SDK instance are sent in strict order, preventing race conditions.
607
+ __publicField(this, "sendQueue", Promise.resolve());
608
+ this.config = {
609
+ serverUrl: "http://localhost:1234",
610
+ logLevel: "info",
611
+ ...config
612
+ };
613
+ if (this.config.logLevel) {
614
+ setGlobalLogLevel(this.config.logLevel);
615
+ }
616
+ this.http = axios.create({
617
+ baseURL: this.config.serverUrl,
618
+ headers: this.config.apiKey ? { "X-API-Key": this.config.apiKey } : void 0
619
+ });
620
+ this.socket = io(this.config.serverUrl, {
621
+ auth: this.config.apiKey ? { apiKey: this.config.apiKey } : void 0,
622
+ // 🚨 IMPORTANT: Polling transport configuration notes
623
+ //
624
+ // Root cause analysis:
625
+ // 1. Socket.IO 'polling' transport can cause unstable connections in certain network environments
626
+ // 2. When "xhr poll error" occurs, Socket.IO attempts to reconnect
627
+ // 3. During reconnection, the server may repeatedly push the same message with different GUIDs
628
+ // 4. This is not simple client-side duplicate processing, but server-side message duplication
629
+ //
630
+ // Solutions:
631
+ // - Prioritize WebSocket transport, fallback to polling as backup
632
+ // - Set reasonable timeout to avoid frequent reconnections
633
+ // - Use forceNew to ensure fresh connections and avoid state pollution
634
+ // - Implement client-side message deduplication as the last line of defense
635
+ transports: ["websocket"],
636
+ // Only WebSocket - polling disabled to prevent message duplication
637
+ timeout: 1e4,
638
+ // 10 second timeout to avoid overly frequent reconnections
639
+ forceNew: true
640
+ // Force new connection to avoid connection state pollution
641
+ });
642
+ const enqueueSend = this.enqueueSend.bind(this);
643
+ this.attachments = new AttachmentModule(this.http, enqueueSend);
644
+ this.messages = new MessageModule(this.http, enqueueSend);
645
+ this.chats = new ChatModule(this.http);
646
+ this.contacts = new ContactModule(this.http);
647
+ this.handles = new HandleModule(this.http);
648
+ this.facetime = new FaceTimeModule(this.http);
649
+ this.icloud = new ICloudModule(this.http);
650
+ this.scheduledMessages = new ScheduledMessageModule(this.http);
651
+ this.server = new ServerModule(this.http);
652
+ }
653
+ static getInstance(config) {
654
+ const existing = _AdvancedIMessageKit.getGlobalSdk();
655
+ if (existing) return existing;
656
+ const instance = new _AdvancedIMessageKit(config);
657
+ _AdvancedIMessageKit.setGlobalSdk(instance);
658
+ return instance;
659
+ }
660
+ emit(event, ...args) {
661
+ return super.emit(event, ...args);
662
+ }
663
+ on(event, listener) {
664
+ return super.on(event, listener);
665
+ }
666
+ once(event, listener) {
667
+ return super.once(event, listener);
668
+ }
669
+ off(event, listener) {
670
+ return super.off(event, listener);
671
+ }
672
+ addListener(event, listener) {
673
+ return super.addListener(event, listener);
674
+ }
675
+ removeListener(event, listener) {
676
+ return super.removeListener(event, listener);
677
+ }
678
+ async connect() {
679
+ const serverEvents = [
680
+ "new-message",
681
+ "message-updated",
682
+ "updated-message",
683
+ "chat-read-status-changed",
684
+ "group-name-change",
685
+ "participant-added",
686
+ "participant-removed",
687
+ "participant-left",
688
+ "group-icon-changed",
689
+ "group-icon-removed",
690
+ "message-send-error",
691
+ "typing-indicator",
692
+ "new-server",
693
+ "incoming-facetime",
694
+ "ft-call-status-changed",
695
+ "hello-world"
696
+ ];
697
+ for (const eventName of serverEvents) {
698
+ this.socket.on(eventName, (...args) => {
699
+ if (eventName === "new-message" && args.length > 0) {
700
+ const message = args[0];
701
+ if (message?.guid) {
702
+ if (this.processedMessages.has(message.guid)) {
703
+ this.logger.debug(`Message already processed, skipping duplicate: ${message.guid}`);
704
+ return;
705
+ }
706
+ this.processedMessages.add(message.guid);
707
+ }
708
+ }
709
+ if (args.length > 0) {
710
+ super.emit(eventName, args[0]);
711
+ } else {
712
+ super.emit(eventName);
713
+ }
714
+ });
715
+ }
716
+ this.socket.on("disconnect", () => {
717
+ this.logger.info("Disconnected from iMessage server");
718
+ this.emit("disconnect");
719
+ });
720
+ this.socket.on("auth-ok", () => {
721
+ this.logger.info("Authentication successful");
722
+ this.emit("ready");
723
+ });
724
+ this.socket.on("auth-error", (error) => {
725
+ this.logger.error(`Authentication failed: ${error.message} ${error.reason ? `(${error.reason})` : ""}`);
726
+ this.emit("error", new Error(`Authentication failed: ${error.message}`));
727
+ });
728
+ if (this.socket.connected) {
729
+ this.logger.info("Already connected to iMessage server");
730
+ return;
731
+ }
732
+ this.socket.once("connect", () => {
733
+ this.logger.info("Connected to iMessage server, waiting for authentication...");
734
+ if (!this.config.apiKey) {
735
+ this.logger.info("No API key provided, skipping authentication (legacy server mode)");
736
+ this.emit("ready");
737
+ }
738
+ });
739
+ if (!this.socket.connected) {
740
+ this.socket.connect();
741
+ }
742
+ }
743
+ async close() {
744
+ this.socket.disconnect();
745
+ }
746
+ /**
747
+ * Clear processed message records (prevent memory leaks)
748
+ * @param maxSize Maximum number of messages to retain, default 1000
749
+ */
750
+ clearProcessedMessages(maxSize = 1e3) {
751
+ if (this.processedMessages.size > maxSize) {
752
+ const messages = Array.from(this.processedMessages);
753
+ this.processedMessages.clear();
754
+ messages.slice(-Math.floor(maxSize / 2)).forEach((guid) => {
755
+ this.processedMessages.add(guid);
756
+ });
757
+ this.logger.debug(`Cleared processed message records, retained ${this.processedMessages.size} messages`);
758
+ }
759
+ }
760
+ /**
761
+ * Get the count of processed messages
762
+ */
763
+ getProcessedMessageCount() {
764
+ return this.processedMessages.size;
765
+ }
766
+ /**
767
+ * Enqueue a send operation to ensure sequential delivery.
768
+ * All send operations (messages, attachments, stickers) should use this method
769
+ * to guarantee order for a single user.
770
+ * @param task The async send operation to enqueue
771
+ * @returns Promise that resolves with the task result
772
+ */
773
+ enqueueSend(task) {
774
+ const result = this.sendQueue.then(() => task());
775
+ this.sendQueue = result.catch(() => {
776
+ });
777
+ return result;
778
+ }
779
+ };
780
+ __publicField(_AdvancedIMessageKit, "getGlobalSdk", () => globalThis.__AdvancedIMessageKit__ ?? null);
781
+ __publicField(_AdvancedIMessageKit, "setGlobalSdk", (sdk) => {
782
+ globalThis.__AdvancedIMessageKit__ = sdk;
783
+ });
784
+ var AdvancedIMessageKit = _AdvancedIMessageKit;
785
+ var SDK = AdvancedIMessageKit.getInstance;
786
+
787
+ // events.ts
788
+ var SCHEDULED_MESSAGE_ERROR = "scheduled-message-error";
789
+ var SCHEDULED_MESSAGE_SENT = "scheduled-message-sent";
790
+ var SCHEDULED_MESSAGE_DELETED = "scheduled-message-deleted";
791
+ var SCHEDULED_MESSAGE_UPDATED = "scheduled-message-updated";
792
+ var SCHEDULED_MESSAGE_CREATED = "scheduled-message-created";
793
+ var NEW_MESSAGE = "new-message";
794
+ var MESSAGE_SEND_ERROR = "message-send-error";
795
+ var MESSAGE_UPDATED = "updated-message";
796
+ var NEW_SERVER = "new-server";
797
+ var PARTICIPANT_REMOVED = "participant-removed";
798
+ var PARTICIPANT_ADDED = "participant-added";
799
+ var PARTICIPANT_LEFT = "participant-left";
800
+ var GROUP_ICON_CHANGED = "group-icon-changed";
801
+ var GROUP_ICON_REMOVED = "group-icon-removed";
802
+ var CHAT_READ_STATUS_CHANGED = "chat-read-status-changed";
803
+ var HELLO_WORLD = "hello-world";
804
+ var TYPING_INDICATOR = "typing-indicator";
805
+ var SERVER_UPDATE = "server-update";
806
+ var SERVER_UPDATE_DOWNLOADING = "server-update-downloading";
807
+ var SERVER_UPDATE_INSTALLING = "server-update-installing";
808
+ var GROUP_NAME_CHANGE = "group-name-change";
809
+ var INCOMING_FACETIME = "incoming-facetime";
810
+ var SETTINGS_BACKUP_CREATED = "settings-backup-created";
811
+ var SETTINGS_BACKUP_DELETED = "settings-backup-deleted";
812
+ var SETTINGS_BACKUP_UPDATED = "settings-backup-updated";
813
+ var THEME_BACKUP_CREATED = "theme-backup-created";
814
+ var THEME_BACKUP_DELETED = "theme-backup-deleted";
815
+ var THEME_BACKUP_UPDATED = "theme-backup-updated";
816
+ var IMESSAGE_ALIASES_REMOVED = "imessage-aliases-removed";
817
+ var FT_CALL_STATUS_CHANGED = "ft-call-status-changed";
818
+ var NEW_FINDMY_LOCATION = "new-findmy-location";
819
+
820
+ export { AdvancedIMessageKit, CHAT_READ_STATUS_CHANGED, FT_CALL_STATUS_CHANGED, GROUP_ICON_CHANGED, GROUP_ICON_REMOVED, GROUP_NAME_CHANGE, HELLO_WORLD, IMESSAGE_ALIASES_REMOVED, INCOMING_FACETIME, MESSAGE_SEND_ERROR, MESSAGE_UPDATED, NEW_FINDMY_LOCATION, NEW_MESSAGE, NEW_SERVER, PARTICIPANT_ADDED, PARTICIPANT_LEFT, PARTICIPANT_REMOVED, SCHEDULED_MESSAGE_CREATED, SCHEDULED_MESSAGE_DELETED, SCHEDULED_MESSAGE_ERROR, SCHEDULED_MESSAGE_SENT, SCHEDULED_MESSAGE_UPDATED, SDK, SERVER_UPDATE, SERVER_UPDATE_DOWNLOADING, SERVER_UPDATE_INSTALLING, SETTINGS_BACKUP_CREATED, SETTINGS_BACKUP_DELETED, SETTINGS_BACKUP_UPDATED, THEME_BACKUP_CREATED, THEME_BACKUP_DELETED, THEME_BACKUP_UPDATED, TYPING_INDICATOR, getLogger, setGlobalLogLevel };
821
+ //# sourceMappingURL=index.js.map
6
822
  //# sourceMappingURL=index.js.map