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