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