@amityco/ts-sdk 7.13.1-e261145.0 → 7.14.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/@types/domains/client.d.ts +10 -1
- package/dist/@types/domains/client.d.ts.map +1 -1
- package/dist/@types/domains/feed.d.ts +17 -1
- package/dist/@types/domains/feed.d.ts.map +1 -1
- package/dist/@types/domains/message.d.ts +1 -1
- package/dist/@types/domains/message.d.ts.map +1 -1
- package/dist/@types/domains/post.d.ts +5 -0
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/client/api/accessTokenExpiryWatcher.d.ts +1 -1
- package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -1
- package/dist/client/api/index.d.ts +2 -0
- package/dist/client/api/index.d.ts.map +1 -1
- package/dist/client/api/isSameUserId.d.ts +2 -0
- package/dist/client/api/isSameUserId.d.ts.map +1 -0
- package/dist/client/api/login.d.ts.map +1 -1
- package/dist/client/api/loginAsBot.d.ts.map +1 -1
- package/dist/client/api/loginAsVisitor.d.ts.map +1 -1
- package/dist/client/api/loginWithAccessToken.d.ts +28 -0
- package/dist/client/api/loginWithAccessToken.d.ts.map +1 -0
- package/dist/client/api/logout.d.ts.map +1 -1
- package/dist/client/api/renewTokenWithHandler.d.ts +11 -0
- package/dist/client/api/renewTokenWithHandler.d.ts.map +1 -0
- package/dist/client/api/renewWithAccessToken.d.ts +2 -0
- package/dist/client/api/renewWithAccessToken.d.ts.map +1 -0
- package/dist/client/api/resumeSession.d.ts.map +1 -1
- package/dist/client/api/setAccessTokenHandler.d.ts +31 -0
- package/dist/client/api/setAccessTokenHandler.d.ts.map +1 -0
- package/dist/client/api/setupLoginSubscriptions.d.ts +11 -0
- package/dist/client/api/setupLoginSubscriptions.d.ts.map +1 -0
- package/dist/client/api/tests/loginWithAccessToken.test.d.ts +2 -0
- package/dist/client/api/tests/loginWithAccessToken.test.d.ts.map +1 -0
- package/dist/client/api/validateAccessToken.d.ts +11 -0
- package/dist/client/api/validateAccessToken.d.ts.map +1 -0
- package/dist/commentRepository/api/createComment.d.ts.map +1 -1
- package/dist/commentRepository/api/deleteComment.d.ts.map +1 -1
- package/dist/commentRepository/events/utils.d.ts.map +1 -1
- package/dist/core/subscription.d.ts +2 -2
- package/dist/core/subscription.d.ts.map +1 -1
- package/dist/feedRepository/index.d.ts +1 -1
- package/dist/feedRepository/index.d.ts.map +1 -1
- package/dist/feedRepository/observers/getCommunityFeed/LiveCollectionController.d.ts +13 -0
- package/dist/feedRepository/observers/getCommunityFeed/LiveCollectionController.d.ts.map +1 -0
- package/dist/feedRepository/observers/getCommunityFeed/PaginationController.d.ts +5 -0
- package/dist/feedRepository/observers/getCommunityFeed/PaginationController.d.ts.map +1 -0
- package/dist/feedRepository/observers/getCommunityFeed/QueryStreamController.d.ts +15 -0
- package/dist/feedRepository/observers/getCommunityFeed/QueryStreamController.d.ts.map +1 -0
- package/dist/feedRepository/observers/getCommunityFeed.d.ts +34 -0
- package/dist/feedRepository/observers/getCommunityFeed.d.ts.map +1 -0
- package/dist/feedRepository/observers/index.d.ts +1 -0
- package/dist/feedRepository/observers/index.d.ts.map +1 -1
- package/dist/feedRepository/observers/utils.d.ts.map +1 -1
- package/dist/index.cjs.js +996 -386
- package/dist/index.esm.js +980 -370
- package/dist/index.umd.js +3 -3
- package/dist/postRepository/events/utils.d.ts.map +1 -1
- package/dist/postRepository/observers/utils.d.ts.map +1 -1
- package/dist/postRepository/utils/PostCommentCountEngine/CommentChange.d.ts +11 -0
- package/dist/postRepository/utils/PostCommentCountEngine/CommentChange.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/CreateTask.d.ts +8 -0
- package/dist/postRepository/utils/PostCommentCountEngine/CreateTask.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/DeleteTask.d.ts +7 -0
- package/dist/postRepository/utils/PostCommentCountEngine/DeleteTask.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts +19 -0
- package/dist/postRepository/utils/PostCommentCountEngine/PostCommentCountEngine.d.ts.map +1 -0
- package/dist/postRepository/utils/PostCommentCountEngine/ResetTask.d.ts +8 -0
- package/dist/postRepository/utils/PostCommentCountEngine/ResetTask.d.ts.map +1 -0
- package/dist/postRepository/utils/payload.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/commentRepository/internalApi/createComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/createComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/deleteComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/deleteComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/flagComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/flagComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/hardDeleteComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/hardDeleteComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/isCommentFlaggedByMe.d.ts +0 -2
- package/dist/commentRepository/internalApi/isCommentFlaggedByMe.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/queryComments.d.ts +0 -2
- package/dist/commentRepository/internalApi/queryComments.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/softDeleteComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/softDeleteComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/createComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/createComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/deleteComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/deleteComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/getCommentByIds.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/getCommentByIds.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/getComments.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/getComments.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/hardDeleteComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/hardDeleteComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/queryComments.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/queryComments.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/softDeleteComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/softDeleteComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/tests/updateComment.test.d.ts +0 -2
- package/dist/commentRepository/internalApi/tests/updateComment.test.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/unflagComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/unflagComment.d.ts.map +0 -1
- package/dist/commentRepository/internalApi/updateComment.d.ts +0 -2
- package/dist/commentRepository/internalApi/updateComment.d.ts.map +0 -1
package/dist/index.cjs.js
CHANGED
|
@@ -203,6 +203,12 @@ exports.FeedSourceEnum = void 0;
|
|
|
203
203
|
FeedSourceEnum["Community"] = "community";
|
|
204
204
|
FeedSourceEnum["User"] = "user";
|
|
205
205
|
})(exports.FeedSourceEnum || (exports.FeedSourceEnum = {}));
|
|
206
|
+
exports.FeedTypeEnum = void 0;
|
|
207
|
+
(function (FeedTypeEnum) {
|
|
208
|
+
FeedTypeEnum["Reviewing"] = "reviewing";
|
|
209
|
+
FeedTypeEnum["Published"] = "published";
|
|
210
|
+
FeedTypeEnum["Declined"] = "declined";
|
|
211
|
+
})(exports.FeedTypeEnum || (exports.FeedTypeEnum = {}));
|
|
206
212
|
|
|
207
213
|
exports.AmityEventType = void 0;
|
|
208
214
|
(function (AmityEventType) {
|
|
@@ -239,8 +245,8 @@ exports.AmityEventOrderOption = void 0;
|
|
|
239
245
|
|
|
240
246
|
function getVersion() {
|
|
241
247
|
try {
|
|
242
|
-
// the string ''v7.
|
|
243
|
-
return 'v7.
|
|
248
|
+
// the string ''v7.14.0-cjs'' should be replaced by actual value by @rollup/plugin-replace
|
|
249
|
+
return 'v7.14.0-cjs';
|
|
244
250
|
}
|
|
245
251
|
catch (error) {
|
|
246
252
|
return '__dev__';
|
|
@@ -1682,10 +1688,14 @@ const getLiveReactionTopic = (post) => {
|
|
|
1682
1688
|
};
|
|
1683
1689
|
const getRoomWatcherTopic = (room) => {
|
|
1684
1690
|
const user = getCurrentUser();
|
|
1691
|
+
if (!user)
|
|
1692
|
+
return;
|
|
1685
1693
|
return `${getNetworkId(user)}/room/${room._id}`;
|
|
1686
1694
|
};
|
|
1687
1695
|
const getRoomStreamerTopic = (room) => {
|
|
1688
1696
|
const user = getCurrentUser();
|
|
1697
|
+
if (!user)
|
|
1698
|
+
return;
|
|
1689
1699
|
return `${getNetworkId(user)}/room/${room.roomId}/streamer`;
|
|
1690
1700
|
};
|
|
1691
1701
|
function subscribeTopic(topic, callback) {
|
|
@@ -1780,13 +1790,13 @@ class NetworkActivitiesWatcher {
|
|
|
1780
1790
|
this._listener.clear();
|
|
1781
1791
|
}
|
|
1782
1792
|
}
|
|
1783
|
-
let instance$
|
|
1793
|
+
let instance$8;
|
|
1784
1794
|
var NetworkActivitiesWatcher$1 = {
|
|
1785
1795
|
getInstance: () => {
|
|
1786
|
-
if (!instance$
|
|
1787
|
-
instance$
|
|
1796
|
+
if (!instance$8) {
|
|
1797
|
+
instance$8 = new NetworkActivitiesWatcher();
|
|
1788
1798
|
}
|
|
1789
|
-
return instance$
|
|
1799
|
+
return instance$8;
|
|
1790
1800
|
},
|
|
1791
1801
|
};
|
|
1792
1802
|
|
|
@@ -6838,13 +6848,13 @@ class SessionWatcher {
|
|
|
6838
6848
|
this._listener.clear();
|
|
6839
6849
|
}
|
|
6840
6850
|
}
|
|
6841
|
-
let instance$
|
|
6851
|
+
let instance$7;
|
|
6842
6852
|
var SessionWatcher$1 = {
|
|
6843
6853
|
getInstance: () => {
|
|
6844
|
-
if (!instance$
|
|
6845
|
-
instance$
|
|
6854
|
+
if (!instance$7) {
|
|
6855
|
+
instance$7 = new SessionWatcher();
|
|
6846
6856
|
}
|
|
6847
|
-
return instance$
|
|
6857
|
+
return instance$7;
|
|
6848
6858
|
},
|
|
6849
6859
|
};
|
|
6850
6860
|
|
|
@@ -7421,6 +7431,108 @@ const setVisitorClientToken = async (params) => {
|
|
|
7421
7431
|
return { accessToken, users, userType };
|
|
7422
7432
|
};
|
|
7423
7433
|
|
|
7434
|
+
/* begin_public_function
|
|
7435
|
+
id: client.logout
|
|
7436
|
+
*/
|
|
7437
|
+
/**
|
|
7438
|
+
* ```js
|
|
7439
|
+
* import { Client } from '@amityco/ts-sdk';
|
|
7440
|
+
* const success = await Client.logout()
|
|
7441
|
+
* ```
|
|
7442
|
+
*
|
|
7443
|
+
* Disconnects an {@link Amity.Client} instance from ASC servers
|
|
7444
|
+
*
|
|
7445
|
+
* @returns a success boolean if disconnected
|
|
7446
|
+
*
|
|
7447
|
+
* @category Client API
|
|
7448
|
+
* @async
|
|
7449
|
+
*/
|
|
7450
|
+
const logout = async () => {
|
|
7451
|
+
var _a;
|
|
7452
|
+
const client = getActiveClient();
|
|
7453
|
+
client.log('client/api/disconnectClient');
|
|
7454
|
+
if (client.mqtt && client.mqtt.connected) {
|
|
7455
|
+
client.mqtt.disconnect();
|
|
7456
|
+
}
|
|
7457
|
+
/*
|
|
7458
|
+
* for cases when session state is terminated (example on ban) or token expired,
|
|
7459
|
+
* the terminating block will set session state to terminated or for the or
|
|
7460
|
+
* in the case of expired token the same happens
|
|
7461
|
+
*
|
|
7462
|
+
* establishing state also ignored in cases where accessTokenExpiryWatcher
|
|
7463
|
+
* calls renewal. There is a possibility that renewal will be called before
|
|
7464
|
+
* disconnectClient finishes execution
|
|
7465
|
+
*
|
|
7466
|
+
* IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
|
|
7467
|
+
* event will never be triggered
|
|
7468
|
+
*/
|
|
7469
|
+
if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
|
|
7470
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
7471
|
+
client.emitter.all.clear();
|
|
7472
|
+
(_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
7473
|
+
client.userId = undefined;
|
|
7474
|
+
client.token = undefined;
|
|
7475
|
+
client.loginType = undefined;
|
|
7476
|
+
client.http.defaults.headers.common.Authorization = '';
|
|
7477
|
+
client.http.defaults.metadata = {
|
|
7478
|
+
tokenExpiry: '',
|
|
7479
|
+
isGlobalBanned: false,
|
|
7480
|
+
isUserDeleted: false,
|
|
7481
|
+
};
|
|
7482
|
+
if (typeof document !== 'undefined') {
|
|
7483
|
+
document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
|
7484
|
+
}
|
|
7485
|
+
/*
|
|
7486
|
+
* Cache should be usable if tokenExpired
|
|
7487
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
|
|
7488
|
+
*/
|
|
7489
|
+
if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
|
|
7490
|
+
client.cache = { data: {} };
|
|
7491
|
+
}
|
|
7492
|
+
return true;
|
|
7493
|
+
};
|
|
7494
|
+
/* end_public_function */
|
|
7495
|
+
|
|
7496
|
+
/**
|
|
7497
|
+
* Terminates {@link Amity.Client} instance
|
|
7498
|
+
*
|
|
7499
|
+
*
|
|
7500
|
+
*
|
|
7501
|
+
* @category private
|
|
7502
|
+
*/
|
|
7503
|
+
const terminateClient = (terminationReason) => {
|
|
7504
|
+
const client = getActiveClient();
|
|
7505
|
+
setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
|
|
7506
|
+
if (client.http.defaults.metadata) {
|
|
7507
|
+
if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
|
|
7508
|
+
client.http.defaults.metadata.isGlobalBanned = true;
|
|
7509
|
+
if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
|
|
7510
|
+
client.http.defaults.metadata.isUserDeleted = true;
|
|
7511
|
+
}
|
|
7512
|
+
client.sessionHandler = undefined;
|
|
7513
|
+
logout();
|
|
7514
|
+
};
|
|
7515
|
+
|
|
7516
|
+
let currentUserType = null;
|
|
7517
|
+
/* begin_public_function
|
|
7518
|
+
id: client.get_current_user_type
|
|
7519
|
+
*/
|
|
7520
|
+
const getCurrentUserType = () => {
|
|
7521
|
+
if (!currentUserType) {
|
|
7522
|
+
throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
7523
|
+
}
|
|
7524
|
+
return currentUserType;
|
|
7525
|
+
};
|
|
7526
|
+
/* end_public_function */
|
|
7527
|
+
const setCurrentUserType = (userType) => {
|
|
7528
|
+
currentUserType = userType;
|
|
7529
|
+
};
|
|
7530
|
+
|
|
7531
|
+
const setCurrentUser = ({ user, userType, }) => {
|
|
7532
|
+
setActiveUser(user);
|
|
7533
|
+
setCurrentUserType(userType);
|
|
7534
|
+
};
|
|
7535
|
+
|
|
7424
7536
|
const createUserEventSubscriber = (event, callback) => {
|
|
7425
7537
|
const client = getActiveClient();
|
|
7426
7538
|
const filter = (data) => {
|
|
@@ -7739,13 +7851,13 @@ class AnalyticsEngine {
|
|
|
7739
7851
|
this._eventCapturer.resetAllBuckets();
|
|
7740
7852
|
}
|
|
7741
7853
|
}
|
|
7742
|
-
let instance$
|
|
7854
|
+
let instance$6;
|
|
7743
7855
|
var AnalyticsEngine$1 = {
|
|
7744
7856
|
getInstance: () => {
|
|
7745
|
-
if (!instance$
|
|
7746
|
-
instance$
|
|
7857
|
+
if (!instance$6) {
|
|
7858
|
+
instance$6 = new AnalyticsEngine();
|
|
7747
7859
|
}
|
|
7748
|
-
return instance$
|
|
7860
|
+
return instance$6;
|
|
7749
7861
|
},
|
|
7750
7862
|
};
|
|
7751
7863
|
|
|
@@ -7973,12 +8085,12 @@ class MessageReadReceiptSyncEngine {
|
|
|
7973
8085
|
}
|
|
7974
8086
|
}
|
|
7975
8087
|
}
|
|
7976
|
-
let instance$
|
|
8088
|
+
let instance$5 = null;
|
|
7977
8089
|
var ReadReceiptSyncEngine = {
|
|
7978
8090
|
getInstance: () => {
|
|
7979
|
-
if (!instance$
|
|
7980
|
-
instance$
|
|
7981
|
-
return instance$
|
|
8091
|
+
if (!instance$5)
|
|
8092
|
+
instance$5 = new MessageReadReceiptSyncEngine();
|
|
8093
|
+
return instance$5;
|
|
7982
8094
|
},
|
|
7983
8095
|
};
|
|
7984
8096
|
|
|
@@ -8232,12 +8344,12 @@ class LegacyMessageReadReceiptSyncEngine {
|
|
|
8232
8344
|
}
|
|
8233
8345
|
}
|
|
8234
8346
|
}
|
|
8235
|
-
let instance$
|
|
8347
|
+
let instance$4 = null;
|
|
8236
8348
|
var LegacyReadReceiptSyncEngine = {
|
|
8237
8349
|
getInstance: () => {
|
|
8238
|
-
if (!instance$
|
|
8239
|
-
instance$
|
|
8240
|
-
return instance$
|
|
8350
|
+
if (!instance$4)
|
|
8351
|
+
instance$4 = new LegacyMessageReadReceiptSyncEngine();
|
|
8352
|
+
return instance$4;
|
|
8241
8353
|
},
|
|
8242
8354
|
};
|
|
8243
8355
|
|
|
@@ -8483,12 +8595,12 @@ class ObjectResolverEngine {
|
|
|
8483
8595
|
this.stopResolver();
|
|
8484
8596
|
}
|
|
8485
8597
|
}
|
|
8486
|
-
let instance$
|
|
8598
|
+
let instance$3 = null;
|
|
8487
8599
|
var ObjectResolverEngine$1 = {
|
|
8488
8600
|
getInstance: () => {
|
|
8489
|
-
if (!instance$
|
|
8490
|
-
instance$
|
|
8491
|
-
return instance$
|
|
8601
|
+
if (!instance$3)
|
|
8602
|
+
instance$3 = new ObjectResolverEngine();
|
|
8603
|
+
return instance$3;
|
|
8492
8604
|
},
|
|
8493
8605
|
};
|
|
8494
8606
|
|
|
@@ -8638,13 +8750,13 @@ class LiveReactionSyncEngine {
|
|
|
8638
8750
|
this.stopReactionsSync();
|
|
8639
8751
|
}
|
|
8640
8752
|
}
|
|
8641
|
-
let instance$
|
|
8753
|
+
let instance$2;
|
|
8642
8754
|
var ReactionSyncEngine = {
|
|
8643
8755
|
getInstance: () => {
|
|
8644
|
-
if (!instance$
|
|
8645
|
-
instance$
|
|
8756
|
+
if (!instance$2) {
|
|
8757
|
+
instance$2 = new LiveReactionSyncEngine();
|
|
8646
8758
|
}
|
|
8647
|
-
return instance$
|
|
8759
|
+
return instance$2;
|
|
8648
8760
|
},
|
|
8649
8761
|
};
|
|
8650
8762
|
|
|
@@ -8666,87 +8778,6 @@ var reactionSyncEngineOnLoginHandler = () => {
|
|
|
8666
8778
|
};
|
|
8667
8779
|
};
|
|
8668
8780
|
|
|
8669
|
-
/* begin_public_function
|
|
8670
|
-
id: client.logout
|
|
8671
|
-
*/
|
|
8672
|
-
/**
|
|
8673
|
-
* ```js
|
|
8674
|
-
* import { Client } from '@amityco/ts-sdk';
|
|
8675
|
-
* const success = await Client.logout()
|
|
8676
|
-
* ```
|
|
8677
|
-
*
|
|
8678
|
-
* Disconnects an {@link Amity.Client} instance from ASC servers
|
|
8679
|
-
*
|
|
8680
|
-
* @returns a success boolean if disconnected
|
|
8681
|
-
*
|
|
8682
|
-
* @category Client API
|
|
8683
|
-
* @async
|
|
8684
|
-
*/
|
|
8685
|
-
const logout = async () => {
|
|
8686
|
-
var _a;
|
|
8687
|
-
const client = getActiveClient();
|
|
8688
|
-
client.log('client/api/disconnectClient');
|
|
8689
|
-
if (client.mqtt && client.mqtt.connected) {
|
|
8690
|
-
client.mqtt.disconnect();
|
|
8691
|
-
}
|
|
8692
|
-
/*
|
|
8693
|
-
* for cases when session state is terminated (example on ban) or token expired,
|
|
8694
|
-
* the terminating block will set session state to terminated or for the or
|
|
8695
|
-
* in the case of expired token the same happens
|
|
8696
|
-
*
|
|
8697
|
-
* establishing state also ignored in cases where accessTokenExpiryWatcher
|
|
8698
|
-
* calls renewal. There is a possibility that renewal will be called before
|
|
8699
|
-
* disconnectClient finishes execution
|
|
8700
|
-
*
|
|
8701
|
-
* IMPORTANT: call this before `emitter.all.clear()`, otherwise the session
|
|
8702
|
-
* event will never be triggered
|
|
8703
|
-
*/
|
|
8704
|
-
if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
|
|
8705
|
-
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
8706
|
-
client.emitter.all.clear();
|
|
8707
|
-
(_a = client.mqtt) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
8708
|
-
client.userId = undefined;
|
|
8709
|
-
client.token = undefined;
|
|
8710
|
-
client.http.defaults.headers.common.Authorization = '';
|
|
8711
|
-
client.http.defaults.metadata = {
|
|
8712
|
-
tokenExpiry: '',
|
|
8713
|
-
isGlobalBanned: false,
|
|
8714
|
-
isUserDeleted: false,
|
|
8715
|
-
};
|
|
8716
|
-
if (typeof document !== 'undefined') {
|
|
8717
|
-
document.cookie = '_ascSession=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
|
8718
|
-
}
|
|
8719
|
-
/*
|
|
8720
|
-
* Cache should be usable if tokenExpired
|
|
8721
|
-
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
|
|
8722
|
-
*/
|
|
8723
|
-
if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
|
|
8724
|
-
client.cache = { data: {} };
|
|
8725
|
-
}
|
|
8726
|
-
return true;
|
|
8727
|
-
};
|
|
8728
|
-
/* end_public_function */
|
|
8729
|
-
|
|
8730
|
-
/**
|
|
8731
|
-
* Terminates {@link Amity.Client} instance
|
|
8732
|
-
*
|
|
8733
|
-
*
|
|
8734
|
-
*
|
|
8735
|
-
* @category private
|
|
8736
|
-
*/
|
|
8737
|
-
const terminateClient = (terminationReason) => {
|
|
8738
|
-
const client = getActiveClient();
|
|
8739
|
-
setSessionState("terminated" /* Amity.SessionStates.TERMINATED */, terminationReason);
|
|
8740
|
-
if (client.http.defaults.metadata) {
|
|
8741
|
-
if (terminationReason === "globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */)
|
|
8742
|
-
client.http.defaults.metadata.isGlobalBanned = true;
|
|
8743
|
-
if (terminationReason === "userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */)
|
|
8744
|
-
client.http.defaults.metadata.isUserDeleted = true;
|
|
8745
|
-
}
|
|
8746
|
-
client.sessionHandler = undefined;
|
|
8747
|
-
logout();
|
|
8748
|
-
};
|
|
8749
|
-
|
|
8750
8781
|
const EVENTS = [
|
|
8751
8782
|
'disconnected',
|
|
8752
8783
|
'error',
|
|
@@ -8876,24 +8907,50 @@ const removeChannelMarkerCache = (channel) => {
|
|
|
8876
8907
|
dropFromCache(['channelMarker', 'get', id], true);
|
|
8877
8908
|
};
|
|
8878
8909
|
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8910
|
+
/**
|
|
8911
|
+
* Sets up all login-related event subscriptions
|
|
8912
|
+
* This includes handlers for user bans, deletions, token events, and various engine initializations
|
|
8913
|
+
*
|
|
8914
|
+
* @param unsubWatcher - The unsubscriber function for the access token expiry watcher
|
|
8915
|
+
* @returns Array of unsubscriber functions for all registered subscriptions
|
|
8916
|
+
*
|
|
8917
|
+
* @category private
|
|
8918
|
+
*/
|
|
8919
|
+
const setupLoginSubscriptions = (unsubWatcher) => {
|
|
8920
|
+
const client = getActiveClient();
|
|
8921
|
+
const subscriptions = [];
|
|
8922
|
+
subscriptions.push(
|
|
8923
|
+
// GLOBAL_BAN
|
|
8924
|
+
onClientBanned((_) => {
|
|
8925
|
+
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
8926
|
+
subscriptions.forEach(fn => fn());
|
|
8927
|
+
unsubWatcher();
|
|
8928
|
+
}), onTokenTerminated(_ => {
|
|
8929
|
+
terminateClient();
|
|
8930
|
+
subscriptions.forEach(fn => fn());
|
|
8931
|
+
unsubWatcher();
|
|
8932
|
+
}), onUserDeleted$2((user) => {
|
|
8933
|
+
if (user.userId === client.userId) {
|
|
8934
|
+
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
8935
|
+
subscriptions.forEach(fn => fn());
|
|
8936
|
+
unsubWatcher();
|
|
8937
|
+
}
|
|
8938
|
+
}), onTokenExpired(state => {
|
|
8939
|
+
SessionWatcher$1.getInstance().setSessionState(state);
|
|
8940
|
+
logout();
|
|
8941
|
+
subscriptions.forEach(fn => fn());
|
|
8942
|
+
}),
|
|
8943
|
+
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
8944
|
+
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
8945
|
+
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
8946
|
+
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
|
|
8947
|
+
if (client.useLegacyUnreadCount) {
|
|
8948
|
+
subscriptions.push(readReceiptSyncEngineOnLoginHandler());
|
|
8886
8949
|
}
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
|
|
8891
|
-
currentUserType = userType;
|
|
8892
|
-
};
|
|
8893
|
-
|
|
8894
|
-
const setCurrentUser = ({ user, userType, }) => {
|
|
8895
|
-
setActiveUser(user);
|
|
8896
|
-
setCurrentUserType(userType);
|
|
8950
|
+
else {
|
|
8951
|
+
subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
8952
|
+
}
|
|
8953
|
+
return subscriptions;
|
|
8897
8954
|
};
|
|
8898
8955
|
|
|
8899
8956
|
/* eslint-disable no-param-reassign */
|
|
@@ -8902,8 +8959,8 @@ const setCurrentUser = ({ user, userType, }) => {
|
|
|
8902
8959
|
* than the one already connected, in which case the existing subscriptions need
|
|
8903
8960
|
* to be cleared
|
|
8904
8961
|
*/
|
|
8905
|
-
let subscriptions$
|
|
8906
|
-
async function runMqtt$
|
|
8962
|
+
let subscriptions$4 = [];
|
|
8963
|
+
async function runMqtt$2() {
|
|
8907
8964
|
await modifyMqttConnection();
|
|
8908
8965
|
}
|
|
8909
8966
|
/* begin_public_function
|
|
@@ -8937,8 +8994,8 @@ const login = async (params, sessionHandler, config) => {
|
|
|
8937
8994
|
if (client.userId && client.userId !== params.userId) {
|
|
8938
8995
|
await logout();
|
|
8939
8996
|
// Remove subscription to ban and delete
|
|
8940
|
-
subscriptions$
|
|
8941
|
-
subscriptions$
|
|
8997
|
+
subscriptions$4.forEach(fn => fn());
|
|
8998
|
+
subscriptions$4 = [];
|
|
8942
8999
|
}
|
|
8943
9000
|
// default values
|
|
8944
9001
|
const defaultDeviceId = await getDeviceId();
|
|
@@ -8963,11 +9020,12 @@ const login = async (params, sessionHandler, config) => {
|
|
|
8963
9020
|
}
|
|
8964
9021
|
client.userId = user.userId;
|
|
8965
9022
|
client.sessionHandler = sessionHandler;
|
|
9023
|
+
client.loginType = 'userId';
|
|
8966
9024
|
/*
|
|
8967
9025
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
8968
9026
|
* token expires
|
|
8969
9027
|
*/
|
|
8970
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
9028
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
8971
9029
|
setCurrentUser({ user, userType });
|
|
8972
9030
|
}
|
|
8973
9031
|
catch (error) {
|
|
@@ -8980,40 +9038,11 @@ const login = async (params, sessionHandler, config) => {
|
|
|
8980
9038
|
throw error;
|
|
8981
9039
|
}
|
|
8982
9040
|
if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
|
|
8983
|
-
runMqtt$
|
|
9041
|
+
runMqtt$2();
|
|
8984
9042
|
}
|
|
8985
9043
|
await initializeMessagePreviewSetting();
|
|
8986
|
-
if (subscriptions$
|
|
8987
|
-
subscriptions$
|
|
8988
|
-
// GLOBAL_BAN
|
|
8989
|
-
onClientBanned((_) => {
|
|
8990
|
-
terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
|
|
8991
|
-
subscriptions$3.forEach(fn => fn());
|
|
8992
|
-
unsubWatcher();
|
|
8993
|
-
}), onTokenTerminated(_ => {
|
|
8994
|
-
terminateClient();
|
|
8995
|
-
subscriptions$3.forEach(fn => fn());
|
|
8996
|
-
unsubWatcher();
|
|
8997
|
-
}), onUserDeleted$2((user) => {
|
|
8998
|
-
if (user.userId === client.userId) {
|
|
8999
|
-
terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
|
|
9000
|
-
subscriptions$3.forEach(fn => fn());
|
|
9001
|
-
unsubWatcher();
|
|
9002
|
-
}
|
|
9003
|
-
}), onTokenExpired(state => {
|
|
9004
|
-
SessionWatcher$1.getInstance().setSessionState(state);
|
|
9005
|
-
logout();
|
|
9006
|
-
subscriptions$3.forEach(fn => fn());
|
|
9007
|
-
}),
|
|
9008
|
-
// NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
|
|
9009
|
-
// the channel because currently backend can't handle this, so every time a user is banned from
|
|
9010
|
-
// a channel or the channel is deleted the channel's unread count will not be reset to zero
|
|
9011
|
-
onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler(), reactionSyncEngineOnLoginHandler());
|
|
9012
|
-
if (client.useLegacyUnreadCount) {
|
|
9013
|
-
subscriptions$3.push(readReceiptSyncEngineOnLoginHandler());
|
|
9014
|
-
}
|
|
9015
|
-
else
|
|
9016
|
-
subscriptions$3.push(legacyReadReceiptSyncEngineOnLoginHandler());
|
|
9044
|
+
if (subscriptions$4.length === 0) {
|
|
9045
|
+
subscriptions$4 = setupLoginSubscriptions(unsubWatcher);
|
|
9017
9046
|
}
|
|
9018
9047
|
return true;
|
|
9019
9048
|
};
|
|
@@ -9025,7 +9054,7 @@ const login = async (params, sessionHandler, config) => {
|
|
|
9025
9054
|
* than the one already connected, in which case the existing subscriptions need
|
|
9026
9055
|
* to be cleared
|
|
9027
9056
|
*/
|
|
9028
|
-
const subscriptions$
|
|
9057
|
+
const subscriptions$3 = [];
|
|
9029
9058
|
/* begin_public_function
|
|
9030
9059
|
id: client.loginAsVisitor
|
|
9031
9060
|
*/
|
|
@@ -9068,11 +9097,12 @@ const loginAsVisitor = async (params) => {
|
|
|
9068
9097
|
[user] = users;
|
|
9069
9098
|
client.userId = user.userId;
|
|
9070
9099
|
client.sessionHandler = params.sessionHandler;
|
|
9100
|
+
client.loginType = 'userId';
|
|
9071
9101
|
/*
|
|
9072
9102
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
9073
9103
|
* token expires
|
|
9074
9104
|
*/
|
|
9075
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
9105
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
9076
9106
|
setCurrentUser({ user, userType });
|
|
9077
9107
|
}
|
|
9078
9108
|
catch (error) {
|
|
@@ -9085,16 +9115,16 @@ const loginAsVisitor = async (params) => {
|
|
|
9085
9115
|
throw error;
|
|
9086
9116
|
}
|
|
9087
9117
|
await initializeMessagePreviewSetting();
|
|
9088
|
-
if (subscriptions$
|
|
9118
|
+
if (subscriptions$3.length === 0) {
|
|
9089
9119
|
// handling internal SDK events
|
|
9090
|
-
subscriptions$
|
|
9120
|
+
subscriptions$3.push(onTokenTerminated(_ => {
|
|
9091
9121
|
terminateClient();
|
|
9092
|
-
subscriptions$
|
|
9122
|
+
subscriptions$3.forEach(fn => fn());
|
|
9093
9123
|
unsubWatcher();
|
|
9094
9124
|
}), onTokenExpired(state => {
|
|
9095
9125
|
SessionWatcher$1.getInstance().setSessionState(state);
|
|
9096
9126
|
logout();
|
|
9097
|
-
subscriptions$
|
|
9127
|
+
subscriptions$3.forEach(fn => fn());
|
|
9098
9128
|
}));
|
|
9099
9129
|
}
|
|
9100
9130
|
return true;
|
|
@@ -9123,7 +9153,7 @@ const renewal = () => {
|
|
|
9123
9153
|
* Per instance of Renewal, only one renewal is allowed
|
|
9124
9154
|
*/
|
|
9125
9155
|
const renewToken = async (authToken) => {
|
|
9126
|
-
const { userId, displayName } =
|
|
9156
|
+
const { userId, displayName } = getActiveUser();
|
|
9127
9157
|
const deviceId = await getDeviceId();
|
|
9128
9158
|
const params = { userId, displayName, authToken, deviceId };
|
|
9129
9159
|
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
@@ -9198,6 +9228,242 @@ const renewal = () => {
|
|
|
9198
9228
|
};
|
|
9199
9229
|
/* end_public_function */
|
|
9200
9230
|
|
|
9231
|
+
const validateAccessToken = async ({ token, userId }) => {
|
|
9232
|
+
const client = getActiveClient();
|
|
9233
|
+
// Validate token using sessions API
|
|
9234
|
+
await client.http.get('/api/v3/sessions', {
|
|
9235
|
+
headers: {
|
|
9236
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
9237
|
+
},
|
|
9238
|
+
});
|
|
9239
|
+
// Get user details
|
|
9240
|
+
const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
|
|
9241
|
+
headers: {
|
|
9242
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
9243
|
+
},
|
|
9244
|
+
});
|
|
9245
|
+
const user = users.find((u) => u.userId === userId);
|
|
9246
|
+
client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9247
|
+
client.http.defaults.metadata = {
|
|
9248
|
+
tokenExpiry: token.expiresAt,
|
|
9249
|
+
isGlobalBanned: false,
|
|
9250
|
+
isUserDeleted: false,
|
|
9251
|
+
};
|
|
9252
|
+
client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9253
|
+
client.upload.defaults.metadata = {
|
|
9254
|
+
tokenExpiry: token.expiresAt,
|
|
9255
|
+
isGlobalBanned: false,
|
|
9256
|
+
isUserDeleted: false,
|
|
9257
|
+
};
|
|
9258
|
+
client.token = token;
|
|
9259
|
+
return user;
|
|
9260
|
+
};
|
|
9261
|
+
|
|
9262
|
+
const isSameUserId = (token) => {
|
|
9263
|
+
var _a;
|
|
9264
|
+
const client = getActiveClient();
|
|
9265
|
+
const decoded = jwtDecode__default["default"](token);
|
|
9266
|
+
return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
|
|
9267
|
+
};
|
|
9268
|
+
|
|
9269
|
+
let subscriptions$2 = [];
|
|
9270
|
+
async function runMqtt$1() {
|
|
9271
|
+
await modifyMqttConnection();
|
|
9272
|
+
}
|
|
9273
|
+
/* begin_public_function
|
|
9274
|
+
id: client.loginWithAccessToken
|
|
9275
|
+
*/
|
|
9276
|
+
/**
|
|
9277
|
+
* ```js
|
|
9278
|
+
* import { loginWithAccessToken } from '@amityco/ts-sdk'
|
|
9279
|
+
* const success = await loginWithAccessToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
|
|
9280
|
+
* ```
|
|
9281
|
+
*
|
|
9282
|
+
* Authenticates a user using a pre-existing access token, allowing direct login without user credentials.
|
|
9283
|
+
* Designed for customers who manage access tokens on their own backend.
|
|
9284
|
+
*
|
|
9285
|
+
* @param accessToken JWT access token signed by customer's backend containing user identity
|
|
9286
|
+
* @returns true if authentication is successful
|
|
9287
|
+
*
|
|
9288
|
+
* @category Client API
|
|
9289
|
+
* @async
|
|
9290
|
+
*/
|
|
9291
|
+
const loginWithAccessToken = async (accessToken) => {
|
|
9292
|
+
var _a, _b;
|
|
9293
|
+
const client = getActiveClient();
|
|
9294
|
+
let unsubWatcher;
|
|
9295
|
+
client.log('client/api/loginWithAccessToken', {
|
|
9296
|
+
apiKey: client.apiKey,
|
|
9297
|
+
sessionState: client.sessionState,
|
|
9298
|
+
});
|
|
9299
|
+
// Validate input
|
|
9300
|
+
if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
|
|
9301
|
+
throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9302
|
+
}
|
|
9303
|
+
let decoded;
|
|
9304
|
+
try {
|
|
9305
|
+
decoded = jwtDecode__default["default"](accessToken);
|
|
9306
|
+
}
|
|
9307
|
+
catch (error) {
|
|
9308
|
+
throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9309
|
+
}
|
|
9310
|
+
// Extract userId from token
|
|
9311
|
+
const userId = ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) || ((_b = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _b === void 0 ? void 0 : _b.userId);
|
|
9312
|
+
if (!userId) {
|
|
9313
|
+
throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9314
|
+
}
|
|
9315
|
+
// Handle existing connected user
|
|
9316
|
+
if (client.userId) {
|
|
9317
|
+
const sameUser = isSameUserId(accessToken);
|
|
9318
|
+
if (!sameUser) {
|
|
9319
|
+
// Different user - do full logout
|
|
9320
|
+
await logout();
|
|
9321
|
+
}
|
|
9322
|
+
}
|
|
9323
|
+
try {
|
|
9324
|
+
// Set state to establishing
|
|
9325
|
+
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
9326
|
+
// Prepare token object for validation
|
|
9327
|
+
const tokenObject = {
|
|
9328
|
+
accessToken,
|
|
9329
|
+
issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
|
|
9330
|
+
expiresAt: new Date(decoded.exp * 1000).toISOString(),
|
|
9331
|
+
};
|
|
9332
|
+
// Validate token and get user
|
|
9333
|
+
const user = await validateAccessToken({
|
|
9334
|
+
token: tokenObject,
|
|
9335
|
+
userId,
|
|
9336
|
+
});
|
|
9337
|
+
if (user == null) {
|
|
9338
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9339
|
+
throw new ASCError(`User ${userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9340
|
+
}
|
|
9341
|
+
if (user.isDeleted) {
|
|
9342
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9343
|
+
throw new ASCError(`User ${userId} has been deleted`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9344
|
+
}
|
|
9345
|
+
if (user.isGlobalBanned) {
|
|
9346
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9347
|
+
throw new ASCError(`User ${userId} is globally banned`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9348
|
+
}
|
|
9349
|
+
// Set userId and login method flag
|
|
9350
|
+
client.userId = user.userId;
|
|
9351
|
+
// Set login method flag to 'accessToken' in platform-specific login session
|
|
9352
|
+
client.loginType = 'accessToken';
|
|
9353
|
+
// This will be used by the access token handler to determine if token renewal should be invoked
|
|
9354
|
+
// Set active user
|
|
9355
|
+
setActiveUser(user);
|
|
9356
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
9357
|
+
setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
|
|
9358
|
+
}
|
|
9359
|
+
catch (error) {
|
|
9360
|
+
// If error occurs, revert session state to not logged in
|
|
9361
|
+
setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
|
|
9362
|
+
// Re-throw if it's already an ASCError
|
|
9363
|
+
if (error instanceof ASCError) {
|
|
9364
|
+
throw error;
|
|
9365
|
+
}
|
|
9366
|
+
// Wrap other errors
|
|
9367
|
+
throw new ASCError((error instanceof Error ? error.message : undefined) || 'Login with access token failed', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9368
|
+
}
|
|
9369
|
+
runMqtt$1();
|
|
9370
|
+
await initializeMessagePreviewSetting();
|
|
9371
|
+
if (subscriptions$2.length === 0) {
|
|
9372
|
+
subscriptions$2 = setupLoginSubscriptions(unsubWatcher);
|
|
9373
|
+
}
|
|
9374
|
+
return true;
|
|
9375
|
+
};
|
|
9376
|
+
/* end_public_function */
|
|
9377
|
+
|
|
9378
|
+
/* begin_public_function
|
|
9379
|
+
id: client.renew_with_accessToken
|
|
9380
|
+
*/
|
|
9381
|
+
/*
|
|
9382
|
+
* Renewal defintion accepted by SessionHandler interface
|
|
9383
|
+
*
|
|
9384
|
+
* Tech Spec:
|
|
9385
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
|
|
9386
|
+
*
|
|
9387
|
+
* @category private
|
|
9388
|
+
*/
|
|
9389
|
+
const renewWithAccessToken = async (accessToken) => {
|
|
9390
|
+
var _a, _b;
|
|
9391
|
+
const client = getActiveClient();
|
|
9392
|
+
client.log('initiating access token renewal');
|
|
9393
|
+
/*
|
|
9394
|
+
* Renews a token if it is hasn't been renewed before. Also marks token as
|
|
9395
|
+
* renewed once done
|
|
9396
|
+
* Per instance of Renewal, only one renewal is allowed
|
|
9397
|
+
*/
|
|
9398
|
+
// Validate input
|
|
9399
|
+
if (!accessToken || typeof accessToken !== 'string' || accessToken.trim() === '') {
|
|
9400
|
+
throw new ASCError('Access token must be a non-empty string', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9401
|
+
}
|
|
9402
|
+
let decoded;
|
|
9403
|
+
try {
|
|
9404
|
+
decoded = jwtDecode__default["default"](accessToken);
|
|
9405
|
+
}
|
|
9406
|
+
catch (error) {
|
|
9407
|
+
throw new ASCError('Invalid access token format', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9408
|
+
}
|
|
9409
|
+
// Extract userId from token
|
|
9410
|
+
const userId = ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) || ((_b = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _b === void 0 ? void 0 : _b.userId);
|
|
9411
|
+
if (!userId) {
|
|
9412
|
+
throw new ASCError('Access token does not contain userId', 400100 /* Amity.ServerError.UNAUTHORIZED */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
9413
|
+
}
|
|
9414
|
+
// Handle existing connected user
|
|
9415
|
+
if (client.userId) {
|
|
9416
|
+
const sameUser = isSameUserId(accessToken);
|
|
9417
|
+
if (!sameUser) {
|
|
9418
|
+
// Different user - do full logout
|
|
9419
|
+
await logout();
|
|
9420
|
+
}
|
|
9421
|
+
}
|
|
9422
|
+
const tokenObject = {
|
|
9423
|
+
accessToken,
|
|
9424
|
+
issuedAt: decoded.iat ? new Date(decoded.iat * 1000).toISOString() : new Date().toISOString(),
|
|
9425
|
+
expiresAt: new Date(decoded.exp * 1000).toISOString(),
|
|
9426
|
+
};
|
|
9427
|
+
if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.sessionHandler) {
|
|
9428
|
+
await loginWithAccessToken(accessToken);
|
|
9429
|
+
}
|
|
9430
|
+
else {
|
|
9431
|
+
// about to expire
|
|
9432
|
+
await validateAccessToken({
|
|
9433
|
+
token: tokenObject,
|
|
9434
|
+
userId,
|
|
9435
|
+
});
|
|
9436
|
+
}
|
|
9437
|
+
};
|
|
9438
|
+
/* end_public_function */
|
|
9439
|
+
|
|
9440
|
+
/**
|
|
9441
|
+
* Helper function to renew access token using the accessTokenHandler
|
|
9442
|
+
* Handles error catching and logging
|
|
9443
|
+
*
|
|
9444
|
+
* @param useScheduledTask - Whether to wrap renewal in scheduleTask (for token expired case)
|
|
9445
|
+
* @category private
|
|
9446
|
+
*/
|
|
9447
|
+
const renewTokenWithHandler = async ({ useScheduledTask = false, }) => {
|
|
9448
|
+
const client = getActiveClient();
|
|
9449
|
+
if (!client.userId || !client.accessTokenHandler) {
|
|
9450
|
+
return;
|
|
9451
|
+
}
|
|
9452
|
+
try {
|
|
9453
|
+
const newToken = await client.accessTokenHandler.onTokenRenew(client.userId);
|
|
9454
|
+
if (useScheduledTask) {
|
|
9455
|
+
scheduleTask(() => renewWithAccessToken(newToken));
|
|
9456
|
+
}
|
|
9457
|
+
else {
|
|
9458
|
+
renewWithAccessToken(newToken);
|
|
9459
|
+
}
|
|
9460
|
+
}
|
|
9461
|
+
catch (error) {
|
|
9462
|
+
client.log('Proactive token renewal failed, will retry when token expires', error);
|
|
9463
|
+
// Will fallback to expired token flow
|
|
9464
|
+
}
|
|
9465
|
+
};
|
|
9466
|
+
|
|
9201
9467
|
const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
|
|
9202
9468
|
const COMPENSATED_DELAY = 5 * MINUTE;
|
|
9203
9469
|
/*
|
|
@@ -9233,10 +9499,11 @@ const isAboutToExpire = (params) => {
|
|
|
9233
9499
|
*
|
|
9234
9500
|
* @category private
|
|
9235
9501
|
*/
|
|
9236
|
-
const accessTokenExpiryWatcher = (
|
|
9237
|
-
const interval = setInterval(() => {
|
|
9502
|
+
const accessTokenExpiryWatcher = () => {
|
|
9503
|
+
const interval = setInterval(async () => {
|
|
9238
9504
|
const client = getActiveClient();
|
|
9239
|
-
|
|
9505
|
+
const { sessionHandler, accessTokenHandler, loginType } = client;
|
|
9506
|
+
if (!client.token || !client.userId)
|
|
9240
9507
|
return;
|
|
9241
9508
|
const { issuedAt, expiresAt } = client.token;
|
|
9242
9509
|
if (isExpired(expiresAt)) {
|
|
@@ -9247,18 +9514,38 @@ const accessTokenExpiryWatcher = (sessionHandler) => {
|
|
|
9247
9514
|
*/
|
|
9248
9515
|
fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
|
|
9249
9516
|
/*
|
|
9250
|
-
*
|
|
9251
|
-
*
|
|
9252
|
-
*
|
|
9253
|
-
* Since fireEvent is scheduled, it will be called
|
|
9254
|
-
* after sessionHandler leading to an invalid state change from
|
|
9255
|
-
* establishing to tokenExpired
|
|
9517
|
+
* Check loginType to determine which handler to use:
|
|
9518
|
+
* - 'accessToken' = use accessTokenHandler
|
|
9519
|
+
* - 'userId' = use sessionHandler
|
|
9256
9520
|
*/
|
|
9257
|
-
|
|
9521
|
+
if (loginType === 'accessToken' && accessTokenHandler) {
|
|
9522
|
+
await renewTokenWithHandler({ useScheduledTask: false });
|
|
9523
|
+
}
|
|
9524
|
+
else if (loginType === 'userId' && sessionHandler) {
|
|
9525
|
+
/*
|
|
9526
|
+
* https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
|
|
9527
|
+
*
|
|
9528
|
+
* Why scheduled task?
|
|
9529
|
+
* Since fireEvent is scheduled, it will be called
|
|
9530
|
+
* after sessionHandler leading to an invalid state change from
|
|
9531
|
+
* establishing to tokenExpired
|
|
9532
|
+
*/
|
|
9533
|
+
scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
|
|
9534
|
+
}
|
|
9258
9535
|
return;
|
|
9259
9536
|
}
|
|
9260
9537
|
if (isAboutToExpire({ expiresAt, issuedAt })) {
|
|
9261
|
-
|
|
9538
|
+
/*
|
|
9539
|
+
* Check loginType to determine which handler to use for proactive renewal:
|
|
9540
|
+
* - 'accessToken' = use accessTokenHandler
|
|
9541
|
+
* - 'userId' = use sessionHandler
|
|
9542
|
+
*/
|
|
9543
|
+
if (loginType === 'accessToken' && accessTokenHandler) {
|
|
9544
|
+
await renewTokenWithHandler({ useScheduledTask: false });
|
|
9545
|
+
}
|
|
9546
|
+
else if (loginType === 'userId' && sessionHandler) {
|
|
9547
|
+
sessionHandler.sessionWillRenewAccessToken(renewal());
|
|
9548
|
+
}
|
|
9262
9549
|
}
|
|
9263
9550
|
}, ACCESS_TOKEN_WATCHER_INTERVAL);
|
|
9264
9551
|
return () => clearInterval(interval);
|
|
@@ -9791,6 +10078,7 @@ const secureLogout = async () => {
|
|
|
9791
10078
|
};
|
|
9792
10079
|
/* end_public_function */
|
|
9793
10080
|
|
|
10081
|
+
/* eslint-disable no-param-reassign */
|
|
9794
10082
|
/*
|
|
9795
10083
|
* declared earlier to accomodate case when logging in with a different user
|
|
9796
10084
|
* than the one already connected, in which case the existing subscriptions need
|
|
@@ -9800,38 +10088,6 @@ let subscriptions$1 = [];
|
|
|
9800
10088
|
async function runMqtt() {
|
|
9801
10089
|
await modifyMqttConnection();
|
|
9802
10090
|
}
|
|
9803
|
-
const isSameUserId = (token) => {
|
|
9804
|
-
var _a;
|
|
9805
|
-
const client = getActiveClient();
|
|
9806
|
-
const decoded = jwtDecode__default["default"](token);
|
|
9807
|
-
return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
|
|
9808
|
-
};
|
|
9809
|
-
const validateAccessToken = async ({ token, userId }) => {
|
|
9810
|
-
const client = getActiveClient();
|
|
9811
|
-
// begin establishing session
|
|
9812
|
-
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
9813
|
-
const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
|
|
9814
|
-
headers: {
|
|
9815
|
-
Authorization: `Bearer ${token.accessToken}`,
|
|
9816
|
-
},
|
|
9817
|
-
});
|
|
9818
|
-
const user = users.find((u) => u.userId === userId);
|
|
9819
|
-
client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9820
|
-
client.http.defaults.metadata = {
|
|
9821
|
-
tokenExpiry: token.expiresAt,
|
|
9822
|
-
isGlobalBanned: false,
|
|
9823
|
-
isUserDeleted: false,
|
|
9824
|
-
};
|
|
9825
|
-
client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
|
|
9826
|
-
client.upload.defaults.metadata = {
|
|
9827
|
-
tokenExpiry: token.expiresAt,
|
|
9828
|
-
isGlobalBanned: false,
|
|
9829
|
-
isUserDeleted: false,
|
|
9830
|
-
};
|
|
9831
|
-
client.token = token;
|
|
9832
|
-
setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
|
|
9833
|
-
return user;
|
|
9834
|
-
};
|
|
9835
10091
|
/* begin_public_function
|
|
9836
10092
|
id: client.resumeSession
|
|
9837
10093
|
*/
|
|
@@ -9880,6 +10136,7 @@ const resumeSession = async (params, sessionHandler, config) => {
|
|
|
9880
10136
|
}
|
|
9881
10137
|
}
|
|
9882
10138
|
try {
|
|
10139
|
+
setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
|
|
9883
10140
|
const user = await validateAccessToken(params);
|
|
9884
10141
|
if (user == null) {
|
|
9885
10142
|
throw new ASCError(`${params.userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
@@ -9986,13 +10243,13 @@ class GlobalFileAccessType {
|
|
|
9986
10243
|
}
|
|
9987
10244
|
}
|
|
9988
10245
|
_GlobalFileAccessType_fileAccessType = new WeakMap();
|
|
9989
|
-
let instance;
|
|
10246
|
+
let instance$1;
|
|
9990
10247
|
var GlobalFileAccessType$1 = {
|
|
9991
10248
|
getInstance: () => {
|
|
9992
|
-
if (!instance) {
|
|
9993
|
-
instance = new GlobalFileAccessType();
|
|
10249
|
+
if (!instance$1) {
|
|
10250
|
+
instance$1 = new GlobalFileAccessType();
|
|
9994
10251
|
}
|
|
9995
|
-
return instance;
|
|
10252
|
+
return instance$1;
|
|
9996
10253
|
},
|
|
9997
10254
|
};
|
|
9998
10255
|
|
|
@@ -10170,11 +10427,12 @@ const loginAsBot = async (params) => {
|
|
|
10170
10427
|
[user] = users;
|
|
10171
10428
|
client.userId = user.userId;
|
|
10172
10429
|
client.sessionHandler = params.sessionHandler;
|
|
10430
|
+
client.loginType = 'userId';
|
|
10173
10431
|
/*
|
|
10174
10432
|
* Cannot push to subscriptions as watcher needs to continue working even if
|
|
10175
10433
|
* token expires
|
|
10176
10434
|
*/
|
|
10177
|
-
unsubWatcher = client.accessTokenExpiryWatcher(
|
|
10435
|
+
unsubWatcher = client.accessTokenExpiryWatcher();
|
|
10178
10436
|
setCurrentUser({ user, userType });
|
|
10179
10437
|
}
|
|
10180
10438
|
catch (error) {
|
|
@@ -10203,6 +10461,53 @@ const loginAsBot = async (params) => {
|
|
|
10203
10461
|
};
|
|
10204
10462
|
/* end_public_function */
|
|
10205
10463
|
|
|
10464
|
+
/* begin_public_function
|
|
10465
|
+
id: client.setAccessTokenHandler
|
|
10466
|
+
*/
|
|
10467
|
+
/**
|
|
10468
|
+
* ```js
|
|
10469
|
+
* import { setAccessTokenHandler } from '@amityco/ts-sdk'
|
|
10470
|
+
*
|
|
10471
|
+
* const tokenHandler = {
|
|
10472
|
+
* async onTokenRenew() {
|
|
10473
|
+
* const response = await fetch('https://your-backend.com/api/refresh-token', {
|
|
10474
|
+
* method: 'POST',
|
|
10475
|
+
* credentials: 'include',
|
|
10476
|
+
* });
|
|
10477
|
+
* const data = await response.json();
|
|
10478
|
+
* return data.accessToken;
|
|
10479
|
+
* }
|
|
10480
|
+
* };
|
|
10481
|
+
*
|
|
10482
|
+
* setAccessTokenHandler(tokenHandler);
|
|
10483
|
+
* ```
|
|
10484
|
+
*
|
|
10485
|
+
* Registers a custom handler for managing access token renewal and expiration events.
|
|
10486
|
+
* This enables automatic token refresh and graceful handling of expired tokens.
|
|
10487
|
+
*
|
|
10488
|
+
* Must be called before loginWithAccessToken() to ensure the handler is available
|
|
10489
|
+
* when token expiry is detected.
|
|
10490
|
+
*
|
|
10491
|
+
* @param accessTokenHandler Handler object implementing token renewal callbacks
|
|
10492
|
+
* @returns void
|
|
10493
|
+
*
|
|
10494
|
+
* @category Client API
|
|
10495
|
+
*/
|
|
10496
|
+
const setAccessTokenHandler = (accessTokenHandler) => {
|
|
10497
|
+
const client = getActiveClient();
|
|
10498
|
+
client.log('client/api/setAccessTokenHandler', {
|
|
10499
|
+
apiKey: client.apiKey,
|
|
10500
|
+
sessionState: client.sessionState,
|
|
10501
|
+
hasOnTokenRenew: typeof (accessTokenHandler === null || accessTokenHandler === void 0 ? void 0 : accessTokenHandler.onTokenRenew) === 'function',
|
|
10502
|
+
});
|
|
10503
|
+
// Validate handler has required method
|
|
10504
|
+
if (!accessTokenHandler || typeof accessTokenHandler.onTokenRenew !== 'function') {
|
|
10505
|
+
throw new Error('AccessTokenHandler must implement onTokenRenew() method');
|
|
10506
|
+
}
|
|
10507
|
+
// Register the handler
|
|
10508
|
+
client.accessTokenHandler = accessTokenHandler;
|
|
10509
|
+
};
|
|
10510
|
+
|
|
10206
10511
|
/**
|
|
10207
10512
|
* ```js
|
|
10208
10513
|
* import { onChannelMarkerFetched } from '@amityco/ts-sdk'
|
|
@@ -10562,6 +10867,7 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
10562
10867
|
setActiveUser: setActiveUser,
|
|
10563
10868
|
createClient: createClient,
|
|
10564
10869
|
login: login,
|
|
10870
|
+
loginWithAccessToken: loginWithAccessToken,
|
|
10565
10871
|
logout: logout,
|
|
10566
10872
|
secureLogout: secureLogout,
|
|
10567
10873
|
resumeSession: resumeSession,
|
|
@@ -10580,6 +10886,7 @@ var index$r = /*#__PURE__*/Object.freeze({
|
|
|
10580
10886
|
getCurrentUser: getCurrentUser,
|
|
10581
10887
|
getCurrentUserType: getCurrentUserType,
|
|
10582
10888
|
setCurrentUserType: setCurrentUserType,
|
|
10889
|
+
setAccessTokenHandler: setAccessTokenHandler,
|
|
10583
10890
|
onConnectionError: onConnectionError,
|
|
10584
10891
|
onClientDisconnected: onClientDisconnected,
|
|
10585
10892
|
onClientBanned: onClientBanned,
|
|
@@ -12612,7 +12919,7 @@ const getWatchSessionStorage = () => {
|
|
|
12612
12919
|
return storageInstance;
|
|
12613
12920
|
};
|
|
12614
12921
|
|
|
12615
|
-
const privateKey = "
|
|
12922
|
+
const privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHo80SecH7FuF2\nhFYnb+l26/VN8UMLXAQFLnxciNTEwkGVFMpdezlH8rU2HtUJL4RETogbAOLVY0XM\njs6sPn8G1nALmh9qeDpUtVqFOVtBHxEZ910TLOtQiunjqJKO5nWdqZ71EC3OFluR\niGQkO84BiIFbv37ub7xl3S8XarbtKoLcyVpkDHi+1wx1pgCAn6gtBUgckPL5NR8j\nLseabl3HAXQfhTCKo4tmOFM2Dxwl1IUMmIJrJg/aIU/U0tj/1Eoo7mG0JcNWX19l\nW3EecCbi0ncCJOrkUdwlBrcjaMayaX/ubEwyUeTGiLdyc4L3GRLHjyK8xgVNXRMH\nbZWJ2a5NAgMBAAECggEASxuE+35zTFO/XydKgmvIGcWL9FbgMlXb7Vcf0nBoG945\nbiz0NVc2paraIhJXc608xbYF3qLmtAE1MVBI0ORyRdBHNxY024l/6H6SH60Ed+uI\nM4ysp5ourY6Vj+DLwpdRiI9YDjqYAQDIUmhNxJP7XPhOMoZI6st+xZQBM34ic/bv\nAMSJm9OZphSp3+qXVkFZztr2mxD2EZSJJLYxi8BCdgM2qhazalbcJ6zDKHCZWVWm\n8RRxDGldyMb/237JxETzP40tAlzOZDmBAbUgEnurDJ93RVDIE3rbZUshwgeQd18a\nem096mWgvB1AIKYgsTAR3pw+V19YWAjq/glP6fz8wQKBgQD/oQq+ukKF0PRgBeM5\ngeTjSwsdGppQLmf5ndujvoiz/TpdjDEPu6R8kigQr1rG2t4K/yfdZoI8RdmJD1al\n3Q7N9hofooSy4rj6E3txzWZCHJjHad2cnCp/O26HiReGAl7wTcfTmNdiFHhZQzm5\nJBkvWAiwuvQMNfEbnXxw6/vIDwKBgQDH7fX8gsc77JLvAWgp1MaQN/sbqVb6JeT1\nFQfR8E/WFCSmzQBtNzd5KgYuCeelwr/8DyYytvN2BzCYZXp73gI1jF3YlW5jVn74\nOY6TwQ095digwo6Z0yuxopdIOApKgAkL9PRKgNrqAf3NAyMua6lOGifzjDojC3KU\nfylQmxMn4wKBgHp2B9O/H0dEBw5JQ8W0+JX6yWQz7mEjGiR2/1W+XXb8hQ1zr709\nw1r6Gb+EghRpnZ3fBpYGGbYOMFx8wKHM+N6qW3F0ReX8v2juFGE8aRSa5oYBrWzt\nU16Idjbv8hj84cZ1PJmdyvDtpYn9rpWHOZl4rxEbPvbqkIsOMyNVqdT5AoGAOSge\nmwIIU2le2FVeohbibXiToWTYKMuMmURZ5/r72AgKMmWJKbAPe+Q3wBG01/7FRBpQ\noU8Ma0HC8s6QJbliiEyIx9JwrJWd1vkdecBHONrtA4ibm/5zD2WcOllLF+FitLhi\n3qnX6+6F0IaFGFBPJrTzlv0P4dTz/OAdv52V7GECgYEA2TttOKBAqWllgOaZOkql\nLVMJVmgR7s6tLi1+cEP8ZcapV9aRbRzTAKXm4f8AEhtlG9F9kCOvHYCYGi6JaiWJ\nZkHjeex3T+eE6Di6y5Bm/Ift5jtVhJ4jCVwHOKTMej79NPUFTJfv8hCo29haBDv6\nRXFrv+T21KCcw8k3sJeJWWQ=\n-----END PRIVATE KEY-----";
|
|
12616
12923
|
/*
|
|
12617
12924
|
* The crypto algorithm used for importing key and signing string
|
|
12618
12925
|
*/
|
|
@@ -16937,33 +17244,186 @@ removeReaction.optimistically = (referenceType, referenceId, reactionName) => {
|
|
|
16937
17244
|
return !((_d = reaction === null || reaction === void 0 ? void 0 : reaction.myReactions) === null || _d === void 0 ? void 0 : _d.includes(reactionName));
|
|
16938
17245
|
};
|
|
16939
17246
|
|
|
16940
|
-
|
|
16941
|
-
|
|
16942
|
-
|
|
16943
|
-
|
|
16944
|
-
|
|
16945
|
-
}
|
|
16946
|
-
|
|
16947
|
-
|
|
16948
|
-
|
|
16949
|
-
|
|
16950
|
-
|
|
16951
|
-
|
|
16952
|
-
|
|
16953
|
-
|
|
16954
|
-
}
|
|
16955
|
-
|
|
16956
|
-
|
|
17247
|
+
class ResetTask {
|
|
17248
|
+
constructor(postId, latestCreatedAt, serverCommentCount) {
|
|
17249
|
+
this.postId = postId;
|
|
17250
|
+
this.latestCreatedAt = latestCreatedAt;
|
|
17251
|
+
this.serverCommentCount = serverCommentCount;
|
|
17252
|
+
}
|
|
17253
|
+
}
|
|
17254
|
+
|
|
17255
|
+
// Task to track comment creation
|
|
17256
|
+
class CreateTask {
|
|
17257
|
+
constructor(postId, commentId, createdAt) {
|
|
17258
|
+
this.postId = postId;
|
|
17259
|
+
this.commentId = commentId;
|
|
17260
|
+
this.createdAt = createdAt;
|
|
17261
|
+
}
|
|
17262
|
+
}
|
|
17263
|
+
|
|
17264
|
+
// Task to track comment deletion
|
|
17265
|
+
class DeleteTask {
|
|
17266
|
+
constructor(postId, commentId) {
|
|
17267
|
+
this.postId = postId;
|
|
17268
|
+
this.commentId = commentId;
|
|
17269
|
+
}
|
|
17270
|
+
}
|
|
17271
|
+
|
|
17272
|
+
class CommentChange {
|
|
17273
|
+
constructor(latestCreatedAt, serverCommentCount) {
|
|
17274
|
+
this.latestCommentCreatedAt = latestCreatedAt;
|
|
17275
|
+
this.serverCommentCount = serverCommentCount;
|
|
17276
|
+
this.createdCommentIds = new Set();
|
|
17277
|
+
this.deletedCommentIds = new Set();
|
|
17278
|
+
}
|
|
17279
|
+
}
|
|
17280
|
+
|
|
17281
|
+
class PostCommentCountEngine {
|
|
17282
|
+
constructor() {
|
|
17283
|
+
this.isProcessing = false;
|
|
17284
|
+
this.tasks = [];
|
|
17285
|
+
this.commentChangeTracker = new Map();
|
|
17286
|
+
}
|
|
17287
|
+
queueCommentChangeTask(task) {
|
|
17288
|
+
this.tasks.push(task);
|
|
17289
|
+
if (!this.isProcessing) {
|
|
17290
|
+
this.processCommentChangeTask();
|
|
17291
|
+
}
|
|
17292
|
+
}
|
|
17293
|
+
processCommentChangeTask() {
|
|
17294
|
+
if (this.isProcessing) {
|
|
17295
|
+
return;
|
|
17296
|
+
}
|
|
17297
|
+
this.isProcessing = true;
|
|
17298
|
+
if (this.tasks.length === 0) {
|
|
17299
|
+
this.isProcessing = false;
|
|
17300
|
+
return;
|
|
17301
|
+
}
|
|
17302
|
+
// Process in capped batches, coalescing updates
|
|
17303
|
+
const batch = this.tasks.splice(0, PostCommentCountEngine.BATCH_SIZE);
|
|
17304
|
+
const modifiedPostIds = new Set();
|
|
17305
|
+
batch.forEach(task => {
|
|
17306
|
+
let modified = false;
|
|
17307
|
+
if (task instanceof ResetTask) {
|
|
17308
|
+
modified = this.processResetTaskInternal(task);
|
|
17309
|
+
}
|
|
17310
|
+
else if (task instanceof CreateTask) {
|
|
17311
|
+
modified = this.processCreateTaskInternal(task);
|
|
17312
|
+
}
|
|
17313
|
+
else if (task instanceof DeleteTask) {
|
|
17314
|
+
modified = this.processDeleteTaskInternal(task);
|
|
17315
|
+
}
|
|
17316
|
+
if (modified) {
|
|
17317
|
+
modifiedPostIds.add(task.postId);
|
|
17318
|
+
}
|
|
17319
|
+
});
|
|
17320
|
+
// Publish one update per modified post
|
|
17321
|
+
modifiedPostIds.forEach(postId => {
|
|
17322
|
+
const count = this.computeCommentCount(postId);
|
|
17323
|
+
PostCommentCountEngine.publishUpdate(postId, count);
|
|
17324
|
+
});
|
|
17325
|
+
this.isProcessing = false;
|
|
17326
|
+
// Recurse if more tasks remain
|
|
17327
|
+
if (this.tasks.length > 0) {
|
|
17328
|
+
this.processCommentChangeTask();
|
|
17329
|
+
}
|
|
17330
|
+
}
|
|
17331
|
+
processResetTaskInternal(task) {
|
|
17332
|
+
// Always creates/overwrites tracker
|
|
17333
|
+
this.commentChangeTracker.set(task.postId, new CommentChange(task.latestCreatedAt, task.serverCommentCount));
|
|
17334
|
+
return true;
|
|
17335
|
+
}
|
|
17336
|
+
processCreateTaskInternal(task) {
|
|
17337
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
17338
|
+
if (!tracker)
|
|
17339
|
+
return false; // No tracker, skip
|
|
17340
|
+
if (tracker.createdCommentIds.has(task.commentId))
|
|
17341
|
+
return false; // Deduplication
|
|
17342
|
+
if (task.createdAt <= tracker.latestCommentCreatedAt)
|
|
17343
|
+
return false; // Timestamp filtering
|
|
17344
|
+
tracker.createdCommentIds.add(task.commentId);
|
|
17345
|
+
return true;
|
|
17346
|
+
}
|
|
17347
|
+
processDeleteTaskInternal(task) {
|
|
17348
|
+
const tracker = this.commentChangeTracker.get(task.postId);
|
|
17349
|
+
if (!tracker)
|
|
17350
|
+
return false; // No tracker, skip
|
|
17351
|
+
if (tracker.deletedCommentIds.has(task.commentId))
|
|
17352
|
+
return false; // Deduplication
|
|
17353
|
+
tracker.deletedCommentIds.add(task.commentId);
|
|
17354
|
+
return true;
|
|
17355
|
+
}
|
|
17356
|
+
computeCommentCount(postId) {
|
|
17357
|
+
const tracker = this.commentChangeTracker.get(postId);
|
|
17358
|
+
if (!tracker)
|
|
17359
|
+
return 0;
|
|
17360
|
+
const count = tracker.serverCommentCount + tracker.createdCommentIds.size - tracker.deletedCommentIds.size;
|
|
17361
|
+
return Math.max(0, count);
|
|
17362
|
+
}
|
|
17363
|
+
static publishUpdate(postId, newCount) {
|
|
17364
|
+
var _a;
|
|
17365
|
+
const queryKey = ['post', 'get', postId];
|
|
17366
|
+
mergeInCache(queryKey, {
|
|
17367
|
+
localCommentCount: newCount,
|
|
17368
|
+
});
|
|
17369
|
+
const postPayload = (_a = pullFromCache(queryKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
17370
|
+
if (!postPayload)
|
|
17371
|
+
return;
|
|
17372
|
+
fireEvent('local.post.updated', {
|
|
17373
|
+
posts: [postPayload],
|
|
17374
|
+
});
|
|
17375
|
+
}
|
|
17376
|
+
}
|
|
17377
|
+
PostCommentCountEngine.BATCH_SIZE = 50;
|
|
17378
|
+
let instance;
|
|
17379
|
+
var PostCommentCountEngine$1 = {
|
|
17380
|
+
getInstance: () => {
|
|
17381
|
+
if (!instance) {
|
|
17382
|
+
instance = new PostCommentCountEngine();
|
|
17383
|
+
}
|
|
17384
|
+
return instance;
|
|
17385
|
+
},
|
|
17386
|
+
};
|
|
17387
|
+
|
|
17388
|
+
const updateStreamReferences = (streams, streamId, postId) => {
|
|
17389
|
+
if (!streamId)
|
|
17390
|
+
return streams;
|
|
17391
|
+
return streams.map(stream => stream.streamId === streamId
|
|
17392
|
+
? Object.assign(Object.assign({}, stream), { referenceType: 'post', referenceId: postId, postId }) : stream);
|
|
17393
|
+
};
|
|
17394
|
+
const preparePostPayload = (payload) => {
|
|
17395
|
+
const { posts: postsData, postChildren, videoStreamings } = payload, postPayload = __rest(payload, ["posts", "postChildren", "videoStreamings"]);
|
|
17396
|
+
// Unpack community payload by mapping payload field to postSetting value.
|
|
17397
|
+
const communitiesWithPostSetting = addPostSetting({ communities: postPayload.communities });
|
|
17398
|
+
// map users with community
|
|
17399
|
+
const mappedCommunityUsers = postPayload.communityUsers.map(communityUser => {
|
|
17400
|
+
const user = postPayload.users.find(user => user.userId === communityUser.userId);
|
|
17401
|
+
return Object.assign(Object.assign({}, communityUser), { user });
|
|
17402
|
+
});
|
|
17403
|
+
const communityWithMembershipStatus = updateMembershipStatus(communitiesWithPostSetting, mappedCommunityUsers);
|
|
17404
|
+
let mappedNewStream = [];
|
|
16957
17405
|
// feed type
|
|
16958
17406
|
const posts = postsData.map(post => {
|
|
16959
|
-
var _a, _b;
|
|
17407
|
+
var _a, _b, _c, _d;
|
|
16960
17408
|
const feedType = (_a = postPayload.feeds.find(feed => feed.feedId === post.feedId)) === null || _a === void 0 ? void 0 : _a.feedType;
|
|
16961
17409
|
const childPosts = payload.postChildren.filter(children => children.parentPostId === post.postId);
|
|
16962
17410
|
if (childPosts.length > 0 && isAmityLivestreamPost(childPosts[0])) {
|
|
16963
17411
|
mappedNewStream = updateStreamReferences(videoStreamings, (_b = childPosts[0].data) === null || _b === void 0 ? void 0 : _b.streamId, post.postId);
|
|
16964
17412
|
}
|
|
17413
|
+
// --- Computed Comment Count: ResetTask integration ---
|
|
17414
|
+
// Find all comments for this post (referenceType === 'post' && referenceId === postId)
|
|
17415
|
+
const allComments = (payload.comments || []).filter((c) => c.referenceType === 'post' && c.referenceId === post.postId);
|
|
17416
|
+
// Compute latestCreatedAt
|
|
17417
|
+
const latestCreatedAt = allComments.length === 0
|
|
17418
|
+
? new Date().toISOString()
|
|
17419
|
+
: allComments
|
|
17420
|
+
.map(c => c.createdAt)
|
|
17421
|
+
.sort()
|
|
17422
|
+
.at(-1);
|
|
17423
|
+
// Queue ResetTask for this post
|
|
17424
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new ResetTask(post.postId, latestCreatedAt, (_c = post.commentsCount) !== null && _c !== void 0 ? _c : 0));
|
|
16965
17425
|
return Object.assign(Object.assign({}, post), { childPosts,
|
|
16966
|
-
feedType });
|
|
17426
|
+
feedType, localCommentCount: (_d = post.localCommentCount) !== null && _d !== void 0 ? _d : post.commentsCount });
|
|
16967
17427
|
});
|
|
16968
17428
|
return Object.assign(Object.assign({}, postPayload), { postChildren, videoStreamings: mappedNewStream, posts, communities: communityWithMembershipStatus, communityUsers: mappedCommunityUsers });
|
|
16969
17429
|
};
|
|
@@ -17065,14 +17525,12 @@ const createLocalPostEventSubscriber = (event, callback) => {
|
|
|
17065
17525
|
callback(payload.posts[0]);
|
|
17066
17526
|
}
|
|
17067
17527
|
else {
|
|
17068
|
-
const
|
|
17069
|
-
const { communities } = data;
|
|
17070
|
-
ingestInCache(data);
|
|
17528
|
+
const { communities } = payload;
|
|
17071
17529
|
if ((communities === null || communities === void 0 ? void 0 : communities[0]) && !['local.post.updated'].includes(event)) {
|
|
17072
17530
|
fireEvent('community.updated', {
|
|
17073
17531
|
communities,
|
|
17074
17532
|
categories: [],
|
|
17075
|
-
communityUsers:
|
|
17533
|
+
communityUsers: payload.communityUsers,
|
|
17076
17534
|
feeds: [],
|
|
17077
17535
|
files: [],
|
|
17078
17536
|
users: [],
|
|
@@ -17343,7 +17801,7 @@ const createCommentEventSubscriber = (event, callback) => {
|
|
|
17343
17801
|
const createLocalCommentEventSubscriber = (event, callback) => {
|
|
17344
17802
|
const client = getActiveClient();
|
|
17345
17803
|
const filter = (payload) => {
|
|
17346
|
-
var _a, _b;
|
|
17804
|
+
var _a, _b, _c, _d, _e;
|
|
17347
17805
|
if (!client.cache) {
|
|
17348
17806
|
// TODO: here we are missing specific properties here!
|
|
17349
17807
|
callback(LinkedObject.comment(payload.comments[0]));
|
|
@@ -17383,7 +17841,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17383
17841
|
}
|
|
17384
17842
|
}
|
|
17385
17843
|
}
|
|
17386
|
-
|
|
17844
|
+
else {
|
|
17845
|
+
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
17846
|
+
const postCache = (_a = pullFromCache(postCacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
17847
|
+
postCache === null || postCache === void 0 ? void 0 : postCache.comments.push((_b = comments[0]) === null || _b === void 0 ? void 0 : _b.commentId);
|
|
17848
|
+
pushToCache(postCacheKey, postCache);
|
|
17849
|
+
}
|
|
17850
|
+
const queries = (_c = queryCache(['comment', 'query'])) === null || _c === void 0 ? void 0 : _c.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
|
|
17387
17851
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17388
17852
|
}
|
|
17389
17853
|
if (['local.comment.deleted'].includes(event)) {
|
|
@@ -17415,7 +17879,13 @@ const createLocalCommentEventSubscriber = (event, callback) => {
|
|
|
17415
17879
|
}
|
|
17416
17880
|
}
|
|
17417
17881
|
}
|
|
17418
|
-
|
|
17882
|
+
else {
|
|
17883
|
+
const postCacheKey = ['post', 'get', comments[0].referenceId];
|
|
17884
|
+
const postCache = (_d = pullFromCache(postCacheKey)) === null || _d === void 0 ? void 0 : _d.data;
|
|
17885
|
+
const updatedPost = Object.assign(Object.assign({}, postCache), { comments: postCache === null || postCache === void 0 ? void 0 : postCache.comments.filter(commentId => { var _a; return commentId !== ((_a = comments[0]) === null || _a === void 0 ? void 0 : _a.commentId); }) });
|
|
17886
|
+
pushToCache(postCacheKey, updatedPost);
|
|
17887
|
+
}
|
|
17888
|
+
const queries = (_e = queryCache(['comment', 'query'])) === null || _e === void 0 ? void 0 : _e.filter(({ key }) => { var _a; return ((_a = key[2]) === null || _a === void 0 ? void 0 : _a.referenceId) === comment.data.referenceId; });
|
|
17419
17889
|
queries === null || queries === void 0 ? void 0 : queries.map(({ key, data }) => upsertInCache(key, data, { cachedAt: -1 }));
|
|
17420
17890
|
}
|
|
17421
17891
|
callback(LinkedObject.comment(comment.data));
|
|
@@ -25125,7 +25595,6 @@ getCommentByIds.locally = (commentIds) => {
|
|
|
25125
25595
|
* @async
|
|
25126
25596
|
*/
|
|
25127
25597
|
const createComment = async (bundle) => {
|
|
25128
|
-
var _a;
|
|
25129
25598
|
const client = getActiveClient();
|
|
25130
25599
|
client.log('comment/createComment', bundle);
|
|
25131
25600
|
const { data } = await client.http.post('/api/v3/comments', bundle);
|
|
@@ -25137,22 +25606,7 @@ const createComment = async (bundle) => {
|
|
|
25137
25606
|
if (client.cache)
|
|
25138
25607
|
ingestInCache(data, { cachedAt });
|
|
25139
25608
|
if (['post', 'content'].includes(bundle.referenceType)) {
|
|
25140
|
-
|
|
25141
|
-
if (post) {
|
|
25142
|
-
post.commentsCount += 1;
|
|
25143
|
-
fireEvent('local.post.updated', {
|
|
25144
|
-
posts: [post],
|
|
25145
|
-
categories: [],
|
|
25146
|
-
comments: [],
|
|
25147
|
-
communities: [],
|
|
25148
|
-
communityUsers: data.communityUsers,
|
|
25149
|
-
feeds: [],
|
|
25150
|
-
files: data.files,
|
|
25151
|
-
postChildren: [],
|
|
25152
|
-
users: data.users,
|
|
25153
|
-
videoStreamings: [],
|
|
25154
|
-
});
|
|
25155
|
-
}
|
|
25609
|
+
PostCommentCountEngine$1.getInstance().queueCommentChangeTask(new CreateTask(bundle.referenceId, comments[0].commentId, data.comments[0].createdAt));
|
|
25156
25610
|
}
|
|
25157
25611
|
else if (bundle.referenceType === 'story') {
|
|
25158
25612
|
const storyIndex = pullFromCache([
|
|
@@ -25311,7 +25765,7 @@ getStoryByStoryId$1.locally = (storyId) => {
|
|
|
25311
25765
|
* @async
|
|
25312
25766
|
*/
|
|
25313
25767
|
const deleteComment = async (commentId, permanent = false) => {
|
|
25314
|
-
var _a;
|
|
25768
|
+
var _a, _b;
|
|
25315
25769
|
const client = getActiveClient();
|
|
25316
25770
|
const comment = await getComment$2(commentId);
|
|
25317
25771
|
// API-FIX: This endpoint has not been implemented yet.
|
|
@@ -25344,26 +25798,14 @@ const deleteComment = async (commentId, permanent = false) => {
|
|
|
25344
25798
|
else {
|
|
25345
25799
|
const post = (_a = pullFromCache(['post', 'get', comment.data.referenceId])) === null || _a === void 0 ? void 0 : _a.data;
|
|
25346
25800
|
if (post) {
|
|
25347
|
-
|
|
25348
|
-
|
|
25349
|
-
|
|
25350
|
-
|
|
25801
|
+
const engine = PostCommentCountEngine$1.getInstance();
|
|
25802
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, commentId));
|
|
25803
|
+
if (!deleted.parentId && ((_b = deleted.children) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
25804
|
+
// NOTE: delete the parent comment will also remove all children comments
|
|
25805
|
+
deleted.children.forEach((childCommentId) => {
|
|
25806
|
+
engine.queueCommentChangeTask(new DeleteTask(post.postId, childCommentId));
|
|
25807
|
+
});
|
|
25351
25808
|
}
|
|
25352
|
-
else
|
|
25353
|
-
removeCount = 1;
|
|
25354
|
-
post.commentsCount -= removeCount;
|
|
25355
|
-
fireEvent('local.post.updated', {
|
|
25356
|
-
posts: [post],
|
|
25357
|
-
categories: [],
|
|
25358
|
-
comments: [],
|
|
25359
|
-
communities: [],
|
|
25360
|
-
communityUsers: [],
|
|
25361
|
-
feeds: [],
|
|
25362
|
-
files: [],
|
|
25363
|
-
postChildren: [],
|
|
25364
|
-
users: [],
|
|
25365
|
-
videoStreamings: [],
|
|
25366
|
-
});
|
|
25367
25809
|
}
|
|
25368
25810
|
}
|
|
25369
25811
|
fireEvent('local.comment.deleted', {
|
|
@@ -25929,47 +26371,6 @@ var index$d = /*#__PURE__*/Object.freeze({
|
|
|
25929
26371
|
getComments: getComments
|
|
25930
26372
|
});
|
|
25931
26373
|
|
|
25932
|
-
const getPost$1 = async (postId) => {
|
|
25933
|
-
const client = getActiveClient();
|
|
25934
|
-
client.log('post/getPost', postId);
|
|
25935
|
-
isInTombstone('post', postId);
|
|
25936
|
-
let payload;
|
|
25937
|
-
try {
|
|
25938
|
-
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
25939
|
-
const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
|
|
25940
|
-
payload = response.data;
|
|
25941
|
-
}
|
|
25942
|
-
catch (error) {
|
|
25943
|
-
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
25944
|
-
pushToTombstone('post', postId);
|
|
25945
|
-
}
|
|
25946
|
-
throw error;
|
|
25947
|
-
}
|
|
25948
|
-
const data = prepareMembershipPayload(payload, 'communityUsers');
|
|
25949
|
-
const cachedAt = client.cache && Date.now();
|
|
25950
|
-
if (client.cache)
|
|
25951
|
-
ingestInCache(data, { cachedAt });
|
|
25952
|
-
const { posts } = data;
|
|
25953
|
-
const result = posts.find(post => post.postId === postId);
|
|
25954
|
-
return {
|
|
25955
|
-
data: result,
|
|
25956
|
-
cachedAt,
|
|
25957
|
-
};
|
|
25958
|
-
};
|
|
25959
|
-
getPost$1.locally = (postId) => {
|
|
25960
|
-
const client = getActiveClient();
|
|
25961
|
-
client.log('post/getPost.locally', postId);
|
|
25962
|
-
if (!client.cache)
|
|
25963
|
-
return;
|
|
25964
|
-
const cached = pullFromCache(['post', 'get', postId]);
|
|
25965
|
-
if (!cached)
|
|
25966
|
-
return;
|
|
25967
|
-
return {
|
|
25968
|
-
data: cached.data,
|
|
25969
|
-
cachedAt: cached.cachedAt,
|
|
25970
|
-
};
|
|
25971
|
-
};
|
|
25972
|
-
|
|
25973
26374
|
/**
|
|
25974
26375
|
* ```js
|
|
25975
26376
|
* import { onLocalPostDeleted } from '@amityco/ts-sdk'
|
|
@@ -26068,7 +26469,6 @@ const commentEventHandler$1 = (callback, eventHandler, cacheKey) => {
|
|
|
26068
26469
|
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
26069
26470
|
if (!currentCollection || !currentCollection.data.includes(comment.referenceId))
|
|
26070
26471
|
return;
|
|
26071
|
-
await getPost$1(comment.referenceId);
|
|
26072
26472
|
callback(comment);
|
|
26073
26473
|
});
|
|
26074
26474
|
};
|
|
@@ -26076,12 +26476,8 @@ const generateCommentSubscriptions$1 = (cacheKey) => {
|
|
|
26076
26476
|
const eventHandlers = [
|
|
26077
26477
|
onCommentCreated,
|
|
26078
26478
|
onCommentDeleted,
|
|
26079
|
-
onCommentReactionAdded,
|
|
26080
|
-
onCommentReactionRemoved,
|
|
26081
26479
|
onCommentCreatedLocal,
|
|
26082
26480
|
onCommentDeleteLocal,
|
|
26083
|
-
onLocalCommentReactionAdded,
|
|
26084
|
-
onLocalCommentReactionRemoved,
|
|
26085
26481
|
];
|
|
26086
26482
|
return eventHandlers.map(handler => ({
|
|
26087
26483
|
fn: convertEventPayload((callback) => commentEventHandler$1(callback, handler, cacheKey), 'referenceId', 'post'),
|
|
@@ -26445,6 +26841,47 @@ class UserFeedQueryStreamController extends QueryStreamController {
|
|
|
26445
26841
|
}
|
|
26446
26842
|
}
|
|
26447
26843
|
|
|
26844
|
+
const getPost$1 = async (postId) => {
|
|
26845
|
+
const client = getActiveClient();
|
|
26846
|
+
client.log('post/getPost', postId);
|
|
26847
|
+
isInTombstone('post', postId);
|
|
26848
|
+
let payload;
|
|
26849
|
+
try {
|
|
26850
|
+
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
26851
|
+
const response = await client.http.get(`/api/v3/posts/${encodeURIComponent(postId)}`);
|
|
26852
|
+
payload = response.data;
|
|
26853
|
+
}
|
|
26854
|
+
catch (error) {
|
|
26855
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
26856
|
+
pushToTombstone('post', postId);
|
|
26857
|
+
}
|
|
26858
|
+
throw error;
|
|
26859
|
+
}
|
|
26860
|
+
const data = prepareMembershipPayload(payload, 'communityUsers');
|
|
26861
|
+
const cachedAt = client.cache && Date.now();
|
|
26862
|
+
if (client.cache)
|
|
26863
|
+
ingestInCache(data, { cachedAt });
|
|
26864
|
+
const { posts } = data;
|
|
26865
|
+
const result = posts.find(post => post.postId === postId);
|
|
26866
|
+
return {
|
|
26867
|
+
data: result,
|
|
26868
|
+
cachedAt,
|
|
26869
|
+
};
|
|
26870
|
+
};
|
|
26871
|
+
getPost$1.locally = (postId) => {
|
|
26872
|
+
const client = getActiveClient();
|
|
26873
|
+
client.log('post/getPost.locally', postId);
|
|
26874
|
+
if (!client.cache)
|
|
26875
|
+
return;
|
|
26876
|
+
const cached = pullFromCache(['post', 'get', postId]);
|
|
26877
|
+
if (!cached)
|
|
26878
|
+
return;
|
|
26879
|
+
return {
|
|
26880
|
+
data: cached.data,
|
|
26881
|
+
cachedAt: cached.cachedAt,
|
|
26882
|
+
};
|
|
26883
|
+
};
|
|
26884
|
+
|
|
26448
26885
|
class UserFeedLiveCollectionController extends LiveCollectionController {
|
|
26449
26886
|
constructor(query, callback) {
|
|
26450
26887
|
const queryStreamId = hash__default["default"](query);
|
|
@@ -26578,12 +27015,240 @@ const getUserFeed = (params, callback, config) => {
|
|
|
26578
27015
|
};
|
|
26579
27016
|
/* end_public_function */
|
|
26580
27017
|
|
|
27018
|
+
class CommunityFeedPaginationController extends PaginationController {
|
|
27019
|
+
async getRequest(queryParams, token) {
|
|
27020
|
+
const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, includeDeleted, communityId } = queryParams, params = __rest(queryParams, ["limit", "includeDeleted", "communityId"]);
|
|
27021
|
+
const options = token ? { token } : { limit };
|
|
27022
|
+
const { data: queryResponse } = await this.http.get(`/api/v5/posts`, {
|
|
27023
|
+
params: Object.assign(Object.assign({}, params), { targetId: communityId, targetType: 'community', isDeleted: inferIsDeleted(includeDeleted), matchingOnlyParentPost: true, options }),
|
|
27024
|
+
});
|
|
27025
|
+
return queryResponse;
|
|
27026
|
+
}
|
|
27027
|
+
}
|
|
27028
|
+
|
|
27029
|
+
class CommunityFeedQueryStreamController extends QueryStreamController {
|
|
27030
|
+
constructor(query, cacheKey, notifyChange, preparePayload) {
|
|
27031
|
+
super(query, cacheKey);
|
|
27032
|
+
this.notifyChange = notifyChange;
|
|
27033
|
+
this.preparePayload = preparePayload;
|
|
27034
|
+
}
|
|
27035
|
+
async saveToMainDB(response) {
|
|
27036
|
+
const processedPayload = await this.preparePayload(response);
|
|
27037
|
+
const client = getActiveClient();
|
|
27038
|
+
const cachedAt = client.cache && Date.now();
|
|
27039
|
+
if (client.cache) {
|
|
27040
|
+
ingestInCache(processedPayload, { cachedAt });
|
|
27041
|
+
}
|
|
27042
|
+
}
|
|
27043
|
+
appendToQueryStream(response, direction, refresh = false) {
|
|
27044
|
+
var _a, _b;
|
|
27045
|
+
if (refresh) {
|
|
27046
|
+
pushToCache(this.cacheKey, {
|
|
27047
|
+
data: response.posts.map(getResolver('post')),
|
|
27048
|
+
});
|
|
27049
|
+
}
|
|
27050
|
+
else {
|
|
27051
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27052
|
+
const posts = (_b = collection === null || collection === void 0 ? void 0 : collection.data) !== null && _b !== void 0 ? _b : [];
|
|
27053
|
+
pushToCache(this.cacheKey, Object.assign(Object.assign({}, collection), { data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])] }));
|
|
27054
|
+
}
|
|
27055
|
+
}
|
|
27056
|
+
reactor(action) {
|
|
27057
|
+
return (post) => {
|
|
27058
|
+
var _a, _b;
|
|
27059
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27060
|
+
if (!collection)
|
|
27061
|
+
return;
|
|
27062
|
+
if (action === EnumPostActions.OnPostDeleted) {
|
|
27063
|
+
collection.data = collection.data.filter(postId => postId !== post.postId);
|
|
27064
|
+
}
|
|
27065
|
+
if (post.parentPostId && post.isDeleted) {
|
|
27066
|
+
const parentPost = (_b = pullFromCache([
|
|
27067
|
+
'post',
|
|
27068
|
+
'get',
|
|
27069
|
+
post.parentPostId,
|
|
27070
|
+
])) === null || _b === void 0 ? void 0 : _b.data;
|
|
27071
|
+
if (!parentPost)
|
|
27072
|
+
return;
|
|
27073
|
+
parentPost.children = parentPost.children.filter(childId => childId !== post.postId);
|
|
27074
|
+
pushToCache(['post', 'get', parentPost.postId], parentPost);
|
|
27075
|
+
}
|
|
27076
|
+
if (action === EnumPostActions.OnPostDeclined) {
|
|
27077
|
+
collection.data = collection.data.filter(postId => postId !== post.postId);
|
|
27078
|
+
}
|
|
27079
|
+
if (action === EnumPostActions.OnPostCreated || action === EnumPostActions.OnPostApproved) {
|
|
27080
|
+
collection.data = [...new Set([post.postId, ...collection.data])];
|
|
27081
|
+
}
|
|
27082
|
+
pushToCache(this.cacheKey, collection);
|
|
27083
|
+
this.notifyChange({ origin: "event" /* Amity.LiveDataOrigin.EVENT */, loading: false });
|
|
27084
|
+
};
|
|
27085
|
+
}
|
|
27086
|
+
subscribeRTE(createSubscriber) {
|
|
27087
|
+
return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
|
|
27088
|
+
}
|
|
27089
|
+
}
|
|
27090
|
+
|
|
27091
|
+
const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
|
|
27092
|
+
return eventHandler(async (comment) => {
|
|
27093
|
+
var _a;
|
|
27094
|
+
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27095
|
+
if (!currentCollection ||
|
|
27096
|
+
!currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
|
|
27097
|
+
return;
|
|
27098
|
+
callback(comment);
|
|
27099
|
+
});
|
|
27100
|
+
};
|
|
27101
|
+
const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
|
|
27102
|
+
const eventHandlers = [
|
|
27103
|
+
onCommentCreated,
|
|
27104
|
+
onCommentDeleted,
|
|
27105
|
+
onCommentCreatedLocal,
|
|
27106
|
+
onCommentDeleteLocal,
|
|
27107
|
+
];
|
|
27108
|
+
return eventHandlers.map(handler => ({
|
|
27109
|
+
fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
|
|
27110
|
+
action: EnumPostActions.OnPostUpdated,
|
|
27111
|
+
}));
|
|
27112
|
+
};
|
|
27113
|
+
const getPostSubscription = (cacheKey) => {
|
|
27114
|
+
return [
|
|
27115
|
+
{ fn: onPostCreated, action: EnumPostActions.OnPostCreated },
|
|
27116
|
+
{ fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
|
|
27117
|
+
{ fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
|
|
27118
|
+
{ fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27119
|
+
{ fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
|
|
27120
|
+
{ fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
|
|
27121
|
+
{ fn: onPostApproved, action: EnumPostActions.OnPostApproved },
|
|
27122
|
+
{ fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
|
|
27123
|
+
{ fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27124
|
+
{ fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27125
|
+
{ fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27126
|
+
{ fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27127
|
+
{ fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27128
|
+
...generateCommentSubscriptions({ cacheKey }),
|
|
27129
|
+
];
|
|
27130
|
+
};
|
|
27131
|
+
const resolvePostIdsFromRooms = (rooms, posts) => {
|
|
27132
|
+
var _a;
|
|
27133
|
+
return ((_a = rooms
|
|
27134
|
+
.map(room => {
|
|
27135
|
+
const post = posts.find(post => post.postId === room.referenceId);
|
|
27136
|
+
return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
|
|
27137
|
+
})
|
|
27138
|
+
.filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
|
|
27139
|
+
};
|
|
27140
|
+
|
|
27141
|
+
class CommunityFeedLiveCollectionController extends LiveCollectionController {
|
|
27142
|
+
constructor(query, callback) {
|
|
27143
|
+
const queryStreamId = hash__default["default"](query);
|
|
27144
|
+
const cacheKey = ['communityFeed', 'collection', queryStreamId];
|
|
27145
|
+
const paginationController = new CommunityFeedPaginationController(query);
|
|
27146
|
+
super(paginationController, queryStreamId, cacheKey, callback);
|
|
27147
|
+
this.query = query;
|
|
27148
|
+
this.queryStreamController = new CommunityFeedQueryStreamController(this.query, this.cacheKey, this.notifyChange.bind(this), preparePostPayload);
|
|
27149
|
+
this.callback = callback.bind(this);
|
|
27150
|
+
this.loadPage({ initial: true });
|
|
27151
|
+
}
|
|
27152
|
+
setup() {
|
|
27153
|
+
var _a;
|
|
27154
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27155
|
+
if (!collection) {
|
|
27156
|
+
pushToCache(this.cacheKey, {
|
|
27157
|
+
data: [],
|
|
27158
|
+
params: {},
|
|
27159
|
+
});
|
|
27160
|
+
}
|
|
27161
|
+
}
|
|
27162
|
+
async persistModel(queryPayload) {
|
|
27163
|
+
await this.queryStreamController.saveToMainDB(queryPayload);
|
|
27164
|
+
}
|
|
27165
|
+
persistQueryStream({ response, direction, refresh, }) {
|
|
27166
|
+
this.queryStreamController.appendToQueryStream(response, direction, refresh);
|
|
27167
|
+
}
|
|
27168
|
+
startSubscription() {
|
|
27169
|
+
return this.queryStreamController.subscribeRTE(getPostSubscription(this.cacheKey));
|
|
27170
|
+
}
|
|
27171
|
+
notifyChange({ origin, loading, error }) {
|
|
27172
|
+
var _a, _b;
|
|
27173
|
+
const collection = (_a = pullFromCache(this.cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27174
|
+
if (!collection)
|
|
27175
|
+
return;
|
|
27176
|
+
const data = ((_b = collection.data
|
|
27177
|
+
.map(id => pullFromCache(['post', 'get', id]))
|
|
27178
|
+
.filter(isNonNullable)
|
|
27179
|
+
.map(({ data }) => data)) !== null && _b !== void 0 ? _b : []).map(LinkedObject.post);
|
|
27180
|
+
if (!this.shouldNotify(data) && origin === 'event')
|
|
27181
|
+
return;
|
|
27182
|
+
this.callback({
|
|
27183
|
+
onNextPage: () => this.loadPage({ direction: "next" /* Amity.LiveCollectionPageDirection.NEXT */ }),
|
|
27184
|
+
data,
|
|
27185
|
+
hasNextPage: !!this.paginationController.getNextToken(),
|
|
27186
|
+
loading,
|
|
27187
|
+
error,
|
|
27188
|
+
});
|
|
27189
|
+
}
|
|
27190
|
+
}
|
|
27191
|
+
|
|
27192
|
+
/* begin_public_function
|
|
27193
|
+
id: feed.query.community_feed
|
|
27194
|
+
*/
|
|
27195
|
+
/**
|
|
27196
|
+
* ```js
|
|
27197
|
+
* import { FeedRepository } from '@amityco/ts-sdk'
|
|
27198
|
+
*
|
|
27199
|
+
* let posts = []
|
|
27200
|
+
* const unsubscribe = FeedRepository.getCommunityFeed({
|
|
27201
|
+
* communityId: 'community-id',
|
|
27202
|
+
* sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated',
|
|
27203
|
+
* includeDeleted?: boolean,
|
|
27204
|
+
* feedType?: 'reviewing' | 'published' | 'declined',
|
|
27205
|
+
* tags?: string[],
|
|
27206
|
+
* includeMixedStructure?: boolean,
|
|
27207
|
+
* limit?: number,
|
|
27208
|
+
* }, response => processResponse(response))
|
|
27209
|
+
* ```
|
|
27210
|
+
*
|
|
27211
|
+
* Observe all mutations on a list of {@link Amity.Post} for a given community feed.
|
|
27212
|
+
*
|
|
27213
|
+
* @param params - Parameters for querying the community feed:
|
|
27214
|
+
* @param params.communityId The ID of the community (required)
|
|
27215
|
+
* @param params.sortBy The sorting order of the feed (optional)
|
|
27216
|
+
* @param params.includeDeleted Whether to include deleted posts (optional)
|
|
27217
|
+
* @param params.feedType The type of the feed: 'reviewing', 'published', or 'declined' (optional)
|
|
27218
|
+
* @param params.tags Array of tags to filter posts (optional)
|
|
27219
|
+
* @param params.includeMixedStructure Whether to include mixed structure posts (optional)
|
|
27220
|
+
* @param params.limit The maximum number of posts to retrieve (optional)
|
|
27221
|
+
* @param callback The function to call when new data are available
|
|
27222
|
+
* @param config Additional live collection configuration (optional)
|
|
27223
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the feed
|
|
27224
|
+
*
|
|
27225
|
+
* @category Posts Live Collection
|
|
27226
|
+
*/
|
|
27227
|
+
const getCommunityFeed = (params, callback, config) => {
|
|
27228
|
+
const { log, cache } = getActiveClient();
|
|
27229
|
+
if (!cache) {
|
|
27230
|
+
console.log(ENABLE_CACHE_MESSAGE);
|
|
27231
|
+
}
|
|
27232
|
+
const timestamp = Date.now();
|
|
27233
|
+
log(`getCommunityFeed(tmpid: ${timestamp}) > listen`);
|
|
27234
|
+
const communityFeedLiveCollection = new CommunityFeedLiveCollectionController(params, callback);
|
|
27235
|
+
const disposers = communityFeedLiveCollection.startSubscription();
|
|
27236
|
+
const cacheKey = communityFeedLiveCollection.getCacheKey();
|
|
27237
|
+
disposers.push(() => dropFromCache(cacheKey));
|
|
27238
|
+
return () => {
|
|
27239
|
+
log(`getCommunityFeed(tmpid: ${timestamp}) > dispose`);
|
|
27240
|
+
disposers.forEach(fn => fn());
|
|
27241
|
+
};
|
|
27242
|
+
};
|
|
27243
|
+
/* end_public_function */
|
|
27244
|
+
|
|
26581
27245
|
var index$c = /*#__PURE__*/Object.freeze({
|
|
26582
27246
|
__proto__: null,
|
|
26583
27247
|
queryGlobalFeed: queryGlobalFeed,
|
|
26584
27248
|
getCustomRankingGlobalFeed: getCustomRankingGlobalFeed,
|
|
26585
27249
|
getGlobalFeed: getGlobalFeed,
|
|
26586
|
-
getUserFeed: getUserFeed
|
|
27250
|
+
getUserFeed: getUserFeed,
|
|
27251
|
+
getCommunityFeed: getCommunityFeed
|
|
26587
27252
|
});
|
|
26588
27253
|
|
|
26589
27254
|
/* begin_public_function
|
|
@@ -27329,61 +27994,6 @@ class PostQueryStreamController extends QueryStreamController {
|
|
|
27329
27994
|
}
|
|
27330
27995
|
}
|
|
27331
27996
|
|
|
27332
|
-
const commentEventHandler = (callback, eventHandler, cacheKey, resolveId) => {
|
|
27333
|
-
return eventHandler(async (comment) => {
|
|
27334
|
-
var _a;
|
|
27335
|
-
const currentCollection = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
|
|
27336
|
-
if (!currentCollection ||
|
|
27337
|
-
!currentCollection.data.includes(resolveId ? resolveId(comment.referenceId) : comment.referenceId))
|
|
27338
|
-
return;
|
|
27339
|
-
await getPost$1(comment.referenceId);
|
|
27340
|
-
callback(comment);
|
|
27341
|
-
});
|
|
27342
|
-
};
|
|
27343
|
-
const generateCommentSubscriptions = ({ cacheKey, resolveId, }) => {
|
|
27344
|
-
const eventHandlers = [
|
|
27345
|
-
onCommentCreated,
|
|
27346
|
-
onCommentDeleted,
|
|
27347
|
-
onCommentReactionAdded,
|
|
27348
|
-
onCommentReactionRemoved,
|
|
27349
|
-
onCommentCreatedLocal,
|
|
27350
|
-
onCommentDeleteLocal,
|
|
27351
|
-
onLocalCommentReactionAdded,
|
|
27352
|
-
onLocalCommentReactionRemoved,
|
|
27353
|
-
];
|
|
27354
|
-
return eventHandlers.map(handler => ({
|
|
27355
|
-
fn: convertEventPayload((callback) => commentEventHandler(callback, handler, cacheKey, resolveId), 'referenceId', 'post'),
|
|
27356
|
-
action: EnumPostActions.OnPostUpdated,
|
|
27357
|
-
}));
|
|
27358
|
-
};
|
|
27359
|
-
const getPostSubscription = (cacheKey) => {
|
|
27360
|
-
return [
|
|
27361
|
-
{ fn: onPostCreated, action: EnumPostActions.OnPostCreated },
|
|
27362
|
-
{ fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
|
|
27363
|
-
{ fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
|
|
27364
|
-
{ fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27365
|
-
{ fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
|
|
27366
|
-
{ fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
|
|
27367
|
-
{ fn: onPostApproved, action: EnumPostActions.OnPostApproved },
|
|
27368
|
-
{ fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
|
|
27369
|
-
{ fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27370
|
-
{ fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27371
|
-
{ fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
|
|
27372
|
-
{ fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
|
|
27373
|
-
{ fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
|
|
27374
|
-
...generateCommentSubscriptions({ cacheKey }),
|
|
27375
|
-
];
|
|
27376
|
-
};
|
|
27377
|
-
const resolvePostIdsFromRooms = (rooms, posts) => {
|
|
27378
|
-
var _a;
|
|
27379
|
-
return ((_a = rooms
|
|
27380
|
-
.map(room => {
|
|
27381
|
-
const post = posts.find(post => post.postId === room.referenceId);
|
|
27382
|
-
return post ? getResolver('post')({ postId: post === null || post === void 0 ? void 0 : post.postId }) : undefined;
|
|
27383
|
-
})
|
|
27384
|
-
.filter(isNonNullable)) !== null && _a !== void 0 ? _a : []);
|
|
27385
|
-
};
|
|
27386
|
-
|
|
27387
27997
|
class PostLiveCollectionController extends LiveCollectionController {
|
|
27388
27998
|
constructor(query, callback) {
|
|
27389
27999
|
const queryStreamId = hash__default["default"](query);
|