@amityco/ts-sdk 0.0.1-beta.36 → 0.0.1-beta.37

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 (133) hide show
  1. package/dist/@types/core/errors.d.ts +1 -0
  2. package/dist/@types/core/errors.d.ts.map +1 -1
  3. package/dist/@types/core/events.d.ts +4 -0
  4. package/dist/@types/core/events.d.ts.map +1 -1
  5. package/dist/@types/domains/client.d.ts +21 -1
  6. package/dist/@types/domains/client.d.ts.map +1 -1
  7. package/dist/@types/global.d.ts +7 -0
  8. package/dist/@types/global.d.ts.map +1 -1
  9. package/dist/client/api/accessTokenExpiryWatcher.d.ts +4 -0
  10. package/dist/client/api/accessTokenExpiryWatcher.d.ts.map +1 -0
  11. package/dist/client/api/activeUser.d.ts +1 -1
  12. package/dist/client/api/activeUser.d.ts.map +1 -1
  13. package/dist/client/api/connectClient.d.ts +1 -1
  14. package/dist/client/api/connectClient.d.ts.map +1 -1
  15. package/dist/client/api/createClient.d.ts +1 -1
  16. package/dist/client/api/createClient.d.ts.map +1 -1
  17. package/dist/client/api/disconnectClient.d.ts +0 -1
  18. package/dist/client/api/disconnectClient.d.ts.map +1 -1
  19. package/dist/client/api/getToken.d.ts +4 -4
  20. package/dist/client/api/index.d.ts +1 -0
  21. package/dist/client/api/index.d.ts.map +1 -1
  22. package/dist/client/api/renewal.d.ts +2 -0
  23. package/dist/client/api/renewal.d.ts.map +1 -0
  24. package/dist/client/api/setSessionState.d.ts +12 -0
  25. package/dist/client/api/setSessionState.d.ts.map +1 -0
  26. package/dist/client/api/terminateClient.d.ts +9 -0
  27. package/dist/client/api/terminateClient.d.ts.map +1 -0
  28. package/dist/client/api/tests/accessTokenExpiryWatcher.test.d.ts +2 -0
  29. package/dist/client/api/tests/accessTokenExpiryWatcher.test.d.ts.map +1 -0
  30. package/dist/client/api/tests/connectClient.test.d.ts +2 -0
  31. package/dist/client/api/tests/connectClient.test.d.ts.map +1 -0
  32. package/dist/client/api/tests/disconnectClient.test.d.ts +2 -0
  33. package/dist/client/api/tests/disconnectClient.test.d.ts.map +1 -0
  34. package/dist/client/api/tests/getToken.test.d.ts +2 -0
  35. package/dist/client/api/tests/getToken.test.d.ts.map +1 -0
  36. package/dist/client/api/tests/renewal.test.d.ts +2 -0
  37. package/dist/client/api/tests/renewal.test.d.ts.map +1 -0
  38. package/dist/client/api/tests/setSessionState.test.d.ts +2 -0
  39. package/dist/client/api/tests/setSessionState.test.d.ts.map +1 -0
  40. package/dist/client/api/tests/terminateClient.test.d.ts +2 -0
  41. package/dist/client/api/tests/terminateClient.test.d.ts.map +1 -0
  42. package/dist/client/events/index.d.ts +1 -0
  43. package/dist/client/events/index.d.ts.map +1 -1
  44. package/dist/client/events/onClientBanned.d.ts +1 -1
  45. package/dist/client/events/onClientBanned.d.ts.map +1 -1
  46. package/dist/client/events/onSessionStateChange.d.ts +17 -0
  47. package/dist/client/events/onSessionStateChange.d.ts.map +1 -0
  48. package/dist/client/events/onTokenExpired.d.ts +17 -0
  49. package/dist/client/events/onTokenExpired.d.ts.map +1 -0
  50. package/dist/client/events/onTokenTerminated.d.ts +11 -0
  51. package/dist/client/events/onTokenTerminated.d.ts.map +1 -0
  52. package/dist/client/events/tests/onSessionStateChange.test.d.ts +2 -0
  53. package/dist/client/events/tests/onSessionStateChange.test.d.ts.map +1 -0
  54. package/dist/client/events/tests/onTokenTerminated.test.d.ts +2 -0
  55. package/dist/client/events/tests/onTokenTerminated.test.d.ts.map +1 -0
  56. package/dist/client/utils/setClientToken.d.ts +19 -0
  57. package/dist/client/utils/setClientToken.d.ts.map +1 -0
  58. package/dist/comment/events/tests/onCommentDeleted.test.d.ts +2 -0
  59. package/dist/comment/events/tests/onCommentDeleted.test.d.ts.map +1 -0
  60. package/dist/core/events.d.ts +3 -3
  61. package/dist/core/events.d.ts.map +1 -1
  62. package/dist/core/subscription.d.ts.map +1 -1
  63. package/dist/core/transports/http.d.ts.map +1 -1
  64. package/dist/index.cjs.js +503 -137
  65. package/dist/index.esm.js +502 -138
  66. package/dist/index.umd.js +4 -4
  67. package/dist/stream/api/tests/createStream.test.d.ts +2 -0
  68. package/dist/stream/api/tests/createStream.test.d.ts.map +1 -0
  69. package/dist/stream/api/tests/deleteStream.test.d.ts +2 -0
  70. package/dist/stream/api/tests/deleteStream.test.d.ts.map +1 -0
  71. package/dist/stream/api/tests/getStream.test.d.ts +2 -0
  72. package/dist/stream/api/tests/getStream.test.d.ts.map +1 -0
  73. package/dist/subChannel/api/tests/createSubChannel.test.d.ts +2 -0
  74. package/dist/subChannel/api/tests/createSubChannel.test.d.ts.map +1 -0
  75. package/dist/utils/constants.d.ts +2 -0
  76. package/dist/utils/constants.d.ts.map +1 -1
  77. package/dist/utils/tests/client.d.ts.map +1 -1
  78. package/dist/utils/tests/dummy/index.d.ts +2 -0
  79. package/dist/utils/tests/dummy/index.d.ts.map +1 -1
  80. package/dist/utils/tests/dummy/stream.d.ts +83 -0
  81. package/dist/utils/tests/dummy/stream.d.ts.map +1 -0
  82. package/dist/utils/tests/dummy/subChannel.d.ts +20 -0
  83. package/dist/utils/tests/dummy/subChannel.d.ts.map +1 -1
  84. package/dist/utils/tests/dummy/token.d.ts +11 -0
  85. package/dist/utils/tests/dummy/token.d.ts.map +1 -0
  86. package/package.json +1 -1
  87. package/src/@types/core/errors.ts +1 -0
  88. package/src/@types/core/events.ts +6 -0
  89. package/src/@types/domains/client.ts +45 -1
  90. package/src/@types/global.ts +14 -0
  91. package/src/client/api/accessTokenExpiryWatcher.ts +83 -0
  92. package/src/client/api/activeUser.ts +1 -1
  93. package/src/client/api/connectClient.ts +105 -24
  94. package/src/client/api/createClient.ts +9 -1
  95. package/src/client/api/disconnectClient.ts +26 -2
  96. package/src/client/api/getToken.ts +6 -6
  97. package/src/client/api/index.ts +2 -0
  98. package/src/client/api/renewal.ts +74 -0
  99. package/src/client/api/setSessionState.ts +75 -0
  100. package/src/client/api/terminateClient.ts +20 -0
  101. package/src/client/api/tests/accessTokenExpiryWatcher.test.ts +129 -0
  102. package/src/client/api/tests/connectClient.test.ts +84 -0
  103. package/src/client/api/tests/createClient.test.ts +8 -0
  104. package/src/client/api/tests/disconnectClient.test.ts +78 -0
  105. package/src/client/api/tests/getToken.test.ts +36 -0
  106. package/src/client/api/tests/renewal.test.ts +67 -0
  107. package/src/client/api/tests/setSessionState.test.ts +62 -0
  108. package/src/client/api/tests/terminateClient.test.ts +29 -0
  109. package/src/client/events/index.ts +2 -0
  110. package/src/client/events/onClientBanned.ts +12 -5
  111. package/src/client/events/onSessionStateChange.ts +31 -0
  112. package/src/client/events/onTokenExpired.ts +26 -0
  113. package/src/client/events/onTokenTerminated.ts +20 -0
  114. package/src/client/events/tests/onSessionStateChange.test.ts +37 -0
  115. package/src/client/events/tests/onTokenTerminated.test.ts +37 -0
  116. package/src/client/tests/connectClient.test.ts +6 -1
  117. package/src/client/utils/setClientToken.ts +39 -0
  118. package/src/comment/events/tests/onCommentDeleted.test.ts +27 -0
  119. package/src/core/events.ts +5 -3
  120. package/src/core/subscription.ts +3 -1
  121. package/src/core/transports/http.ts +36 -1
  122. package/src/core/transports/mqtt.ts +1 -1
  123. package/src/external/api/createUserToken.ts +2 -2
  124. package/src/stream/api/tests/createStream.test.ts +30 -0
  125. package/src/stream/api/tests/deleteStream.test.ts +48 -0
  126. package/src/stream/api/tests/getStream.test.ts +23 -0
  127. package/src/subChannel/api/tests/createSubChannel.test.ts +103 -0
  128. package/src/utils/constants.ts +2 -0
  129. package/src/utils/tests/client.ts +18 -2
  130. package/src/utils/tests/dummy/index.ts +3 -0
  131. package/src/utils/tests/dummy/stream.ts +86 -0
  132. package/src/utils/tests/dummy/subChannel.ts +22 -0
  133. package/src/utils/tests/dummy/token.ts +12 -0
package/dist/index.cjs.js CHANGED
@@ -1140,6 +1140,9 @@ const WS_EVENTS = [
1140
1140
  'connect_error',
1141
1141
  'reconnect_error',
1142
1142
  'reconnect_failed',
1143
+ 'sessionStateChange',
1144
+ // for internal use by accessTokenExpiryWatcher
1145
+ 'tokenExpired',
1143
1146
  ];
1144
1147
  const MQTT_EVENTS = [
1145
1148
  'connect',
@@ -1149,6 +1152,7 @@ const MQTT_EVENTS = [
1149
1152
  'close',
1150
1153
  'end',
1151
1154
  'reconnect',
1155
+ 'user.didGlobalBan',
1152
1156
  ];
1153
1157
  /** @hidden */
1154
1158
  const createEventEmitter = () => {
@@ -1167,7 +1171,6 @@ const createEventEmitter = () => {
1167
1171
  const proxyWebsocketEvents = (ws, emitter) => {
1168
1172
  WS_EVENTS.forEach(event => {
1169
1173
  ws.on(event, (param) => {
1170
- console.log('ws', event, param);
1171
1174
  emitter.emit(event, param);
1172
1175
  });
1173
1176
  });
@@ -1175,14 +1178,12 @@ const proxyWebsocketEvents = (ws, emitter) => {
1175
1178
  const proxyMqttEvents = (mqttClient, emitter) => {
1176
1179
  MQTT_EVENTS.forEach(event => {
1177
1180
  mqttClient.on(event, (...params) => {
1178
- console.log('mqtt', event, params);
1179
1181
  emitter.emit(event, params.length === 1 ? params[0] : params);
1180
1182
  });
1181
1183
  });
1182
1184
  // @ts-ignore
1183
1185
  mqttClient.on('message', (topic, payload) => {
1184
1186
  const message = JSON.parse(payload.toString());
1185
- console.log('mqtt message', message);
1186
1187
  emitter.emit(message.eventType, message.data);
1187
1188
  });
1188
1189
  };
@@ -1325,7 +1326,9 @@ const getSmartFeedMessageTopic = () => {
1325
1326
  let mqttAccessToken;
1326
1327
  let mqttUserId;
1327
1328
  function subscribeTopic(topic, callback) {
1328
- const { mqtt, emitter, accessToken } = getActiveClient();
1329
+ var _a;
1330
+ const { mqtt, emitter, token } = getActiveClient();
1331
+ const accessToken = (_a = token === null || token === void 0 ? void 0 : token.accessToken) !== null && _a !== void 0 ? _a : '';
1329
1332
  const user = getActiveUser();
1330
1333
  if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
1331
1334
  mqttAccessToken = accessToken;
@@ -1423,12 +1426,32 @@ const createHttpTransport = (endpoint) => {
1423
1426
  httpsAgent: new HttpAgent.HttpsAgent(options),
1424
1427
  paramsSerializer: stringify,
1425
1428
  });
1429
+ instance.interceptors.request.use(config => {
1430
+ var _a;
1431
+ // check global.ts for the extension of AxiosRequestConfig
1432
+ const tokenExpiry = (_a = config.metadata) === null || _a === void 0 ? void 0 : _a.tokenExpiry;
1433
+ if (tokenExpiry) {
1434
+ if (Date.now() >= Date.parse(tokenExpiry)) {
1435
+ return Object.assign(Object.assign({}, config), { cancelToken: new axios__default["default"].CancelToken(cancel => cancel('Token Expired')) });
1436
+ }
1437
+ }
1438
+ return config;
1439
+ });
1426
1440
  instance.interceptors.response.use(response => response, error => {
1427
1441
  var _a;
1428
1442
  const { response } = error;
1429
1443
  // eslint-disable-next-line no-console
1430
1444
  console.error((_a = response === null || response === void 0 ? void 0 : response.data) !== null && _a !== void 0 ? _a : error);
1431
- if (response)
1445
+ // handle unauthorized request
1446
+ if (response.data.code === 400100 /* Amity.ServerError.UNAUTHORIZED */) {
1447
+ fireEvent('tokenTerminated', "terminated" /* Amity.SessionStates.TERMINATED */);
1448
+ }
1449
+ // handle request cancellation
1450
+ if (axios__default["default"].isCancel(error)) {
1451
+ fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
1452
+ throw new ASCError('Token expired', 800403 /* Amity.ClientError.TOKEN_EXPIRED */, "fatal" /* Amity.ErrorLevel.FATAL */);
1453
+ }
1454
+ if (response === null || response === void 0 ? void 0 : response.data)
1432
1455
  unwrapPayload(response.data);
1433
1456
  });
1434
1457
  return instance;
@@ -20163,7 +20186,7 @@ var MqttError;
20163
20186
  MqttError[MqttError["NOT_AUTHORIZED"] = 5] = "NOT_AUTHORIZED";
20164
20187
  })(MqttError || (MqttError = {}));
20165
20188
  function getMqttOptions(params) {
20166
- return Object.assign({ clean: false, clientId: `mqttjs_ + ${Math.random().toString(16).substr(2, 8)}`, protocolId: 'MQTT', protocolVersion: 4, reconnectPeriod: 0, will: {
20189
+ return Object.assign({ clean: false, clientId: `mqttjs_ + ${Math.random().toString(16).substring(2, 10)}`, protocolId: 'MQTT', protocolVersion: 4, reconnectPeriod: 0, will: {
20167
20190
  topic: 'WillMsg',
20168
20191
  payload: 'Connection Closed abnormally..!',
20169
20192
  qos: 0,
@@ -20294,54 +20317,153 @@ const getFeedSettings = async () => {
20294
20317
  }));
20295
20318
  };
20296
20319
 
20297
- const DEFAULT_DEBUG_SESSION = 'amity';
20320
+ const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
20321
+ const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
20322
+ const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
20323
+ const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
20324
+ const UNSYNCED_OBJECT_CACHED_AT_MESSAGE = 'Observing unsynced object is not supported by Live Object.';
20325
+ const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
20326
+ const MINUTE = 60 * 1000;
20327
+ const ACCESS_TOKEN_WATCHER_INTERVAL = 10 * MINUTE;
20328
+
20329
+ // TODO: find a way to uniquely identify the device
20330
+ /** @hidden */
20331
+ const VERSION = '11.0.0';
20332
+ /** @hidden */
20333
+ const getDeviceId = () => {
20334
+ // here maybe put some auto detection of the device id based on if it's react or not?
20335
+ // anyhow we let consumer branch out if they want, but it doesn't mean we shouldn't try to be nice
20336
+ // and do things automatically
20337
+ // https://www.npmjs.com/package/react-native-device-info#getuniqueid
20338
+ // how to make sure that the react native package will not be included when build is for web
20339
+ return `ascWebSdk#${Math.random().toString(16)}`;
20340
+ };
20341
+ /** @hidden */
20342
+ const getDeviceModel = () => {
20343
+ var _a, _b;
20344
+ if ((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node)
20345
+ return safeProcess.versions.node;
20346
+ if (navigator)
20347
+ return `${navigator.product.toLowerCase()}#${(_b = navigator.userAgent) !== null && _b !== void 0 ? _b : 'unknown_agent'}`;
20348
+ return 'unknown_model';
20349
+ };
20350
+ /** @hidden */
20351
+ const getDeviceInfo = () => {
20352
+ const model = getDeviceModel();
20353
+ return {
20354
+ version: VERSION,
20355
+ // TODO: replace with: kind: process.versions ? 'node' : 'web', when backend has fixed this
20356
+ kind: 'web',
20357
+ model,
20358
+ };
20359
+ };
20360
+
20361
+ /*
20362
+ * Session States cannot be set arbitarily.
20363
+ * These are the possible new states based on the current state
20364
+ * Check tech spec for details:
20365
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-State
20366
+ */
20367
+ const sessisonStateTransitions = {
20368
+ // notLoggedIn -> establishing
20369
+ ["notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */]: ["establishing" /* Amity.SessionStates.ESTABLISHING */],
20370
+ // terminated -> establishing
20371
+ ["terminated" /* Amity.SessionStates.TERMINATED */]: ["establishing" /* Amity.SessionStates.ESTABLISHING */],
20372
+ // establishing -> notLoggedIn, established
20373
+ ["establishing" /* Amity.SessionStates.ESTABLISHING */]: [
20374
+ "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */,
20375
+ "established" /* Amity.SessionStates.ESTABLISHED */,
20376
+ ],
20377
+ /*
20378
+ * established -> notLoggedIn, terminated, tokenExpired, establishing (for
20379
+ * cases when logging in same user)
20380
+ */
20381
+ ["established" /* Amity.SessionStates.ESTABLISHED */]: [
20382
+ "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */,
20383
+ "terminated" /* Amity.SessionStates.TERMINATED */,
20384
+ "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */,
20385
+ "establishing" /* Amity.SessionStates.ESTABLISHING */,
20386
+ ],
20387
+ // tokenExpired -> establishing
20388
+ ["tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */]: ["establishing" /* Amity.SessionStates.ESTABLISHING */],
20389
+ };
20390
+ const isValidStateChange = (prevState, nextState) => {
20391
+ return sessisonStateTransitions[prevState].includes(nextState);
20392
+ };
20298
20393
  /**
20299
- * ```js
20300
- * import { createClient } from '@amityco/ts-sdk'
20301
- * const client = createClient(apiKey, 'https://asc.server/', 'myClient')
20302
- * ```
20394
+ * Checks if a {@link Amity.Client} instance is connected to ASC servers
20303
20395
  *
20304
- * Creates a new {@link Amity.Client} instance
20305
20396
  *
20306
- * @param apiKey for the {@link Amity.Client} instance
20307
- * @param apiRegion endpoint to connect to
20308
- * @param apiEndpoint custom endpoint in case you don't want to use a preset endpoint
20309
- * @param debugSession session's identifier for the client's logger instance
20310
- * @returns A {@link Amity.Client} instance
20397
+ * @param state the new session state
20398
+ * @returns a success boolean if connected
20399
+ *
20400
+ * @category private
20401
+ */
20402
+ const setSessionState = (state) => {
20403
+ const client = getActiveClient();
20404
+ client.log('client/api/setSessionState', state);
20405
+ const { sessionState: prevState } = client;
20406
+ if (prevState === state)
20407
+ return false;
20408
+ // check if transition is valid
20409
+ if (!isValidStateChange(prevState, state)) {
20410
+ throw new ASCError(`Session state cannot change from ${prevState} to ${state}`, 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "error" /* Amity.ErrorLevel.ERROR */);
20411
+ }
20412
+ client.sessionState = state;
20413
+ fireEvent('sessionStateChange', state);
20414
+ return true;
20415
+ };
20416
+
20417
+ /**
20418
+ * Retrieves a pair of {@link Amity.Tokens} necessary for connection
20419
+ *
20420
+ * @param params.userId The userId to use to issue a token
20421
+ * @param params.displayName The user's displayName
20422
+ * @param params.deviceId The user's device Id (can be manually set for native users)
20423
+ * @param params.authToken The authentication token - necessary when network option is set to secure
20424
+ * @return The accessToken for the given userId
20311
20425
  *
20312
20426
  * @category Client API
20313
- * */
20314
- const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, } = {}) => {
20315
- var _a, _b;
20316
- const log = createLogger(debugSession);
20317
- log('client/api/createClient', {
20318
- apiKey: apiKey.replace(/.{5}$/g, 'xxxxx'),
20319
- apiRegion,
20427
+ * @hidden
20428
+ */
20429
+ const getToken = async (params) => {
20430
+ const client = getActiveClient();
20431
+ client.log('client/api/getToken', params);
20432
+ const deviceInfo = getDeviceInfo();
20433
+ const { data } = await client.http.post('/api/v3/sessions', Object.assign(Object.assign({}, params), { deviceInfo }), {
20434
+ // @ts-ignore
20435
+ headers: { 'X-API-Key': client.apiKey },
20320
20436
  });
20321
- const httpEndpoint = (_a = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.http) !== null && _a !== void 0 ? _a : computeUrl('http', apiRegion);
20322
- const mqttEndpoint = (_b = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.mqtt) !== null && _b !== void 0 ? _b : computeUrl('mqtt', apiRegion);
20323
- const http = createHttpTransport(httpEndpoint);
20324
- const ws = createWebsocketTransport(httpEndpoint);
20325
- const mqtt = createMqttTransport(mqttEndpoint);
20326
- const emitter = createEventEmitter();
20327
- const client = {
20328
- version: `${VERSION$1}`,
20329
- apiKey,
20330
- log,
20331
- http,
20332
- ws,
20333
- mqtt,
20334
- emitter,
20335
- use: () => setActiveClient(client),
20336
- getFeedSettings,
20337
- };
20338
- try {
20339
- return getActiveClient();
20340
- }
20341
- catch (_c) {
20342
- setActiveClient(client);
20343
- }
20344
- return client;
20437
+ return data;
20438
+ };
20439
+
20440
+ /**
20441
+ * A util to set or refresh client token
20442
+ *
20443
+ * @param params.userId the user ID for the current session
20444
+ * @param params.displayName the user's displayName for the current session
20445
+ * @param params.deviceId Manual override of the user's device id (for device management)
20446
+ * @param params.authToken The authentication token - necessary when network option is set to secure
20447
+ * @returns token & user info
20448
+ *
20449
+ * @category private
20450
+ * @async
20451
+ */
20452
+ const setClientToken = async (params) => {
20453
+ const client = getActiveClient();
20454
+ // begin establishing session
20455
+ setSessionState("establishing" /* Amity.SessionStates.ESTABLISHING */);
20456
+ // @ts-ignore: in that particular case, typing can be
20457
+ // ignored since we enforce default values just before.
20458
+ const { accessToken, users, expiresAt, issuedAt, refreshToken } = await getToken(params);
20459
+ // manually setup the token for http transport
20460
+ client.http.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
20461
+ client.http.defaults.metadata = { tokenExpiry: expiresAt };
20462
+ // manually setup the token for ws transport
20463
+ client.ws.io.opts.query = { token: accessToken };
20464
+ client.token = { accessToken, issuedAt, expiresAt };
20465
+ setSessionState("established" /* Amity.SessionStates.ESTABLISHED */);
20466
+ return { accessToken, users, refreshToken };
20345
20467
  };
20346
20468
 
20347
20469
  /**
@@ -20352,7 +20474,6 @@ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAU
20352
20474
  *
20353
20475
  * Disconnects an {@link Amity.Client} instance from ASC servers
20354
20476
  *
20355
- * @param client The {@link Amity.Client} instance to disconnect
20356
20477
  * @returns a success boolean if disconnected
20357
20478
  *
20358
20479
  * @category Client API
@@ -20371,42 +20492,30 @@ const disconnectClient = async () => {
20371
20492
  client.ws.removeAllListeners();
20372
20493
  client.mqtt.removeAllListeners();
20373
20494
  client.userId = undefined;
20374
- client.accessToken = undefined;
20495
+ client.token = undefined;
20496
+ client.http.defaults.headers.common.Authorization = '';
20497
+ client.ws.io.opts.query = { token: '' };
20498
+ /*
20499
+ * for cases when session state is terminated (example on ban) or token expired,
20500
+ * the terminating block will set session state to terminated or for the or
20501
+ * in the case of expired token the same happens
20502
+ *
20503
+ * establishing state also ignored in cases where accessTokenExpiryWatcher
20504
+ * calls renewal. There is a possibility that renewal will be called before
20505
+ * disconnectClient finishes execution
20506
+ */
20507
+ if (client.sessionState === "established" /* Amity.SessionStates.ESTABLISHED */)
20508
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
20509
+ /*
20510
+ * Cache should be usable if tokenExpired
20511
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#SDK-usability-based-on-Session-State
20512
+ */
20513
+ if (client.sessionState !== "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */ && client.cache) {
20514
+ client.cache = { data: {} };
20515
+ }
20375
20516
  return !client.ws.connected;
20376
20517
  };
20377
20518
 
20378
- // TODO: find a way to uniquely identify the device
20379
- /** @hidden */
20380
- const VERSION = '11.0.0';
20381
- /** @hidden */
20382
- const getDeviceId = () => {
20383
- // here maybe put some auto detection of the device id based on if it's react or not?
20384
- // anyhow we let consumer branch out if they want, but it doesn't mean we shouldn't try to be nice
20385
- // and do things automatically
20386
- // https://www.npmjs.com/package/react-native-device-info#getuniqueid
20387
- // how to make sure that the react native package will not be included when build is for web
20388
- return `ascWebSdk#${Math.random().toString(16)}`;
20389
- };
20390
- /** @hidden */
20391
- const getDeviceModel = () => {
20392
- var _a, _b;
20393
- if ((_a = safeProcess.versions) === null || _a === void 0 ? void 0 : _a.node)
20394
- return safeProcess.versions.node;
20395
- if (navigator)
20396
- return `${navigator.product.toLowerCase()}#${(_b = navigator.userAgent) !== null && _b !== void 0 ? _b : 'unknown_agent'}`;
20397
- return 'unknown_model';
20398
- };
20399
- /** @hidden */
20400
- const getDeviceInfo = () => {
20401
- const model = getDeviceModel();
20402
- return {
20403
- version: VERSION,
20404
- // TODO: replace with: kind: process.versions ? 'node' : 'web', when backend has fixed this
20405
- kind: 'web',
20406
- model,
20407
- };
20408
- };
20409
-
20410
20519
  /**
20411
20520
  * Ingest a payload (v3) into the cache
20412
20521
  *
@@ -20458,26 +20567,17 @@ const createUserEventSubscriber = (event, callback) => {
20458
20567
  const onUserDeleted = (callback) => createUserEventSubscriber('user.deleted', callback);
20459
20568
 
20460
20569
  /**
20461
- * Retrieves a pair of {@link Amity.Tokens} necessary for connection
20570
+ * Terminates {@link Amity.Client} instance
20462
20571
  *
20463
- * @param userId The userId to use to issue a token
20464
- * @param displayName The user's displayName
20465
- * @param deviceId The user's device Id (can be manually set for native users)
20466
- * @param authToken The authentication token - necessary when network option is set to secure
20467
- * @return The accessToken for the given userId
20468
20572
  *
20469
- * @category Client API
20470
- * @hidden
20573
+ *
20574
+ * @category private
20471
20575
  */
20472
- const getToken = async (params) => {
20576
+ const terminateClient = () => {
20473
20577
  const client = getActiveClient();
20474
- client.log('client/api/getToken', params);
20475
- const deviceInfo = await getDeviceInfo();
20476
- const { data } = await client.http.post('/v1/device', Object.assign(Object.assign({}, params), { deviceInfo }), {
20477
- // @ts-ignore
20478
- headers: { 'X-API-Key': client.apiKey },
20479
- });
20480
- return data;
20578
+ setSessionState("terminated" /* Amity.SessionStates.TERMINATED */);
20579
+ client.sessionHandler = undefined;
20580
+ disconnectClient();
20481
20581
  };
20482
20582
 
20483
20583
  const EVENTS = [
@@ -20552,12 +20652,71 @@ const onClientDisconnected = (callback) => {
20552
20652
  * @category Client Events
20553
20653
  */
20554
20654
  const onClientBanned = (callback) => {
20555
- return onConnectionError(({ code }) => {
20556
- code === 400312 /* Amity.ServerError.GLOBAL_BAN */ && callback();
20557
- });
20655
+ const client = getActiveClient();
20656
+ return createEventSubscriber(client, `client/onConnectionError(user.didGlobalBan)`, 'user.didGlobalBan', callback);
20657
+ };
20658
+
20659
+ /**
20660
+ * ```js
20661
+ * import { onSessionStateChange } from '@amityco/ts-sdk'
20662
+ * const dispose = onSessionStateChange((state: Amity.SessionStates) => {
20663
+ * // ...
20664
+ * })
20665
+ * ```
20666
+ *
20667
+ * Fired when any {@link Amity.Client} has a session state change
20668
+ *
20669
+ * @param callback The function to call when the event was fired
20670
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20671
+ *
20672
+ * @category Client Events
20673
+ */
20674
+ const onSessionStateChange = (callback) => {
20675
+ const client = getActiveClient();
20676
+ return createEventSubscriber(client, `client/onSessionStateChange`, 'sessionStateChange', callback);
20677
+ };
20678
+
20679
+ /**
20680
+ * ```js
20681
+ * import { onTokenExpired } from '@amityco/ts-sdk'
20682
+ * const dispose = onTokenExpired((state: Amity.SessionStates.TOKEN_EXPIRED) => {
20683
+ * // ...
20684
+ * })
20685
+ * ```
20686
+ *
20687
+ * Fired when any {@link Amity.Client} session state has expired
20688
+ *
20689
+ * @param callback The function to call when the event was fired
20690
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20691
+ *
20692
+ * @category private
20693
+ */
20694
+ const onTokenExpired = (callback) => {
20695
+ const client = getActiveClient();
20696
+ return createEventSubscriber(client, `client/onTokenExpired`, 'tokenExpired', callback);
20697
+ };
20698
+
20699
+ /**
20700
+ *
20701
+ * Fired when any {@link Amity.Client} session state has terminated
20702
+ *
20703
+ * @param callback The function to call when the event was fired
20704
+ * @returns an {@link Amity.Unsubscriber} function to stop listening
20705
+ *
20706
+ * @category private
20707
+ */
20708
+ const onTokenTerminated = (callback) => {
20709
+ const client = getActiveClient();
20710
+ return createEventSubscriber(client, `client/onTokenTerminated`, 'tokenTerminated', callback);
20558
20711
  };
20559
20712
 
20560
20713
  /* eslint-disable no-param-reassign */
20714
+ /*
20715
+ * declared earlier to accomodate case when logging in with a different user
20716
+ * than the one already connected, in which case the existing subscriptions need
20717
+ * to be cleared
20718
+ */
20719
+ const subscriptions = [];
20561
20720
  /**
20562
20721
  * ```js
20563
20722
  * import { connectClient } from '@amityco/ts-sdk/client/api'
@@ -20578,46 +20737,258 @@ const onClientBanned = (callback) => {
20578
20737
  * @category Client API
20579
20738
  * @async
20580
20739
  */
20581
- const connectClient = async (params, config) => {
20582
- var _a;
20740
+ const connectClient = async (params, sessionHandler, config) => {
20741
+ var _a, _b, _c;
20583
20742
  const client = getActiveClient();
20584
- client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey }, params));
20743
+ let unsubWatcher;
20744
+ client.log('client/api/connectClient', Object.assign({ apiKey: client.apiKey, sessionState: client.sessionState }, params));
20745
+ // if connecting to a different userId than the one that is connected currently
20746
+ if (client.userId && client.userId !== params.userId) {
20747
+ await disconnectClient();
20748
+ // Remove subscription to ban and delete
20749
+ subscriptions.forEach(fn => fn());
20750
+ }
20585
20751
  // default values
20586
20752
  (_a = params.deviceId) !== null && _a !== void 0 ? _a : (params.deviceId = getDeviceId());
20587
- // @ts-ignore: in that particular case, typing can be
20588
- // ignored since we enforce default values just before.
20589
- const { accessToken, users } = await getToken(params);
20590
- // manually setup the token for http, ws transport
20591
- client.http.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
20592
- client.ws.io.opts.query = { token: accessToken };
20593
- // FIXME: events are duplicated if connectClient is called few times without disconnectClient
20594
- // wire websocket events to our event emitter
20595
- proxyWebsocketEvents(client.ws, client.emitter);
20596
- // TODO: in phase 2, this should not be necessary. we should have WS
20597
- // to be connected "on demand" rather than "by default"
20598
- await new Promise(resolve => {
20599
- client.ws.once('connect', resolve);
20600
- client.ws.open();
20601
- });
20602
- client.userId = params.userId;
20603
- client.accessToken = accessToken;
20604
- setActiveUser(users[0]);
20753
+ try {
20754
+ // @ts-ignore: in that particular case, typing can be
20755
+ // ignored since we enforce default values just before.
20756
+ const { users } = await setClientToken(params);
20757
+ // FIXME: events are duplicated if connectClient is called few times without disconnectClient
20758
+ // wire websocket events to our event emitter
20759
+ proxyWebsocketEvents(client.ws, client.emitter);
20760
+ // TODO: in phase 2, this should not be necessary. we should have WS
20761
+ // to be connected "on demand" rather than "by default"
20762
+ await new Promise(resolve => {
20763
+ client.ws.once('connect', resolve);
20764
+ client.ws.open();
20765
+ });
20766
+ client.userId = params.userId;
20767
+ client.sessionHandler = sessionHandler;
20768
+ /*
20769
+ * Cannot push to subscriptions as watcher needs to continue working even if
20770
+ * token expires
20771
+ */
20772
+ unsubWatcher = client.accessTokenExpiryWatcher((_b = client.token) === null || _b === void 0 ? void 0 : _b.issuedAt, (_c = client.token) === null || _c === void 0 ? void 0 : _c.expiresAt, sessionHandler);
20773
+ setActiveUser(users[0]);
20774
+ }
20775
+ catch (error) {
20776
+ /*
20777
+ * if getting token failed session state reverts to initial state when app
20778
+ * is first launched
20779
+ */
20780
+ setSessionState("notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */);
20781
+ // pass error down tree so the calling function handle it
20782
+ throw error;
20783
+ }
20605
20784
  if ((config === null || config === void 0 ? void 0 : config.disableRTE) !== true) {
20606
20785
  subscribeTopic(getNetworkTopic());
20607
20786
  subscribeTopic(getSmartFeedChannelTopic());
20608
20787
  subscribeTopic(getSmartFeedSubChannelTopic());
20609
20788
  subscribeTopic(getSmartFeedMessageTopic());
20789
+ // subscribing to user topic is necessary to handle ban event
20790
+ subscribeTopic(getUserTopic(getActiveUser()));
20610
20791
  }
20611
- const subscriptions = [
20612
- onClientBanned(() => {
20613
- disconnectClient();
20792
+ subscriptions.push(
20793
+ // GLOBAL_BAN
20794
+ onClientBanned((_) => {
20795
+ terminateClient();
20796
+ subscriptions.forEach(fn => fn());
20797
+ unsubWatcher();
20798
+ }), onTokenTerminated(_ => {
20799
+ terminateClient();
20800
+ subscriptions.forEach(fn => fn());
20801
+ unsubWatcher();
20802
+ }), onUserDeleted((user) => {
20803
+ if (user.userId === client.userId) {
20804
+ terminateClient();
20614
20805
  subscriptions.forEach(fn => fn());
20615
- }),
20616
- onUserDeleted(() => null),
20617
- ];
20806
+ unsubWatcher();
20807
+ }
20808
+ }), onTokenExpired(state => {
20809
+ setSessionState(state);
20810
+ disconnectClient();
20811
+ subscriptions.forEach(fn => fn());
20812
+ }), onUserDeleted(() => null));
20618
20813
  return client.ws.connected;
20619
20814
  };
20620
20815
 
20816
+ /*
20817
+ * Renewal defintion accepted by SessionHandler interface
20818
+ *
20819
+ * Tech Spec:
20820
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Session-Handler
20821
+ *
20822
+ * @category private
20823
+ */
20824
+ const renewal = () => {
20825
+ let tokenRenewed = false;
20826
+ let renewTimeoutId;
20827
+ const client = getActiveClient();
20828
+ client.log('initiating access token renewal');
20829
+ /*
20830
+ * Renews a token if it is hasn't been renewed before. Also marks token as
20831
+ * renewed once done
20832
+ * Per instance of Renewal, only one renewal is allowed
20833
+ */
20834
+ const renewToken = async (authToken) => {
20835
+ const { userId, displayName } = getActiveUser();
20836
+ const deviceId = getDeviceId();
20837
+ const params = { userId, displayName, authToken, deviceId };
20838
+ if (client.sessionState === "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */) {
20839
+ // sessionHandler will never be empty when renewal is instantiatied
20840
+ await connectClient(params, client.sessionHandler);
20841
+ }
20842
+ else {
20843
+ // about to expire
20844
+ // @ts-ignore: in that particular case, typing can be
20845
+ // ignored since we enforce default values just before.
20846
+ await setClientToken(params);
20847
+ }
20848
+ tokenRenewed = true;
20849
+ if (renewTimeoutId)
20850
+ clearTimeout(renewTimeoutId);
20851
+ };
20852
+ return {
20853
+ renew: () => {
20854
+ if (tokenRenewed) {
20855
+ console.log("'renew' method can be called only once per renewal instance");
20856
+ return;
20857
+ }
20858
+ renewToken();
20859
+ },
20860
+ renewWithAuthToken: (authToken) => {
20861
+ if (tokenRenewed) {
20862
+ console.log("'renewWithAuthToken' method can be called only once per renewal instance");
20863
+ return;
20864
+ }
20865
+ renewToken(authToken);
20866
+ },
20867
+ unableToRetrieveAuthToken: () => {
20868
+ renewTimeoutId = setTimeout(() => {
20869
+ var _a;
20870
+ (_a = client.sessionHandler) === null || _a === void 0 ? void 0 : _a.sessionWillRenewAccessToken(renewal());
20871
+ }, ACCESS_TOKEN_WATCHER_INTERVAL);
20872
+ },
20873
+ };
20874
+ };
20875
+
20876
+ const ABOUT_TO_EXPIRE_THRESHOLD = 80 / 100;
20877
+ const COMPENSATED_DELAY = 5 * MINUTE;
20878
+ /*
20879
+ * a helper function to check if the token has expires
20880
+ *
20881
+ * @param token to be checked
20882
+ * @returns boolean indicating if token expires
20883
+ *
20884
+ * @category private
20885
+ */
20886
+ const isExpired = (expiresAt) => Date.now() > Date.parse(expiresAt) - COMPENSATED_DELAY;
20887
+ /*
20888
+ * a helper function to check if the token is about to expire
20889
+ *
20890
+ * @param token to be checked
20891
+ * @returns boolean indicating if token is aboutToExpire
20892
+ *
20893
+ * @category private
20894
+ */
20895
+ const isAboutToExpire = (expiresAt, issuedAt) => {
20896
+ const expires = Date.parse(expiresAt);
20897
+ const issued = Date.parse(issuedAt);
20898
+ const now = Date.now();
20899
+ const duration = expires - issued - COMPENSATED_DELAY;
20900
+ const aboutToExpireAt = issued + duration * ABOUT_TO_EXPIRE_THRESHOLD;
20901
+ return now > aboutToExpireAt && now < expires;
20902
+ };
20903
+ /*
20904
+ * Monitors time to expire of token and updates session state to aboutToExpire
20905
+ *
20906
+ * @returns intervalId to be cleared after trigger
20907
+ *
20908
+ * @category private
20909
+ */
20910
+ const accessTokenExpiryWatcher = (expiresAt, issuedAt, sessionHandler) => {
20911
+ const interval = setInterval(() => {
20912
+ if (isExpired(expiresAt)) {
20913
+ /*
20914
+ * the event handler will take care of updating session state
20915
+ * Note, this will also clear the interval id, so this event will only be
20916
+ * fired once
20917
+ */
20918
+ fireEvent('tokenExpired', "tokenExpired" /* Amity.SessionStates.TOKEN_EXPIRED */);
20919
+ /*
20920
+ * https://ekoapp.atlassian.net/wiki/spaces/UP/pages/2082537485/ASC+Core+-+Session+Management+3.0#Automatically-initiate-renewal-flow
20921
+ *
20922
+ * Why sechduled task?
20923
+ * Since fireEvent is scheduled, it will be called
20924
+ * after sessionHandler leading to an invalid state change from
20925
+ * establishing to tokenExpired
20926
+ */
20927
+ scheduleTask(() => sessionHandler.sessionWillRenewAccessToken(renewal()));
20928
+ return;
20929
+ }
20930
+ if (isAboutToExpire(issuedAt, expiresAt)) {
20931
+ sessionHandler.sessionWillRenewAccessToken(renewal());
20932
+ }
20933
+ }, ACCESS_TOKEN_WATCHER_INTERVAL);
20934
+ return () => clearInterval(interval);
20935
+ };
20936
+
20937
+ const DEFAULT_DEBUG_SESSION = 'amity';
20938
+ /**
20939
+ * ```js
20940
+ * import { createClient } from '@amityco/ts-sdk'
20941
+ * const client = createClient(apiKey, 'https://asc.server/', 'myClient')
20942
+ * ```
20943
+ *
20944
+ * Creates a new {@link Amity.Client} instance
20945
+ *
20946
+ * @param apiKey for the {@link Amity.Client} instance
20947
+ * @param apiRegion endpoint to connect to
20948
+ * @param apiEndpoint custom endpoint in case you don't want to use a preset endpoint
20949
+ * @param param.debugSession session's identifier for the client's logger instance
20950
+ * @returns A {@link Amity.Client} instance
20951
+ *
20952
+ * @category Client API
20953
+ * */
20954
+ const createClient = (apiKey, apiRegion = API_REGIONS.SG, { debugSession = DEFAULT_DEBUG_SESSION, apiEndpoint, } = {}) => {
20955
+ var _a, _b;
20956
+ const log = createLogger(debugSession);
20957
+ log('client/api/createClient', {
20958
+ apiKey: apiKey.replace(/.{5}$/g, 'xxxxx'),
20959
+ apiRegion,
20960
+ });
20961
+ const httpEndpoint = (_a = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.http) !== null && _a !== void 0 ? _a : computeUrl('http', apiRegion);
20962
+ const mqttEndpoint = (_b = apiEndpoint === null || apiEndpoint === void 0 ? void 0 : apiEndpoint.mqtt) !== null && _b !== void 0 ? _b : computeUrl('mqtt', apiRegion);
20963
+ const http = createHttpTransport(httpEndpoint);
20964
+ const ws = createWebsocketTransport(httpEndpoint);
20965
+ const mqtt = createMqttTransport(mqttEndpoint);
20966
+ const emitter = createEventEmitter();
20967
+ const sessionState = "notLoggedIn" /* Amity.SessionStates.NOT_LOGGED_IN */;
20968
+ const sessionHandler = undefined;
20969
+ const client = {
20970
+ version: `${VERSION$1}`,
20971
+ apiKey,
20972
+ log,
20973
+ http,
20974
+ ws,
20975
+ mqtt,
20976
+ emitter,
20977
+ accessTokenExpiryWatcher,
20978
+ use: () => setActiveClient(client),
20979
+ sessionState,
20980
+ sessionHandler,
20981
+ getFeedSettings,
20982
+ };
20983
+ try {
20984
+ return getActiveClient();
20985
+ }
20986
+ catch (_c) {
20987
+ setActiveClient(client);
20988
+ }
20989
+ return client;
20990
+ };
20991
+
20621
20992
  /**
20622
20993
  * ```js
20623
20994
  * import { isConnected } from '@amityco/ts-sdk'
@@ -21027,13 +21398,6 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
21027
21398
  */
21028
21399
  const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
21029
21400
 
21030
- const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
21031
- const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
21032
- const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
21033
- const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
21034
- const UNSYNCED_OBJECT_CACHED_AT_MESSAGE = 'Observing unsynced object is not supported by Live Object.';
21035
- const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
21036
-
21037
21401
  /**
21038
21402
  * ```js
21039
21403
  * import { onUserFetched } from '@amityco/ts-sdk'
@@ -29195,9 +29559,9 @@ const onStreamRecorded = (callback) => {
29195
29559
  */
29196
29560
  const createUserToken = async (apiKey, apiRegion, params) => {
29197
29561
  const deviceId = getDeviceId();
29198
- const deviceInfo = await getDeviceInfo();
29562
+ const deviceInfo = getDeviceInfo();
29199
29563
  const http = createHttpTransport(computeUrl('http', apiRegion));
29200
- const { data } = await http.post('/api/v3/sessions', Object.assign(Object.assign({}, params), { deviceId, deviceInfo: Object.assign(Object.assign({}, deviceInfo), { model: 'token management API on TS-SDK' }) }), { headers: { 'X-API-Key': apiKey } });
29564
+ const { data } = await http.post('/api/v4/sessions', Object.assign(Object.assign({}, params), { deviceId, deviceInfo: Object.assign(Object.assign({}, deviceInfo), { model: 'token management API on TS-SDK' }) }), { headers: { 'X-API-Key': apiKey } });
29201
29565
  return { accessToken: data.accessToken };
29202
29566
  };
29203
29567
 
@@ -29401,6 +29765,7 @@ exports.onReactionAdded = onReactionAdded;
29401
29765
  exports.onReactionRemoved = onReactionRemoved;
29402
29766
  exports.onReactorAdded = onReactorAdded;
29403
29767
  exports.onReactorRemoved = onReactorRemoved;
29768
+ exports.onSessionStateChange = onSessionStateChange;
29404
29769
  exports.onStreamRecorded = onStreamRecorded;
29405
29770
  exports.onStreamStarted = onStreamStarted;
29406
29771
  exports.onStreamStopped = onStreamStopped;
@@ -29439,6 +29804,7 @@ exports.removeChannelMembersRole = removeChannelMembersRole;
29439
29804
  exports.removeCommunityMembers = removeCommunityMembers;
29440
29805
  exports.removeCommunityMembersRoles = removeCommunityMembersRoles;
29441
29806
  exports.removeReaction = removeReaction;
29807
+ exports.renewal = renewal;
29442
29808
  exports.restoreCache = restoreCache;
29443
29809
  exports.runQuery = runQuery;
29444
29810
  exports.sortByChannelSegment = sortByChannelSegment;