@amityco/ts-sdk 7.5.4-3506dd3.0 → 7.5.4-6dc7299.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.
Files changed (45) hide show
  1. package/dist/@types/domains/channel.d.ts +1 -0
  2. package/dist/@types/domains/channel.d.ts.map +1 -1
  3. package/dist/@types/domains/group.d.ts +2 -0
  4. package/dist/@types/domains/group.d.ts.map +1 -1
  5. package/dist/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.d.ts.map +1 -1
  6. package/dist/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberLiveCollectionController.d.ts.map +1 -1
  7. package/dist/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberQueryStreamController.d.ts +2 -2
  8. package/dist/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberQueryStreamController.d.ts.map +1 -1
  9. package/dist/client/api/index.d.ts +1 -0
  10. package/dist/client/api/index.d.ts.map +1 -1
  11. package/dist/client/api/resumeSession.d.ts +32 -0
  12. package/dist/client/api/resumeSession.d.ts.map +1 -0
  13. package/dist/client/api/tests/resumeSession.test.d.ts +2 -0
  14. package/dist/client/api/tests/resumeSession.test.d.ts.map +1 -0
  15. package/dist/communityRepository/api/deleteCommunity.d.ts.map +1 -1
  16. package/dist/communityRepository/api/getCommunity.d.ts +2 -2
  17. package/dist/communityRepository/api/getCommunity.d.ts.map +1 -1
  18. package/dist/communityRepository/observers/getCommunity.d.ts.map +1 -1
  19. package/dist/communityRepository/observers/getJoinRequests/JoinRequestsPaginationController.d.ts.map +1 -1
  20. package/dist/index.cjs.js +224 -19
  21. package/dist/index.esm.js +223 -19
  22. package/dist/index.umd.js +4 -4
  23. package/dist/utils/linkedObject/channelLinkedObject.d.ts.map +1 -1
  24. package/dist/utils/linkedObject/channelMemberLinkedObject.d.ts +2 -0
  25. package/dist/utils/linkedObject/channelMemberLinkedObject.d.ts.map +1 -0
  26. package/dist/utils/linkedObject/index.d.ts +1 -0
  27. package/dist/utils/linkedObject/index.d.ts.map +1 -1
  28. package/dist/utils/tests/dummy/community.d.ts +2 -0
  29. package/dist/utils/tests/dummy/community.d.ts.map +1 -1
  30. package/package.json +2 -1
  31. package/src/@types/domains/channel.ts +1 -0
  32. package/src/@types/domains/group.ts +2 -0
  33. package/src/channelRepository/channelMembership/observers/getMembers/ChannelMemberLiveCollectionController.ts +3 -1
  34. package/src/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberLiveCollectionController.ts +2 -1
  35. package/src/channelRepository/channelMembership/observers/searchMembers/SearchChannelMemberQueryStreamController.ts +2 -2
  36. package/src/client/api/index.ts +1 -0
  37. package/src/client/api/resumeSession.ts +282 -0
  38. package/src/client/api/tests/resumeSession.test.ts +173 -0
  39. package/src/communityRepository/api/deleteCommunity.ts +2 -1
  40. package/src/communityRepository/api/getCommunity.ts +5 -7
  41. package/src/communityRepository/observers/getCommunity.ts +24 -12
  42. package/src/communityRepository/observers/getJoinRequests/JoinRequestsPaginationController.ts +1 -2
  43. package/src/utils/linkedObject/channelLinkedObject.ts +19 -0
  44. package/src/utils/linkedObject/channelMemberLinkedObject.ts +20 -0
  45. package/src/utils/linkedObject/index.ts +2 -0
package/dist/index.esm.js CHANGED
@@ -6,6 +6,7 @@ import HttpAgent, { HttpsAgent } from 'agentkeepalive';
6
6
  import io from 'socket.io-client';
7
7
  import uuid$1 from 'react-native-uuid';
8
8
  import hash from 'object-hash';
9
+ import jwtDecode from 'jwt-decode';
9
10
  import Hls from 'hls.js';
10
11
 
11
12
  var MembershipAcceptanceTypeEnum;
@@ -23386,9 +23387,35 @@ const markAsRead = async (channelId) => {
23386
23387
  return true;
23387
23388
  };
23388
23389
 
23390
+ const channelMemberLinkedObject = (channelMember) => {
23391
+ const getUser = () => {
23392
+ var _a;
23393
+ const cacheKey = ['user', 'get', channelMember.userId];
23394
+ const internalUser = (_a = pullFromCache(cacheKey)) === null || _a === void 0 ? void 0 : _a.data;
23395
+ return internalUser ? userLinkedObject(internalUser) : undefined;
23396
+ };
23397
+ return Object.assign(Object.assign({}, channelMember), { get user() {
23398
+ return getUser();
23399
+ } });
23400
+ };
23401
+
23389
23402
  const channelLinkedObject = (channel) => {
23403
+ var _a;
23404
+ let previewMembers = [];
23405
+ if (channel.type === 'conversation') {
23406
+ const channelUsers = queryCache(['channelUsers', 'get']);
23407
+ if (channelUsers && (channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.length) > 0) {
23408
+ previewMembers = ((_a = channelUsers === null || channelUsers === void 0 ? void 0 : channelUsers.filter(({ data }) => data.channelId === channel.channelId)) !== null && _a !== void 0 ? _a : [])
23409
+ // sort in ascending order by userInternalId
23410
+ .sort((a, b) => a.data.userInternalId.localeCompare(b.data.userInternalId))
23411
+ // Select only first 4 members
23412
+ .slice(0, 4)
23413
+ .map(({ data }) => channelMemberLinkedObject(data));
23414
+ }
23415
+ }
23390
23416
  return shallowClone(channel, {
23391
23417
  markAsRead: () => markAsRead(channel.channelInternalId),
23418
+ previewMembers,
23392
23419
  });
23393
23420
  };
23394
23421
 
@@ -23817,7 +23844,7 @@ class PaginationController {
23817
23844
  */
23818
23845
  class JoinRequestsPaginationController extends PaginationController {
23819
23846
  async getRequest(queryParams, token) {
23820
- const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, communityId } = queryParams, params = __rest(queryParams, ["limit", "communityId"]);
23847
+ const { limit = 20, communityId } = queryParams, params = __rest(queryParams, ["limit", "communityId"]);
23821
23848
  const options = token ? { token } : { limit };
23822
23849
  const { data: queryResponse } = await this.http.get(`/api/v4/communities/${communityId}/join`, {
23823
23850
  params: Object.assign(Object.assign({}, params), { options }),
@@ -24711,6 +24738,7 @@ const LinkedObject = {
24711
24738
  community: communityLinkedObject,
24712
24739
  invitation: invitationLinkedObject,
24713
24740
  joinRequest: joinRequestLinkedObject,
24741
+ channelMember: channelMemberLinkedObject,
24714
24742
  };
24715
24743
 
24716
24744
  const constructChannelObject = (channel) => {
@@ -25993,8 +26021,8 @@ const removeChannelMarkerCache = (channel) => {
25993
26021
  * than the one already connected, in which case the existing subscriptions need
25994
26022
  * to be cleared
25995
26023
  */
25996
- let subscriptions = [];
25997
- async function runMqtt() {
26024
+ let subscriptions$1 = [];
26025
+ async function runMqtt$1() {
25998
26026
  await modifyMqttConnection();
25999
26027
  }
26000
26028
  /* begin_public_function
@@ -26029,8 +26057,8 @@ const login = async (params, sessionHandler, config) => {
26029
26057
  if (client.userId && client.userId !== params.userId) {
26030
26058
  await logout();
26031
26059
  // Remove subscription to ban and delete
26032
- subscriptions.forEach(fn => fn());
26033
- subscriptions = [];
26060
+ subscriptions$1.forEach(fn => fn());
26061
+ subscriptions$1 = [];
26034
26062
  }
26035
26063
  // default values
26036
26064
  const defaultDeviceId = await getDeviceId();
@@ -26076,40 +26104,40 @@ const login = async (params, sessionHandler, config) => {
26076
26104
  throw error;
26077
26105
  }
26078
26106
  if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
26079
- runMqtt();
26107
+ runMqtt$1();
26080
26108
  }
26081
26109
  await initializeMessagePreviewSetting();
26082
- if (subscriptions.length === 0) {
26083
- subscriptions.push(
26110
+ if (subscriptions$1.length === 0) {
26111
+ subscriptions$1.push(
26084
26112
  // GLOBAL_BAN
26085
26113
  onClientBanned((_) => {
26086
26114
  terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
26087
- subscriptions.forEach(fn => fn());
26115
+ subscriptions$1.forEach(fn => fn());
26088
26116
  unsubWatcher();
26089
26117
  }), onTokenTerminated(_ => {
26090
26118
  terminateClient();
26091
- subscriptions.forEach(fn => fn());
26119
+ subscriptions$1.forEach(fn => fn());
26092
26120
  unsubWatcher();
26093
26121
  }), onUserDeleted$2((user) => {
26094
26122
  if (user.userId === client.userId) {
26095
26123
  terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
26096
- subscriptions.forEach(fn => fn());
26124
+ subscriptions$1.forEach(fn => fn());
26097
26125
  unsubWatcher();
26098
26126
  }
26099
26127
  }), onTokenExpired(state => {
26100
26128
  SessionWatcher$1.getInstance().setSessionState(state);
26101
26129
  logout();
26102
- subscriptions.forEach(fn => fn());
26130
+ subscriptions$1.forEach(fn => fn());
26103
26131
  }),
26104
26132
  // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
26105
26133
  // the channel because currently backend can't handle this, so every time a user is banned from
26106
26134
  // a channel or the channel is deleted the channel's unread count will not be reset to zero
26107
26135
  onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
26108
26136
  if (client.useLegacyUnreadCount) {
26109
- subscriptions.push(readReceiptSyncEngineOnLoginHandler());
26137
+ subscriptions$1.push(readReceiptSyncEngineOnLoginHandler());
26110
26138
  }
26111
26139
  else
26112
- subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
26140
+ subscriptions$1.push(legacyReadReceiptSyncEngineOnLoginHandler());
26113
26141
  }
26114
26142
  return true;
26115
26143
  };
@@ -27034,6 +27062,176 @@ const secureLogout = async () => {
27034
27062
  };
27035
27063
  /* end_public_function */
27036
27064
 
27065
+ /*
27066
+ * declared earlier to accomodate case when logging in with a different user
27067
+ * than the one already connected, in which case the existing subscriptions need
27068
+ * to be cleared
27069
+ */
27070
+ let subscriptions = [];
27071
+ async function runMqtt() {
27072
+ await modifyMqttConnection();
27073
+ }
27074
+ const isSameUserId = (token) => {
27075
+ var _a;
27076
+ const client = getActiveClient();
27077
+ const decoded = jwtDecode(token);
27078
+ return ((_a = decoded === null || decoded === void 0 ? void 0 : decoded.user) === null || _a === void 0 ? void 0 : _a.publicUserId) === client.userId;
27079
+ };
27080
+ const validateAccessToken = async ({ token, userId }) => {
27081
+ const client = getActiveClient();
27082
+ // begin establishing session
27083
+ setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
27084
+ const { data: { users }, } = await client.http.get(`/api/v3/users/${userId}`, {
27085
+ headers: {
27086
+ Authorization: `Bearer ${token.accessToken}`,
27087
+ },
27088
+ });
27089
+ const user = users.find((u) => u.userId === userId);
27090
+ client.http.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
27091
+ client.http.defaults.metadata = {
27092
+ tokenExpiry: token.expiresAt,
27093
+ isGlobalBanned: false,
27094
+ isUserDeleted: false,
27095
+ };
27096
+ client.upload.defaults.headers.common.Authorization = `Bearer ${token.accessToken}`;
27097
+ client.upload.defaults.metadata = {
27098
+ tokenExpiry: token.expiresAt,
27099
+ isGlobalBanned: false,
27100
+ isUserDeleted: false,
27101
+ };
27102
+ // manually setup the token for ws transport
27103
+ if (client.ws)
27104
+ client.ws.io.opts.query = { token: token.accessToken };
27105
+ client.token = token;
27106
+ setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
27107
+ return user;
27108
+ };
27109
+ /* begin_public_function
27110
+ id: client.resumeSession
27111
+ */
27112
+ /**
27113
+ * ```js
27114
+ * import { resumeSession } from '@amityco/ts-sdk/client/api'
27115
+ * const success = await resumeSession({
27116
+ * userId: 'XYZ123456789',
27117
+ * token: { accessToken: 'abc123', issuedAt: '2023-01-01T00:00:00Z', expiresAt: '2023-01-02T00:00:00Z' }
27118
+ * })
27119
+ * ```
27120
+ *
27121
+ * Connects an {@link Amity.Client} instance to ASC servers using an existing access token
27122
+ *
27123
+ * @param params the connect parameters
27124
+ * @param params.userId the user ID for the current session
27125
+ * @param params.token the existing access token with its metadata
27126
+ * @param sessionHandler the session handler for token renewal
27127
+ * @param config optional configuration
27128
+ * @returns a success boolean if connected
27129
+ *
27130
+ * @category Client API
27131
+ * @async
27132
+ */
27133
+ const resumeSession = async (params, sessionHandler, config) => {
27134
+ var _a;
27135
+ const client = getActiveClient();
27136
+ let unsubWatcher;
27137
+ client.log('client/api/resumeSession', Object.assign({ apiKey: client.apiKey, sessionState: client.sessionState }, params));
27138
+ // Handle existing connected user
27139
+ if (client.userId) {
27140
+ if (client.userId === params.userId && isSameUserId(params.token.accessToken)) {
27141
+ // Clear connections and listeners but preserve cache
27142
+ if (client.mqtt && client.mqtt.connected) {
27143
+ client.mqtt.disconnect();
27144
+ }
27145
+ if (client.ws && client.ws.connected) {
27146
+ client.ws.disconnect();
27147
+ }
27148
+ // Clear existing subscriptions
27149
+ subscriptions.forEach(fn => fn());
27150
+ subscriptions = [];
27151
+ }
27152
+ else {
27153
+ // Different user - do full logout
27154
+ await logout();
27155
+ // Remove subscription to ban and delete
27156
+ subscriptions.forEach(fn => fn());
27157
+ subscriptions = [];
27158
+ }
27159
+ }
27160
+ try {
27161
+ const user = await validateAccessToken(params);
27162
+ if (user == null) {
27163
+ throw new ASCError(`${params.userId} has not been found`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
27164
+ }
27165
+ if (user.isDeleted) {
27166
+ terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
27167
+ return false;
27168
+ }
27169
+ if (user.isGlobalBanned) {
27170
+ terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
27171
+ return false;
27172
+ }
27173
+ // FIXME: events are duplicated if connectClient is called few times without disconnectClient
27174
+ // wire websocket events to our event emitter
27175
+ proxyWebsocketEvents(client.ws, client.emitter);
27176
+ (_a = client.ws) === null || _a === void 0 ? void 0 : _a.open();
27177
+ client.userId = user.userId;
27178
+ client.sessionHandler = sessionHandler;
27179
+ /*
27180
+ * Cannot push to subscriptions as watcher needs to continue working even if
27181
+ * token expires
27182
+ */
27183
+ unsubWatcher = client.accessTokenExpiryWatcher(sessionHandler);
27184
+ setActiveUser(user);
27185
+ }
27186
+ catch (error) {
27187
+ /*
27188
+ * if getting token failed session state reverts to initial state when app
27189
+ * is first launched
27190
+ */
27191
+ SessionWatcher$1.getInstance().setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
27192
+ // pass error down tree so the calling function handle it
27193
+ throw error;
27194
+ }
27195
+ if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
27196
+ runMqtt();
27197
+ }
27198
+ await initializeMessagePreviewSetting();
27199
+ if (subscriptions.length === 0) {
27200
+ subscriptions.push(
27201
+ // GLOBAL_BAN
27202
+ onClientBanned((_) => {
27203
+ terminateClient("globalBan" /* Amity.TokenTerminationReason.GLOBAL_BAN */);
27204
+ subscriptions.forEach(fn => fn());
27205
+ unsubWatcher();
27206
+ }), onTokenTerminated(_ => {
27207
+ terminateClient();
27208
+ subscriptions.forEach(fn => fn());
27209
+ unsubWatcher();
27210
+ }), onUserDeleted$2((user) => {
27211
+ if (user.userId === client.userId) {
27212
+ terminateClient("userDeleted" /* Amity.TokenTerminationReason.USER_DELETED */);
27213
+ subscriptions.forEach(fn => fn());
27214
+ unsubWatcher();
27215
+ }
27216
+ }), onTokenExpired(state => {
27217
+ SessionWatcher$1.getInstance().setSessionState(state);
27218
+ logout();
27219
+ subscriptions.forEach(fn => fn());
27220
+ }),
27221
+ // NOTE: This is a temporary solution to handle the channel marker when the user is forced to leave
27222
+ // the channel because currently backend can't handle this, so every time a user is banned from
27223
+ // a channel or the channel is deleted the channel's unread count will not be reset to zero
27224
+ onChannelDeleted(removeChannelMarkerCache), onChannelMemberBanned(removeChannelMarkerCache), markReadEngineOnLoginHandler(), analyticsEngineOnLoginHandler(), objectResolverEngineOnLoginHandler());
27225
+ if (client.useLegacyUnreadCount) {
27226
+ subscriptions.push(readReceiptSyncEngineOnLoginHandler());
27227
+ }
27228
+ else
27229
+ subscriptions.push(legacyReadReceiptSyncEngineOnLoginHandler());
27230
+ }
27231
+ return true;
27232
+ };
27233
+ /* end_public_function */
27234
+
27037
27235
  /**
27038
27236
  * ```js
27039
27237
  * import { isConnected } from '@amityco/ts-sdk'
@@ -27439,6 +27637,7 @@ var index$n = /*#__PURE__*/Object.freeze({
27439
27637
  login: login,
27440
27638
  logout: logout,
27441
27639
  secureLogout: secureLogout,
27640
+ resumeSession: resumeSession,
27442
27641
  isConnected: isConnected,
27443
27642
  getFeedSettings: getFeedSettings,
27444
27643
  renewal: renewal,
@@ -35133,7 +35332,8 @@ class ChannelMemberLiveCollectionController extends LiveCollectionController {
35133
35332
  const data = this.applyFilter((_b = collection.data
35134
35333
  .map(id => pullFromCache(['channelUsers', 'get', id]))
35135
35334
  .filter(Boolean)
35136
- .map(({ data }) => data)) !== null && _b !== void 0 ? _b : []);
35335
+ .map(({ data }) => data)
35336
+ .map(LinkedObject.channelMember)) !== null && _b !== void 0 ? _b : []);
35137
35337
  if (!this.shouldNotify(data) && origin === 'event')
35138
35338
  return;
35139
35339
  this.callback({
@@ -35700,7 +35900,7 @@ const getCommunity$1 = async (communityId, type, includeDiscoverablePrivateCommu
35700
35900
  }
35701
35901
  const { communities } = data;
35702
35902
  return {
35703
- data: LinkedObject.community(communities.find(community => community.communityId === communityId)),
35903
+ data: communities.find(community => community.communityId === communityId),
35704
35904
  cachedAt,
35705
35905
  };
35706
35906
  };
@@ -35726,7 +35926,7 @@ getCommunity$1.locally = (communityId) => {
35726
35926
  if (!cached)
35727
35927
  return;
35728
35928
  return {
35729
- data: LinkedObject.community(cached.data),
35929
+ data: cached.data,
35730
35930
  cachedAt: cached.cachedAt,
35731
35931
  };
35732
35932
  };
@@ -35762,7 +35962,7 @@ const deleteCommunity = async (communityId) => {
35762
35962
  files: [],
35763
35963
  users: [],
35764
35964
  });
35765
- return deleted.data;
35965
+ return LinkedObject.community(deleted.data);
35766
35966
  };
35767
35967
  /* end_public_function */
35768
35968
 
@@ -37272,7 +37472,11 @@ const getCommunity = (communityId, callback) => {
37272
37472
  onCommunityUserUnbanned,
37273
37473
  onCommunityUserChanged,
37274
37474
  convertEventPayload(onLocalCommunityJoin, 'targetId', 'community'),
37275
- ]);
37475
+ ], {
37476
+ callbackDataSelector: (data) => {
37477
+ return LinkedObject.community(data);
37478
+ },
37479
+ });
37276
37480
  };
37277
37481
  /* end_public_function */
37278
37482