dcim-web-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,798 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DCIMUploadPlugin: () => DCIMUploadPlugin,
24
+ DEFAULT_PLATFORM_ID: () => DEFAULT_PLATFORM_ID,
25
+ EVENT: () => EVENT,
26
+ TYPES: () => TYPES,
27
+ create: () => create,
28
+ createDcimUploadProvider: () => createDcimUploadProvider,
29
+ default: () => index_default
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/constants.ts
34
+ var EVENT = {
35
+ SDK_READY: "SDK_READY",
36
+ SDK_NOT_READY: "SDK_NOT_READY",
37
+ NET_STATE_CHANGE: "NET_STATE_CHANGE",
38
+ ERROR: "ERROR",
39
+ KICKED_OUT: "KICKED_OUT",
40
+ MESSAGE_RECEIVED: "MESSAGE_RECEIVED",
41
+ MESSAGE_MODIFIED: "MESSAGE_MODIFIED"
42
+ };
43
+ var TYPES = {
44
+ CONV_C2C: "C2C"
45
+ };
46
+ var DEFAULT_PLATFORM_ID = 5;
47
+
48
+ // src/adapters/openim-client-adapter.ts
49
+ var import_client_sdk3 = require("@openim/client-sdk");
50
+
51
+ // src/emitter.ts
52
+ var SimpleEmitter = class {
53
+ constructor() {
54
+ this.listeners = /* @__PURE__ */ new Map();
55
+ }
56
+ on(eventName, listener) {
57
+ const set = this.listeners.get(eventName) ?? /* @__PURE__ */ new Set();
58
+ set.add(listener);
59
+ this.listeners.set(eventName, set);
60
+ }
61
+ off(eventName, listener) {
62
+ const set = this.listeners.get(eventName);
63
+ if (!set) return;
64
+ set.delete(listener);
65
+ if (set.size === 0) this.listeners.delete(eventName);
66
+ }
67
+ emit(eventName, payload) {
68
+ const set = this.listeners.get(eventName);
69
+ if (!set) return;
70
+ set.forEach((listener) => listener(payload));
71
+ }
72
+ clear() {
73
+ this.listeners.clear();
74
+ }
75
+ };
76
+
77
+ // src/mappers/event.ts
78
+ var import_client_sdk = require("@openim/client-sdk");
79
+ var OPENIM_TO_COMPAT_EVENT = {
80
+ [import_client_sdk.CbEvents.OnConnectSuccess]: [EVENT.SDK_READY],
81
+ [import_client_sdk.CbEvents.OnConnecting]: [EVENT.NET_STATE_CHANGE],
82
+ [import_client_sdk.CbEvents.OnConnectFailed]: [EVENT.SDK_NOT_READY, EVENT.ERROR],
83
+ [import_client_sdk.CbEvents.OnKickedOffline]: [EVENT.KICKED_OUT],
84
+ [import_client_sdk.CbEvents.OnUserTokenExpired]: [EVENT.KICKED_OUT],
85
+ [import_client_sdk.CbEvents.OnUserTokenInvalid]: [EVENT.KICKED_OUT],
86
+ [import_client_sdk.CbEvents.OnRecvNewMessage]: [EVENT.MESSAGE_RECEIVED],
87
+ [import_client_sdk.CbEvents.OnRecvNewMessages]: [EVENT.MESSAGE_RECEIVED]
88
+ };
89
+
90
+ // src/mappers/message.ts
91
+ var import_client_sdk2 = require("@openim/client-sdk");
92
+
93
+ // src/utils.ts
94
+ var createOperationID = () => {
95
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
96
+ return crypto.randomUUID();
97
+ }
98
+ return `dcim_web_sdk_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
99
+ };
100
+ var toUnixSeconds = (value) => {
101
+ if (!value) return void 0;
102
+ return value > 1e12 ? Math.floor(value / 1e3) : value;
103
+ };
104
+ var inferFileType = (fileName) => {
105
+ const index = fileName.lastIndexOf(".");
106
+ if (index < 0) return "";
107
+ return fileName.slice(index + 1).toLowerCase();
108
+ };
109
+
110
+ // src/mappers/message.ts
111
+ var mapPictureToImageInfo = (picture, type = 1) => {
112
+ if (!picture) return void 0;
113
+ return {
114
+ type,
115
+ size: picture.size ?? picture.Size,
116
+ width: picture.width ?? picture.Width,
117
+ height: picture.height ?? picture.Height,
118
+ url: picture.url ?? picture.Url
119
+ };
120
+ };
121
+ var resolvePicture = (pictureElem, kind) => {
122
+ if (!pictureElem) return void 0;
123
+ if (kind === "source") return pictureElem.sourcePicture ?? pictureElem.SourcePicture;
124
+ if (kind === "big") return pictureElem.bigPicture ?? pictureElem.BigPicture;
125
+ return pictureElem.snapshotPicture ?? pictureElem.SnapshotPicture;
126
+ };
127
+ var resolveFileField = (fileElem, kind) => {
128
+ if (!fileElem) return void 0;
129
+ if (kind === "url") return fileElem.sourceUrl ?? fileElem.sourceURL ?? fileElem.SourceUrl ?? fileElem.SourceURL;
130
+ if (kind === "name") return fileElem.fileName ?? fileElem.FileName;
131
+ return fileElem.fileSize ?? fileElem.FileSize;
132
+ };
133
+ var toOptionalString = (value) => {
134
+ if (value == null) return void 0;
135
+ return String(value);
136
+ };
137
+ var resolveTextContent = (textElem) => textElem?.content ?? textElem?.Content ?? "";
138
+ var resolveAtText = (atTextElem) => atTextElem?.text ?? atTextElem?.Text ?? "";
139
+ var mapIncomingMessage = (message) => {
140
+ const base = {
141
+ ID: message.clientMsgID,
142
+ cloudCustomData: message.ex ?? "",
143
+ time: toUnixSeconds(message.sendTime),
144
+ clientTime: toUnixSeconds(message.createTime),
145
+ conversationID: message.groupID || message.recvID || message.sendID,
146
+ _raw: message
147
+ };
148
+ switch (message.contentType) {
149
+ case import_client_sdk2.MessageType.TextMessage: {
150
+ const textElem = message.textElem;
151
+ return {
152
+ ...base,
153
+ type: "TIMTextElem",
154
+ payload: {
155
+ text: resolveTextContent(textElem)
156
+ }
157
+ };
158
+ }
159
+ case import_client_sdk2.MessageType.AtTextMessage: {
160
+ const atTextElem = message.atTextElem;
161
+ return {
162
+ ...base,
163
+ type: "TIMTextElem",
164
+ payload: {
165
+ text: resolveAtText(atTextElem)
166
+ }
167
+ };
168
+ }
169
+ case import_client_sdk2.MessageType.PictureMessage: {
170
+ const pictureElem = message.pictureElem;
171
+ const sourcePicture = resolvePicture(pictureElem, "source");
172
+ const source = mapPictureToImageInfo(sourcePicture, 1);
173
+ const big = mapPictureToImageInfo(resolvePicture(pictureElem, "big"), 2);
174
+ const snapshot = mapPictureToImageInfo(resolvePicture(pictureElem, "snapshot"), 3);
175
+ return {
176
+ ...base,
177
+ type: "TIMImageElem",
178
+ payload: {
179
+ imageInfoArray: [source, big, snapshot].filter(Boolean),
180
+ imageFormat: toOptionalString(sourcePicture?.type ?? sourcePicture?.Type)
181
+ }
182
+ };
183
+ }
184
+ case import_client_sdk2.MessageType.FileMessage: {
185
+ const fileElem = message.fileElem;
186
+ return {
187
+ ...base,
188
+ type: "TIMFileElem",
189
+ payload: {
190
+ fileUrl: toOptionalString(resolveFileField(fileElem, "url")),
191
+ fileName: toOptionalString(resolveFileField(fileElem, "name")),
192
+ fileSize: resolveFileField(fileElem, "size")
193
+ }
194
+ };
195
+ }
196
+ default:
197
+ return null;
198
+ }
199
+ };
200
+ var buildTextSendResult = (payload, raw) => ({
201
+ data: { message: { payload: { ...payload } } },
202
+ message: { payload: { ...payload } },
203
+ raw
204
+ });
205
+ var buildImageSendResult = (upload, raw) => {
206
+ const cloneImageInfoArray = () => (upload.imageInfoArray ?? []).map((item) => ({
207
+ type: item.type,
208
+ size: item.size,
209
+ width: item.width,
210
+ height: item.height,
211
+ url: item.url
212
+ }));
213
+ const payload = {
214
+ imageInfoArray: cloneImageInfoArray(),
215
+ imageFormat: upload.imageFormat,
216
+ url: upload.url
217
+ };
218
+ return {
219
+ data: {
220
+ message: {
221
+ payload: {
222
+ imageInfoArray: cloneImageInfoArray(),
223
+ imageFormat: payload.imageFormat,
224
+ url: payload.url
225
+ }
226
+ }
227
+ },
228
+ message: {
229
+ payload: {
230
+ imageInfoArray: cloneImageInfoArray(),
231
+ imageFormat: payload.imageFormat,
232
+ url: payload.url
233
+ }
234
+ },
235
+ raw
236
+ };
237
+ };
238
+ var buildFileSendResult = (upload, fileName, fileSize, raw) => {
239
+ const payload = {
240
+ fileUrl: upload.url,
241
+ url: upload.url,
242
+ fileName: upload.fileName ?? fileName,
243
+ fileSize: upload.fileSize ?? fileSize,
244
+ fileType: upload.fileType ?? inferFileType(fileName)
245
+ };
246
+ return {
247
+ data: { message: { payload: { ...payload } } },
248
+ message: { payload: { ...payload } },
249
+ raw
250
+ };
251
+ };
252
+ var buildLocalTextMessage = (input) => ({
253
+ to: input.to,
254
+ conversationType: input.conversationType,
255
+ type: "TIMTextElem",
256
+ payload: { text: input.payload.text },
257
+ cloudCustomData: input.cloudCustomData
258
+ });
259
+ var buildLocalImageMessage = (input) => ({
260
+ to: input.to,
261
+ conversationType: input.conversationType,
262
+ type: "TIMImageElem",
263
+ payload: {
264
+ file: input.payload.file,
265
+ imageInfoArray: [],
266
+ imageFormat: "",
267
+ url: "",
268
+ onProgress: input.onProgress
269
+ },
270
+ cloudCustomData: input.cloudCustomData
271
+ });
272
+ var buildLocalFileMessage = (input) => ({
273
+ to: input.to,
274
+ conversationType: input.conversationType,
275
+ type: "TIMFileElem",
276
+ payload: {
277
+ file: input.payload.file,
278
+ fileName: input.payload.file.name,
279
+ fileSize: input.payload.file.size,
280
+ fileUrl: "",
281
+ onProgress: input.onProgress
282
+ },
283
+ cloudCustomData: input.cloudCustomData
284
+ });
285
+
286
+ // src/dcim-upload-plugin.ts
287
+ var DCIMUploadPlugin = { __brand: "dcim-upload-plugin" };
288
+
289
+ // src/providers.ts
290
+ var joinURL = (baseURL, path) => `${baseURL.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
291
+ var createFormData = (file, objectName) => {
292
+ const formData = new FormData();
293
+ formData.append("file", file, objectName ?? file.name);
294
+ return formData;
295
+ };
296
+ var canUseXHRUpload = () => typeof XMLHttpRequest !== "undefined";
297
+ var normalizeImageResult = (data) => ({
298
+ url: data?.url ?? "",
299
+ uuid: data?.uuid ?? "",
300
+ imageFormat: data?.imageFormat ?? "",
301
+ imageInfoArray: data?.imageInfoArray ?? []
302
+ });
303
+ var normalizeFileResult = (data) => ({
304
+ url: data?.fileUrl ?? data?.url ?? "",
305
+ uuid: data?.uuid ?? "",
306
+ fileName: data?.fileName ?? "",
307
+ fileSize: data?.fileSize ?? 0
308
+ });
309
+ var createDcimUploadProvider = (options) => {
310
+ const fetchImpl = options.fetchImpl ?? fetch;
311
+ const doUploadByXHR = async (endpoint, file, objectName, onProgress) => {
312
+ const token = await options.getToken?.();
313
+ const url = joinURL(options.baseURL, endpoint);
314
+ return new Promise((resolve, reject) => {
315
+ const xhr = new XMLHttpRequest();
316
+ xhr.open("POST", url, true);
317
+ if (token) xhr.setRequestHeader("token", token);
318
+ xhr.upload.onprogress = (event) => {
319
+ if (!onProgress) return;
320
+ onProgress({
321
+ loaded: event.loaded,
322
+ total: event.total,
323
+ progress: event.lengthComputable && event.total > 0 ? event.loaded / event.total : 0,
324
+ originalEvent: event
325
+ });
326
+ };
327
+ xhr.onerror = () => {
328
+ reject(new Error("Upload failed"));
329
+ };
330
+ xhr.onload = () => {
331
+ if (xhr.status < 200 || xhr.status >= 300) {
332
+ reject(new Error(`Upload failed with status ${xhr.status}`));
333
+ return;
334
+ }
335
+ try {
336
+ const body = JSON.parse(xhr.responseText);
337
+ if (body?.errCode && body.errCode !== 0) {
338
+ reject(new Error(body.errMsg || "Upload failed"));
339
+ return;
340
+ }
341
+ resolve(body?.data ?? body);
342
+ } catch (error) {
343
+ reject(error);
344
+ }
345
+ };
346
+ xhr.send(createFormData(file, objectName));
347
+ });
348
+ };
349
+ const doUploadByFetch = async (endpoint, file, objectName) => {
350
+ const token = await options.getToken?.();
351
+ const headers = {};
352
+ if (token) headers.token = token;
353
+ const response = await fetchImpl(joinURL(options.baseURL, endpoint), {
354
+ method: "POST",
355
+ headers,
356
+ body: createFormData(file, objectName)
357
+ });
358
+ if (!response.ok) {
359
+ throw new Error(`Upload failed with status ${response.status}`);
360
+ }
361
+ const body = await response.json();
362
+ if (body?.errCode && body.errCode !== 0) {
363
+ throw new Error(body.errMsg || "Upload failed");
364
+ }
365
+ return body?.data ?? body;
366
+ };
367
+ const doUpload = async (endpoint, file, onProgress) => {
368
+ const objectName = await options.getObjectName?.(file);
369
+ if (onProgress && canUseXHRUpload()) {
370
+ return doUploadByXHR(endpoint, file, objectName, onProgress);
371
+ }
372
+ return doUploadByFetch(endpoint, file, objectName);
373
+ };
374
+ return {
375
+ async uploadImage({ file, onProgress }) {
376
+ const data = await doUpload(options.imageEndpoint ?? "/tencent/uploadImage", file, onProgress);
377
+ return normalizeImageResult(data);
378
+ },
379
+ async uploadFile({ file, onProgress }) {
380
+ const data = await doUpload(options.fileEndpoint ?? "/tencent/uploadFile", file, onProgress);
381
+ return normalizeFileResult(data);
382
+ }
383
+ };
384
+ };
385
+
386
+ // src/adapters/openim-client-adapter.ts
387
+ var OpenIMClientAdapter = class {
388
+ constructor(options) {
389
+ this.emitter = new SimpleEmitter();
390
+ this.boundHandlers = [];
391
+ this.inactiveTimer = null;
392
+ this.loggingOut = false;
393
+ this.ready = false;
394
+ this.logLevel = import_client_sdk3.LogLevel.Info;
395
+ this.options = options;
396
+ this.inactiveTimeout = options.inactiveTimeout ?? 0;
397
+ this.sdk = (0, import_client_sdk3.getSDK)();
398
+ if (options.debug) this.logLevel = import_client_sdk3.LogLevel.Debug;
399
+ this.bindSdkEvents();
400
+ }
401
+ registerPlugin(plugins) {
402
+ const candidate = plugins?.["dcim-upload-plugin"];
403
+ if (!candidate) return;
404
+ if (candidate === DCIMUploadPlugin) {
405
+ this.pluginUploader = createDcimUploadProvider({
406
+ baseURL: this.options.apiAddr,
407
+ getToken: () => this.token
408
+ });
409
+ return;
410
+ }
411
+ if (typeof candidate === "object" && "uploadImage" in candidate && "uploadFile" in candidate) {
412
+ this.pluginUploader = candidate;
413
+ }
414
+ }
415
+ resetInactiveTimer() {
416
+ if (this.inactiveTimeout <= 0) return;
417
+ this.clearInactiveTimer();
418
+ this.inactiveTimer = setTimeout(() => {
419
+ this.logout().catch(() => {
420
+ });
421
+ }, this.inactiveTimeout);
422
+ }
423
+ clearInactiveTimer() {
424
+ if (this.inactiveTimer) {
425
+ clearTimeout(this.inactiveTimer);
426
+ this.inactiveTimer = null;
427
+ }
428
+ }
429
+ setLogLevel(level) {
430
+ if (level <= import_client_sdk3.LogLevel.Trace && level >= import_client_sdk3.LogLevel.Silent) {
431
+ this.logLevel = level;
432
+ }
433
+ }
434
+ on(eventName, listener) {
435
+ this.emitter.on(eventName, listener);
436
+ }
437
+ off(eventName, listener) {
438
+ this.emitter.off(eventName, listener);
439
+ }
440
+ async login(options) {
441
+ const token = options.token ?? this.options.token;
442
+ if (!token) throw new Error("token is required for login");
443
+ this.token = token;
444
+ this.loggingOut = false;
445
+ const userID = options.userID ?? this.options.userID;
446
+ if (!userID) throw new Error("userID is required for login");
447
+ const result = await this.sdk.login({
448
+ userID,
449
+ token,
450
+ platformID: DEFAULT_PLATFORM_ID,
451
+ apiAddr: options.apiAddr ?? this.options.apiAddr,
452
+ wsAddr: options.wsAddr ?? this.options.wsAddr,
453
+ logLevel: this.logLevel
454
+ });
455
+ this.resetInactiveTimer();
456
+ return result;
457
+ }
458
+ async logout() {
459
+ this.loggingOut = true;
460
+ this.ready = false;
461
+ this.clearInactiveTimer();
462
+ await this.sdk.logout();
463
+ }
464
+ async destroy() {
465
+ this.loggingOut = true;
466
+ this.ready = false;
467
+ this.clearInactiveTimer();
468
+ try {
469
+ const status = await this.sdk.getLoginStatus();
470
+ if (status.data !== import_client_sdk3.LoginStatus.Logout) {
471
+ await this.sdk.logout();
472
+ }
473
+ } catch {
474
+ }
475
+ this.boundHandlers.forEach(({ event, handler }) => {
476
+ this.sdk.off(event, handler);
477
+ });
478
+ this.boundHandlers.length = 0;
479
+ this.emitter.clear();
480
+ }
481
+ isReady() {
482
+ return this.ready;
483
+ }
484
+ createTextMessage(input) {
485
+ return buildLocalTextMessage(input);
486
+ }
487
+ createImageMessage(input) {
488
+ return buildLocalImageMessage(input);
489
+ }
490
+ createFileMessage(input) {
491
+ return buildLocalFileMessage(input);
492
+ }
493
+ async sendMessage(message) {
494
+ let result;
495
+ switch (message.type) {
496
+ case "TIMTextElem":
497
+ result = await this.sendTextMessage(message);
498
+ break;
499
+ case "TIMImageElem":
500
+ result = await this.sendImageMessage(message);
501
+ break;
502
+ case "TIMFileElem":
503
+ result = await this.sendFileMessage(message);
504
+ break;
505
+ default:
506
+ throw new Error(`Unsupported message type: ${message.type}`);
507
+ }
508
+ this.resetInactiveTimer();
509
+ return result;
510
+ }
511
+ bindSdkEvents() {
512
+ const listen = (event, handler) => {
513
+ this.sdk.on(event, handler);
514
+ this.boundHandlers.push({ event, handler });
515
+ };
516
+ listen(import_client_sdk3.CbEvents.OnConnectSuccess, (payload) => {
517
+ this.ready = true;
518
+ this.emitMappedEvents(import_client_sdk3.CbEvents.OnConnectSuccess, payload);
519
+ });
520
+ listen(import_client_sdk3.CbEvents.OnConnecting, (payload) => {
521
+ this.ready = false;
522
+ this.emitMappedEvents(import_client_sdk3.CbEvents.OnConnecting, {
523
+ ...payload,
524
+ data: { state: "CONNECTING" }
525
+ });
526
+ });
527
+ listen(import_client_sdk3.CbEvents.OnConnectFailed, (payload) => {
528
+ this.ready = false;
529
+ if (this.loggingOut) return;
530
+ this.emitMappedEvents(import_client_sdk3.CbEvents.OnConnectFailed, payload);
531
+ });
532
+ listen(import_client_sdk3.CbEvents.OnKickedOffline, (payload) => {
533
+ this.ready = false;
534
+ this.emitMappedEvents(import_client_sdk3.CbEvents.OnKickedOffline, {
535
+ ...payload,
536
+ data: { type: "multipleDevice" }
537
+ });
538
+ });
539
+ listen(import_client_sdk3.CbEvents.OnUserTokenExpired, (payload) => {
540
+ this.ready = false;
541
+ this.emitMappedEvents(import_client_sdk3.CbEvents.OnUserTokenExpired, {
542
+ ...payload,
543
+ data: { type: "tokenExpired" }
544
+ });
545
+ });
546
+ listen(import_client_sdk3.CbEvents.OnUserTokenInvalid, (payload) => {
547
+ this.ready = false;
548
+ this.emitMappedEvents(import_client_sdk3.CbEvents.OnUserTokenInvalid, {
549
+ ...payload,
550
+ data: { type: "tokenInvalid" }
551
+ });
552
+ });
553
+ listen(import_client_sdk3.CbEvents.OnRecvNewMessage, (payload) => {
554
+ this.handleIncomingMessages(payload, false);
555
+ });
556
+ listen(import_client_sdk3.CbEvents.OnRecvNewMessages, (payload) => {
557
+ this.handleIncomingMessages(payload, true);
558
+ });
559
+ }
560
+ emitMappedEvents(event, payload) {
561
+ const eventNames = OPENIM_TO_COMPAT_EVENT[event] ?? [];
562
+ eventNames.forEach((eventName) => {
563
+ if (eventName === EVENT.ERROR) {
564
+ this.emitter.emit(eventName, {
565
+ name: eventName,
566
+ data: {
567
+ code: payload.errCode,
568
+ message: payload.errMsg
569
+ }
570
+ });
571
+ return;
572
+ }
573
+ this.emitter.emit(eventName, {
574
+ name: eventName,
575
+ data: payload.data
576
+ });
577
+ });
578
+ }
579
+ handleIncomingMessages(payload, multiple) {
580
+ const rawMessages = multiple ? payload.data ?? [] : [payload.data];
581
+ const messages = rawMessages.map(mapIncomingMessage).filter(Boolean);
582
+ if (messages.length === 0) return;
583
+ this.emitter.emit(EVENT.MESSAGE_RECEIVED, {
584
+ data: messages
585
+ });
586
+ }
587
+ async sendTextMessage(message) {
588
+ const text = String(message.payload.text ?? "");
589
+ const created = await this.wrapSdkCall("createTextMessage", () => this.sdk.createTextMessage(text));
590
+ const rawMessage = this.attachEx(created.data, message.cloudCustomData);
591
+ const sent = await this.wrapSdkCall("sendMessage(text)", () => this.sdk.sendMessage({
592
+ recvID: message.to,
593
+ groupID: "",
594
+ message: rawMessage,
595
+ isOnlineOnly: false
596
+ }));
597
+ return buildTextSendResult({ text }, sent);
598
+ }
599
+ async sendImageMessage(message) {
600
+ const file = message.payload.file;
601
+ if (!(file instanceof File)) throw new Error("image file is required");
602
+ const uploader = this.options.uploader ?? this.pluginUploader;
603
+ const upload = uploader ? await uploader.uploadImage({
604
+ file,
605
+ onProgress: message.payload.onProgress
606
+ }) : await this.createNativeImageUpload(file);
607
+ const imageMessage = await this.wrapSdkCall(
608
+ "createImageMessageByURL",
609
+ () => this.sdk.createImageMessageByURL(this.buildImageParams(upload))
610
+ );
611
+ const rawMessage = this.attachEx(imageMessage.data, message.cloudCustomData);
612
+ const sent = await this.wrapSdkCall("sendMessageNotOss(image)", () => this.sdk.sendMessageNotOss({
613
+ recvID: message.to,
614
+ groupID: "",
615
+ message: rawMessage,
616
+ offlinePushInfo: void 0
617
+ }));
618
+ return buildImageSendResult(upload, sent);
619
+ }
620
+ async sendFileMessage(message) {
621
+ const file = message.payload.file;
622
+ if (!(file instanceof File)) throw new Error("file is required");
623
+ const uploader = this.options.uploader ?? this.pluginUploader;
624
+ const upload = uploader ? await uploader.uploadFile({
625
+ file,
626
+ onProgress: message.payload.onProgress
627
+ }) : await this.createNativeFileUpload(file);
628
+ const fileMessage = await this.wrapSdkCall(
629
+ "createFileMessageByURL",
630
+ () => this.sdk.createFileMessageByURL(this.buildFileParams(upload, file))
631
+ );
632
+ const rawMessage = this.attachEx(fileMessage.data, message.cloudCustomData);
633
+ const sent = await this.wrapSdkCall("sendMessageNotOss(file)", () => this.sdk.sendMessageNotOss({
634
+ recvID: message.to,
635
+ groupID: "",
636
+ message: rawMessage,
637
+ offlinePushInfo: void 0
638
+ }));
639
+ return buildFileSendResult(upload, file.name, file.size, sent);
640
+ }
641
+ async createNativeImageUpload(file) {
642
+ const uuid = createOperationID();
643
+ const created = await this.sdk.createImageMessageByFile({
644
+ file,
645
+ sourcePath: file.name,
646
+ sourcePicture: {
647
+ uuid,
648
+ type: inferFileType(file.name),
649
+ size: file.size,
650
+ width: 0,
651
+ height: 0,
652
+ url: ""
653
+ },
654
+ bigPicture: {
655
+ uuid,
656
+ type: inferFileType(file.name),
657
+ size: file.size,
658
+ width: 0,
659
+ height: 0,
660
+ url: ""
661
+ },
662
+ snapshotPicture: {
663
+ uuid,
664
+ type: inferFileType(file.name),
665
+ size: file.size,
666
+ width: 0,
667
+ height: 0,
668
+ url: ""
669
+ }
670
+ });
671
+ const data = created.data;
672
+ return {
673
+ url: data.pictureElem?.sourcePicture?.url ?? "",
674
+ uuid: data.pictureElem?.sourcePicture?.uuid ?? uuid,
675
+ imageFormat: data.pictureElem?.sourcePicture?.type ?? inferFileType(file.name),
676
+ imageInfoArray: [
677
+ this.toImageInfo(data.pictureElem?.sourcePicture, 1),
678
+ this.toImageInfo(data.pictureElem?.bigPicture, 2),
679
+ this.toImageInfo(data.pictureElem?.snapshotPicture, 3)
680
+ ].filter((item) => Boolean(item))
681
+ };
682
+ }
683
+ async createNativeFileUpload(file) {
684
+ const uuid = createOperationID();
685
+ const created = await this.sdk.createFileMessageByFile({
686
+ file,
687
+ filePath: file.name,
688
+ fileName: file.name,
689
+ uuid,
690
+ sourceUrl: "",
691
+ fileSize: file.size,
692
+ fileType: inferFileType(file.name)
693
+ });
694
+ const data = created.data;
695
+ return {
696
+ url: data.fileElem?.sourceUrl ?? "",
697
+ uuid: data.fileElem?.uuid ?? uuid,
698
+ fileName: data.fileElem?.fileName ?? file.name,
699
+ fileSize: data.fileElem?.fileSize ?? file.size,
700
+ fileType: inferFileType(file.name)
701
+ };
702
+ }
703
+ buildImageParams(upload) {
704
+ const source = upload.imageInfoArray?.find((item) => item.type === 1) ?? upload.imageInfoArray?.[0];
705
+ const big = upload.imageInfoArray?.find((item) => item.type === 2) ?? source;
706
+ const snapshot = upload.imageInfoArray?.find((item) => item.type === 3) ?? source;
707
+ const format = upload.imageFormat ?? "";
708
+ const uuid = upload.uuid ?? createOperationID();
709
+ return {
710
+ sourcePath: "",
711
+ sourcePicture: {
712
+ uuid,
713
+ type: format,
714
+ size: source?.size ?? 0,
715
+ width: source?.width ?? 0,
716
+ height: source?.height ?? 0,
717
+ url: source?.url ?? upload.url
718
+ },
719
+ bigPicture: {
720
+ uuid,
721
+ type: format,
722
+ size: big?.size ?? source?.size ?? 0,
723
+ width: big?.width ?? source?.width ?? 0,
724
+ height: big?.height ?? source?.height ?? 0,
725
+ url: big?.url ?? upload.url
726
+ },
727
+ snapshotPicture: {
728
+ uuid,
729
+ type: format,
730
+ size: snapshot?.size ?? source?.size ?? 0,
731
+ width: snapshot?.width ?? source?.width ?? 0,
732
+ height: snapshot?.height ?? source?.height ?? 0,
733
+ url: snapshot?.url ?? upload.url
734
+ }
735
+ };
736
+ }
737
+ buildFileParams(upload, file) {
738
+ return {
739
+ filePath: "",
740
+ fileName: upload.fileName ?? file.name,
741
+ uuid: upload.uuid ?? createOperationID(),
742
+ sourceUrl: upload.url,
743
+ fileSize: upload.fileSize ?? file.size,
744
+ fileType: upload.fileType ?? inferFileType(file.name)
745
+ };
746
+ }
747
+ attachEx(message, cloudCustomData) {
748
+ const sanitized = cloudCustomData === "null" || cloudCustomData === "undefined" ? "" : cloudCustomData;
749
+ return {
750
+ ...message,
751
+ ex: sanitized ?? message.ex ?? ""
752
+ };
753
+ }
754
+ toImageInfo(picture, type = 1) {
755
+ if (!picture) return void 0;
756
+ return {
757
+ type,
758
+ size: picture.size,
759
+ width: picture.width,
760
+ height: picture.height,
761
+ url: picture.url
762
+ };
763
+ }
764
+ async wrapSdkCall(label, action) {
765
+ try {
766
+ return await action();
767
+ } catch (error) {
768
+ throw new Error(`${label} failed: ${this.stringifySdkError(error)}`);
769
+ }
770
+ }
771
+ stringifySdkError(error) {
772
+ if (error instanceof Error) return error.message;
773
+ if (typeof error === "string") return error;
774
+ try {
775
+ return JSON.stringify(error);
776
+ } catch {
777
+ return String(error);
778
+ }
779
+ }
780
+ };
781
+
782
+ // src/index.ts
783
+ var create = (options) => new OpenIMClientAdapter(options);
784
+ var ChatIMSDK = {
785
+ EVENT,
786
+ TYPES,
787
+ create
788
+ };
789
+ var index_default = ChatIMSDK;
790
+ // Annotate the CommonJS export names for ESM import in node:
791
+ 0 && (module.exports = {
792
+ DCIMUploadPlugin,
793
+ DEFAULT_PLATFORM_ID,
794
+ EVENT,
795
+ TYPES,
796
+ create,
797
+ createDcimUploadProvider
798
+ });