@amityco/ts-sdk 0.0.1-beta.15 → 0.0.1-beta.16

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 (142) hide show
  1. package/dist/@types/core/cache.d.ts +1 -1
  2. package/dist/@types/core/cache.d.ts.map +1 -1
  3. package/dist/@types/core/events.d.ts +10 -1
  4. package/dist/@types/core/events.d.ts.map +1 -1
  5. package/dist/@types/core/model.d.ts +4 -0
  6. package/dist/@types/core/model.d.ts.map +1 -1
  7. package/dist/@types/core/paging.d.ts +10 -10
  8. package/dist/@types/core/paging.d.ts.map +1 -1
  9. package/dist/@types/core/payload.d.ts +10 -0
  10. package/dist/@types/core/payload.d.ts.map +1 -1
  11. package/dist/@types/core/query.d.ts +5 -4
  12. package/dist/@types/core/query.d.ts.map +1 -1
  13. package/dist/@types/domains/client.d.ts +0 -1
  14. package/dist/@types/domains/client.d.ts.map +1 -1
  15. package/dist/@types/domains/follow.d.ts +20 -0
  16. package/dist/@types/domains/follow.d.ts.map +1 -0
  17. package/dist/@types/index.d.ts +1 -0
  18. package/dist/@types/index.d.ts.map +1 -1
  19. package/dist/category/api/queryCategories.d.ts +3 -3
  20. package/dist/channel/api/createChannel.d.ts +1 -1
  21. package/dist/channel/api/queryChannels.d.ts +1 -1
  22. package/dist/client/api/activeUser.d.ts +6 -0
  23. package/dist/client/api/activeUser.d.ts.map +1 -0
  24. package/dist/client/api/connectClient.d.ts.map +1 -1
  25. package/dist/community/api/getRecommendedCommunities.d.ts +32 -0
  26. package/dist/community/api/getRecommendedCommunities.d.ts.map +1 -0
  27. package/dist/community/api/getTopTrendingCommunities.d.ts +32 -0
  28. package/dist/community/api/getTopTrendingCommunities.d.ts.map +1 -0
  29. package/dist/community/api/index.d.ts +2 -0
  30. package/dist/community/api/index.d.ts.map +1 -1
  31. package/dist/community/api/queryCommunities.d.ts +1 -1
  32. package/dist/core/events.d.ts +3 -3
  33. package/dist/core/events.d.ts.map +1 -1
  34. package/dist/core/model/idResolvers.d.ts.map +1 -1
  35. package/dist/core/model/identifyModel.d.ts.map +1 -1
  36. package/dist/core/model/index.d.ts.map +1 -1
  37. package/dist/core/query/paging.d.ts +3 -3
  38. package/dist/core/query/paging.d.ts.map +1 -1
  39. package/dist/core/subscription.d.ts +2 -0
  40. package/dist/core/subscription.d.ts.map +1 -1
  41. package/dist/feed/api/queryGlobalFeed.d.ts +1 -1
  42. package/dist/follow/api/acceptFollower.d.ts +16 -0
  43. package/dist/follow/api/acceptFollower.d.ts.map +1 -0
  44. package/dist/follow/api/declineFollower.d.ts +16 -0
  45. package/dist/follow/api/declineFollower.d.ts.map +1 -0
  46. package/dist/follow/api/follow.d.ts +16 -0
  47. package/dist/follow/api/follow.d.ts.map +1 -0
  48. package/dist/follow/api/getFollowInfo.d.ts +32 -0
  49. package/dist/follow/api/getFollowInfo.d.ts.map +1 -0
  50. package/dist/follow/api/index.d.ts +8 -0
  51. package/dist/follow/api/index.d.ts.map +1 -0
  52. package/dist/follow/api/queryFollowers.d.ts +36 -0
  53. package/dist/follow/api/queryFollowers.d.ts.map +1 -0
  54. package/dist/follow/api/queryFollowings.d.ts +36 -0
  55. package/dist/follow/api/queryFollowings.d.ts.map +1 -0
  56. package/dist/follow/api/unfollow.d.ts +16 -0
  57. package/dist/follow/api/unfollow.d.ts.map +1 -0
  58. package/dist/follow/api/utils.d.ts +9 -0
  59. package/dist/follow/api/utils.d.ts.map +1 -0
  60. package/dist/follow/events/index.d.ts +9 -0
  61. package/dist/follow/events/index.d.ts.map +1 -0
  62. package/dist/follow/events/onFollowInfoUpdated.d.ts +17 -0
  63. package/dist/follow/events/onFollowInfoUpdated.d.ts.map +1 -0
  64. package/dist/follow/events/onFollowRequestAccepted.d.ts +17 -0
  65. package/dist/follow/events/onFollowRequestAccepted.d.ts.map +1 -0
  66. package/dist/follow/events/onFollowRequestCanceled.d.ts +17 -0
  67. package/dist/follow/events/onFollowRequestCanceled.d.ts.map +1 -0
  68. package/dist/follow/events/onFollowRequestDeclined.d.ts +17 -0
  69. package/dist/follow/events/onFollowRequestDeclined.d.ts.map +1 -0
  70. package/dist/follow/events/onFollowerDeleted.d.ts +17 -0
  71. package/dist/follow/events/onFollowerDeleted.d.ts.map +1 -0
  72. package/dist/follow/events/onFollowerRequested.d.ts +17 -0
  73. package/dist/follow/events/onFollowerRequested.d.ts.map +1 -0
  74. package/dist/follow/events/onUserFollowed.d.ts +17 -0
  75. package/dist/follow/events/onUserFollowed.d.ts.map +1 -0
  76. package/dist/follow/events/onUserUnfollowed.d.ts +17 -0
  77. package/dist/follow/events/onUserUnfollowed.d.ts.map +1 -0
  78. package/dist/follow/events/utils.d.ts +2 -0
  79. package/dist/follow/events/utils.d.ts.map +1 -0
  80. package/dist/follow/observers/index.d.ts +4 -0
  81. package/dist/follow/observers/index.d.ts.map +1 -0
  82. package/dist/follow/observers/observeFollowInfo.d.ts +18 -0
  83. package/dist/follow/observers/observeFollowInfo.d.ts.map +1 -0
  84. package/dist/follow/observers/observeFollowers.d.ts +18 -0
  85. package/dist/follow/observers/observeFollowers.d.ts.map +1 -0
  86. package/dist/follow/observers/observeFollowings.d.ts +18 -0
  87. package/dist/follow/observers/observeFollowings.d.ts.map +1 -0
  88. package/dist/index.cjs.js +752 -8
  89. package/dist/index.d.ts +3 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.esm.js +731 -9
  92. package/dist/index.umd.js +5 -5
  93. package/dist/post/api/queryPosts.d.ts +2 -2
  94. package/dist/post/api/queryPosts.d.ts.map +1 -1
  95. package/dist/role/api/queryRoles.d.ts +1 -1
  96. package/dist/stream/api/queryStreams.d.ts +1 -1
  97. package/package.json +1 -1
  98. package/src/@types/core/cache.ts +1 -1
  99. package/src/@types/core/events.ts +11 -0
  100. package/src/@types/core/model.ts +6 -0
  101. package/src/@types/core/paging.ts +9 -9
  102. package/src/@types/core/payload.ts +14 -0
  103. package/src/@types/core/query.ts +8 -4
  104. package/src/@types/domains/client.ts +0 -1
  105. package/src/@types/domains/follow.ts +25 -0
  106. package/src/@types/index.ts +1 -0
  107. package/src/channel/api/createChannel.ts +1 -1
  108. package/src/client/api/activeUser.ts +26 -0
  109. package/src/client/api/connectClient.ts +3 -1
  110. package/src/community/api/getRecommendedCommunities.ts +86 -0
  111. package/src/community/api/getTopTrendingCommunities.ts +86 -0
  112. package/src/community/api/index.ts +3 -0
  113. package/src/core/model/idResolvers.ts +3 -0
  114. package/src/core/model/identifyModel.ts +2 -0
  115. package/src/core/model/index.ts +3 -0
  116. package/src/core/query/paging.ts +10 -10
  117. package/src/core/subscription.ts +21 -3
  118. package/src/follow/api/acceptFollower.ts +32 -0
  119. package/src/follow/api/declineFollower.ts +32 -0
  120. package/src/follow/api/follow.ts +40 -0
  121. package/src/follow/api/getFollowInfo.ts +75 -0
  122. package/src/follow/api/index.ts +8 -0
  123. package/src/follow/api/queryFollowers.ts +42 -0
  124. package/src/follow/api/queryFollowings.ts +42 -0
  125. package/src/follow/api/unfollow.ts +32 -0
  126. package/src/follow/api/utils.ts +77 -0
  127. package/src/follow/events/index.ts +10 -0
  128. package/src/follow/events/onFollowInfoUpdated.ts +43 -0
  129. package/src/follow/events/onFollowRequestAccepted.ts +19 -0
  130. package/src/follow/events/onFollowRequestCanceled.ts +19 -0
  131. package/src/follow/events/onFollowRequestDeclined.ts +19 -0
  132. package/src/follow/events/onFollowerDeleted.ts +19 -0
  133. package/src/follow/events/onFollowerRequested.ts +19 -0
  134. package/src/follow/events/onUserFollowed.ts +19 -0
  135. package/src/follow/events/onUserUnfollowed.ts +19 -0
  136. package/src/follow/events/utils.ts +38 -0
  137. package/src/follow/observers/index.ts +3 -0
  138. package/src/follow/observers/observeFollowInfo.ts +68 -0
  139. package/src/follow/observers/observeFollowers.ts +78 -0
  140. package/src/follow/observers/observeFollowings.ts +78 -0
  141. package/src/index.ts +4 -0
  142. package/src/post/api/queryPosts.ts +2 -2
@@ -24,7 +24,7 @@ export declare const queryPosts: {
24
24
  tags?: Amity.Taggable['tags'];
25
25
  matchingOnlyParentPost?: boolean;
26
26
  page?: Amity.PageRaw;
27
- }): Promise<Amity.Cached<Amity.Paged<Amity.Post>>>;
27
+ }): Promise<Amity.Cached<Amity.Paged<Amity.Post, Amity.PageRaw>>>;
28
28
  /**
29
29
  * ```js
30
30
  * import { queryPosts } from '@amityco/ts-sdk'
@@ -38,6 +38,6 @@ export declare const queryPosts: {
38
38
  *
39
39
  * @category Post API
40
40
  */
41
- locally(query: Parameters<typeof queryPosts>[0]): Amity.Cached<Amity.Paged<Amity.Post>> | undefined;
41
+ locally(query: Parameters<typeof queryPosts>[0]): Amity.Cached<Amity.Paged<Amity.Post, Amity.PageRaw>> | undefined;
42
42
  };
43
43
  //# sourceMappingURL=queryPosts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryPosts.d.ts","sourceRoot":"","sources":["../../../src/post/api/queryPosts.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU;YACd;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,aAAa,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,CAAA;QACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,CAAA;QACnC,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,QAAQ,CAAC,EAAE,WAAW,GAAG,WAAW,CAAA;QACpC,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAA;QAChC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAA;KACrB,GACA,QAAQ,MAAM,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAuCjD;;;;;;;;;;;;OAYG;mBAEM,WAAW,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACtC,MAAM,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,SAAS;CAjBnD,CAAA"}
1
+ {"version":3,"file":"queryPosts.d.ts","sourceRoot":"","sources":["../../../src/post/api/queryPosts.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU;YACd;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,aAAa,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,CAAA;QACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,CAAA;QACnC,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,QAAQ,CAAC,EAAE,WAAW,GAAG,WAAW,CAAA;QACpC,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAA;QAChC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAA;KACrB,GACA,QAAQ,MAAM,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;IAuChE;;;;;;;;;;;;OAYG;mBAEM,WAAW,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACtC,MAAM,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS;CAjBlE,CAAA"}
@@ -17,7 +17,7 @@ export declare const queryRoles: {
17
17
  (query?: {
18
18
  displayName?: string | undefined;
19
19
  sortBy?: "displayName" | "firstCreated" | "lastCreated" | undefined;
20
- page?: Amity.Page<number> | undefined;
20
+ page?: Amity.Page | undefined;
21
21
  } | undefined): Promise<Amity.Cached<Amity.Paged<Amity.Role>>>;
22
22
  /**
23
23
  * ```js
@@ -19,7 +19,7 @@ export declare const queryStreams: {
19
19
  userPublicIds?: string[] | undefined;
20
20
  sortBy?: "lastCreated" | "firstCreated" | undefined;
21
21
  isDeleted?: Amity.Stream['isDeleted'];
22
- page?: Amity.Page<number> | undefined;
22
+ page?: Amity.Page | undefined;
23
23
  } | undefined): Promise<Amity.Cached<Amity.Paged<Amity.Stream>>>;
24
24
  /**
25
25
  * ```js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk",
3
- "version": "0.0.1-beta.15",
3
+ "version": "0.0.1-beta.16",
4
4
  "license": "CC-BY-ND-4.0",
5
5
  "author": "amity.co <developers@amity.co> (https://amity.co)",
6
6
  "description": "Amity Social Cloud Typescript SDK",
@@ -49,7 +49,7 @@ declare global {
49
49
  * Minimal CacheEntry alias, used mostly
50
50
  */
51
51
  type Cached<T extends unknown = unknown> = (
52
- T extends Amity.Paged<any>
52
+ T extends Amity.Paged<any, infer K>
53
53
  ? T
54
54
  : { data: T }
55
55
  ) & {
@@ -96,10 +96,21 @@ declare global {
96
96
  'user.flagCleared': Amity.UserPayload
97
97
  }
98
98
 
99
+ type MqttFollowMessageEvents = {
100
+ 'follow.created': Amity.FollowStatus
101
+ 'follow.requested': Amity.FollowStatus
102
+ 'follow.accepted': Amity.FollowStatus
103
+ 'follow.unfollowed': Amity.FollowStatus
104
+ 'follow.requestCanceled': Amity.FollowStatus
105
+ 'follow.requestDeclined': Amity.FollowStatus
106
+ 'follow.followerDeleted': Amity.FollowStatus
107
+ }
108
+
99
109
  type MqttMessageEvents = MqttCommunityMessageEvents
100
110
  & MqttPostMessageEvents
101
111
  & MqttCommentMessageEvents
102
112
  & MqttUserMessageEvents
113
+ & MqttFollowMessageEvents
103
114
 
104
115
  type Events = WsEvents & MqttEvents & MqttMessageEvents
105
116
  }
@@ -23,6 +23,9 @@ declare global {
23
23
  'comment': Amity.Comment
24
24
 
25
25
  'stream': Amity.Stream
26
+
27
+ 'follow': Amity.FollowStatus
28
+ 'followCount': Amity.FollowCount
26
29
  }
27
30
 
28
31
  /**
@@ -48,6 +51,9 @@ declare global {
48
51
  'comment': Pick<Amity.Comment, 'commentId'>
49
52
 
50
53
  'stream': Pick<Amity.Stream, 'streamId'>
54
+
55
+ 'follow': Pick<Amity.FollowStatus, 'from' | 'to'>
56
+ 'followCount': Pick<Amity.FollowCount, 'userId'>
51
57
  }
52
58
  }
53
59
  }
@@ -4,27 +4,27 @@ declare global {
4
4
  namespace Amity {
5
5
  type PaginationStyles = 'skiplimit' | 'afterbefore' | 'afterbeforeraw'
6
6
 
7
- type Paging = {
7
+ type PageLimit = {
8
8
  limit: number
9
9
  }
10
10
 
11
- type PrevPage<T extends number | string = number> = Paging & {
11
+ type PrevPage<T extends number | string> = PageLimit & {
12
12
  after?: never
13
13
  before?: T
14
14
  }
15
15
 
16
- type NextPage<T extends number | string = number> = Paging & {
16
+ type NextPage<T extends number | string> = PageLimit & {
17
17
  after?: T
18
18
  before?: never
19
19
  }
20
20
 
21
- type Page<T extends number | string = number> = (PrevPage<T> | NextPage<T>)
21
+ type Page = PrevPage<number> | NextPage<number>
22
22
 
23
23
  /*
24
24
  updatedAt is here because if you need sort by updatedAt you
25
25
  need to include this data in query also
26
26
  */
27
- type PageRaw = Page<string> & {
27
+ type PageRaw = (PrevPage<string> | NextPage<string>) & {
28
28
  updatedAt?: string
29
29
  }
30
30
 
@@ -50,11 +50,11 @@ declare global {
50
50
 
51
51
  type AfterBeforeRawPagination = PageRaw
52
52
 
53
- type Pages = {
54
- nextPage?: (Page | PageRaw) | null
55
- prevPage?: (Page | PageRaw) | null
53
+ type Pages<T extends (Page | PageRaw)> = {
54
+ nextPage?: T
55
+ prevPage?: T
56
56
  }
57
57
 
58
- type Paged<T> = { data: T[] } & Pages
58
+ type Paged<T, K extends (Page | PageRaw) = Page> = { data: T[] } & Pages<K>
59
59
  }
60
60
  }
@@ -98,5 +98,19 @@ declare global {
98
98
  }
99
99
 
100
100
  type GlobalFeedPayload = Amity.PostPayload
101
+
102
+ type FollowersPayload = {
103
+ follows: Amity.FollowStatus[]
104
+ }
105
+ & UserPayload
106
+
107
+ type FollowStatusPayload = {
108
+ follows: Amity.FollowStatus[]
109
+ }
110
+
111
+ type FollowInfoPayload = {
112
+ follows: Amity.FollowStatus[]
113
+ followCounts: Amity.FollowCount[]
114
+ }
101
115
  }
102
116
  }
@@ -47,12 +47,16 @@ declare global {
47
47
 
48
48
  type Snapshot<T> = (
49
49
  T extends Amity.Cached<infer T2>
50
- ? T2 extends Amity.Paged<infer T3>
51
- ? { data: T3[] | undefined } & Pages & { cachedAt?: CacheOptions['cachedAt'] }
50
+ ? T2 extends Amity.Paged<infer T3, infer T4>
51
+ ? { data: T3[] | undefined } & Pages<T4> & { cachedAt?: CacheOptions['cachedAt'] }
52
52
  : { data: T2 } & { cachedAt?: CacheOptions['cachedAt'] }
53
- : T extends Amity.Paged<infer T3>
54
- ? { data: T3[] | undefined } & Pages
53
+ : T extends Amity.Paged<infer T3, infer T4>
54
+ ? { data: T3[] | undefined } & Pages<T4>
55
55
  : { data: T | undefined }
56
56
  ) & SnapshotOptions
57
+
58
+ type RunQueryOptions<T> = T extends Amity.AsyncFunc<infer Args, infer Returned>
59
+ ? Omit<Amity.Snapshot<Returned>, 'data'>
60
+ : never
57
61
  }
58
62
  }
@@ -18,7 +18,6 @@ declare global {
18
18
 
19
19
  apiKey?: string
20
20
  userId?: string
21
- _internalUserId?: string
22
21
  accessToken?: string
23
22
 
24
23
  use: () => void
@@ -0,0 +1,25 @@
1
+ export {}
2
+
3
+ declare global {
4
+ namespace Amity {
5
+ type FollowStatus = {
6
+ from: Amity.User['userId']
7
+ to: Amity.User['userId']
8
+ status: 'pending' | 'accepted' | 'none'
9
+ }
10
+ & Amity.CreatedAt
11
+ & Amity.UpdatedAt
12
+
13
+ type FollowCount = {
14
+ userId: Amity.User['userId']
15
+ followerCount: number
16
+ followingCount: number
17
+ pendingCount: number
18
+ }
19
+
20
+ type FollowInfo = {
21
+ status?: FollowStatus['status']
22
+ }
23
+ & FollowCount
24
+ }
25
+ }
@@ -13,6 +13,7 @@ import './core/cache' // cache.pull('user', ...)
13
13
  import './domains/client' // client definition
14
14
 
15
15
  import './domains/user'
16
+ import './domains/follow'
16
17
  import './domains/file'
17
18
 
18
19
  import './domains/partials' // small model partials (CreatedAt, etc...)
@@ -17,7 +17,7 @@ import { ingestInCache } from '~/cache/api/ingestInCache'
17
17
  * @async
18
18
  */
19
19
  export const createChannel = async <T extends Amity.ChannelType>(
20
- bundle: { type: T, userIds?: Amity.User['userId'] }
20
+ bundle: { type: T, userIds?: Amity.User['userId'][] }
21
21
  & Pick<Amity.Channel<T>, 'displayName' | 'avatarFileId' | 'tags' | 'metadata'>
22
22
  ): Promise<Amity.Cached<Amity.Channel>> => {
23
23
  const client = getActiveClient()
@@ -0,0 +1,26 @@
1
+ import { ASCError } from '~/core/errors'
2
+
3
+ let activeUser: Pick<Amity.User, '_id' | 'userId' | 'path'> | null = null
4
+
5
+ /**
6
+ * for internal use
7
+ */
8
+ export const getActiveUser = () => {
9
+ if (!activeUser) {
10
+ throw new ASCError(
11
+ 'Connect client first',
12
+ Amity.ClientError.UNKNOWN_ERROR,
13
+ Amity.ErrorLevel.FATAL,
14
+ )
15
+ }
16
+
17
+ return activeUser!
18
+ }
19
+
20
+ export const setActiveUser = (user: Amity.User) => {
21
+ activeUser = {
22
+ _id: user._id,
23
+ userId: user.userId,
24
+ path: user.path,
25
+ }
26
+ }
@@ -3,6 +3,7 @@ import { getDeviceId } from '~/core/device'
3
3
  import { proxyMqttEvents, proxyWebsocketEvents } from '~/core/events'
4
4
 
5
5
  import { getActiveClient } from './activeClient'
6
+ import { setActiveUser } from './activeUser'
6
7
 
7
8
  import { getToken } from './getToken'
8
9
  import { onClientBanned } from '../events'
@@ -66,8 +67,9 @@ export const connectClient = async (params: {
66
67
  })
67
68
 
68
69
  client.userId = params.userId
69
- client._internalUserId = users[0]._id
70
70
  client.accessToken = accessToken
71
71
 
72
+ setActiveUser(users[0])
73
+
72
74
  return client.ws.connected
73
75
  }
@@ -0,0 +1,86 @@
1
+ import { getActiveClient } from '~/client/api'
2
+
3
+ import { getResolver } from '~/core/model'
4
+ import { pullFromCache, pushToCache } from '~/cache/api'
5
+ import { ingestInCache } from '~/cache/api/ingestInCache'
6
+
7
+ /**
8
+ * ```js
9
+ * import { getRecommendedCommunities } from '@amityco/ts-sdk'
10
+ * const communities = await getRecommendedCommunities()
11
+ * ```
12
+ *
13
+ * Gets a list of recommended {@link Amity.Community} objects
14
+ *
15
+ * @param query The query parameters
16
+ * @returns A list of {@link Amity.Community} objects
17
+ *
18
+ * @category Community API
19
+ * @async
20
+ */
21
+ export const getRecommendedCommunities = async (
22
+ query?: Partial<Amity.PageLimit>
23
+ ): Promise<Amity.Cached<Amity.Community[]>> => {
24
+ const client = getActiveClient()
25
+ client.log('channel/getRecommendedCommunities', query)
26
+
27
+ const { limit = 5 } = query ?? {}
28
+
29
+ // API-FIX: backend doesnt answer Amity.Response
30
+ // const { data } = await client.http.get<Amity.Response<CommunityPayload>>(
31
+ const { data } = await client.http.get<Amity.CommunityPayload>(
32
+ `/api/v3/communities/recommended`, { params: { options: { limit }}}
33
+ )
34
+
35
+ const { communities } = data
36
+
37
+ const cachedAt = client.cache && Date.now()
38
+
39
+ if (client.cache) {
40
+ ingestInCache(data, { cachedAt })
41
+
42
+ const cacheKey = ['community', 'recommended', { params: { options: { limit }} }]
43
+ pushToCache(cacheKey, { communities: communities.map(getResolver('community')) })
44
+ }
45
+
46
+ return { data: communities, cachedAt }
47
+ }
48
+
49
+ /**
50
+ * ```js
51
+ * import { getRecommendedCommunities } from '@amityco/ts-sdk'
52
+ * const communities = getRecommendedCommunities.locally()
53
+ * ```
54
+ *
55
+ * Gets a list of recommended {@link Amity.Community} objects from cache
56
+ *
57
+ * @param query The query parameters
58
+ * @returns communities
59
+ *
60
+ * @category Community API
61
+ */
62
+ getRecommendedCommunities.locally = (
63
+ query: Parameters<typeof getRecommendedCommunities>[0],
64
+ ): Amity.Cached<Amity.Community[]> | undefined => {
65
+ const client = getActiveClient()
66
+ client.log('community/getRecommendedCommunities.locally', query)
67
+
68
+ if (!client.cache) return
69
+
70
+ const { limit = 5 } = query ?? {}
71
+
72
+ const queryKey = ['community', 'recommended', { params: { options: { limit }} }];
73
+ const { data, cachedAt } = pullFromCache<{communities: Pick<Amity.Community, 'communityId'>[]}>(queryKey) ?? {}
74
+
75
+ if (!data?.communities.length)
76
+ return
77
+
78
+ const communities: Amity.Community[] = data.communities
79
+ .map(communityId => pullFromCache<Amity.Community>(['community', 'get', communityId])!)
80
+ .filter(Boolean)
81
+ .map(({ data }) => data)
82
+
83
+ return communities.length === data?.communities?.length
84
+ ? { data: communities, cachedAt }
85
+ : undefined
86
+ }
@@ -0,0 +1,86 @@
1
+ import { getActiveClient } from '~/client/api'
2
+
3
+ import { getResolver } from '~/core/model'
4
+ import { pullFromCache, pushToCache } from '~/cache/api'
5
+ import { ingestInCache } from '~/cache/api/ingestInCache'
6
+
7
+ /**
8
+ * ```js
9
+ * import { getTopTrendingCommunities } from '@amityco/ts-sdk'
10
+ * const trendingCommunities = await getTopTrendingCommunities()
11
+ * ```
12
+ *
13
+ * Gets a list of top trending {@link Amity.Community} objects
14
+ *
15
+ * @param query The query parameters
16
+ * @returns A list of {@link Amity.Community} objects
17
+ *
18
+ * @category Community API
19
+ * @async
20
+ */
21
+ export const getTopTrendingCommunities = async (
22
+ query?: Partial<Amity.PageLimit>
23
+ ): Promise<Amity.Cached<Amity.Community[]>> => {
24
+ const client = getActiveClient()
25
+ client.log('channel/getTopTrendingCommunities', query)
26
+
27
+ const { limit = 5 } = query ?? {}
28
+
29
+ // API-FIX: backend doesnt answer Amity.Response
30
+ // const { data } = await client.http.get<Amity.Response<CommunityPayload>>(
31
+ const { data } = await client.http.get<Amity.CommunityPayload>(
32
+ `/api/v3/communities/top-trending`, { params: { options: { limit }}}
33
+ )
34
+
35
+ const { communities } = data
36
+
37
+ const cachedAt = client.cache && Date.now()
38
+
39
+ if (client.cache) {
40
+ ingestInCache(data, { cachedAt })
41
+
42
+ const cacheKey = ['community', 'top-trending', { params: { options: { limit }} }]
43
+ pushToCache(cacheKey, { communities: communities.map(getResolver('community')) })
44
+ }
45
+
46
+ return { data: communities, cachedAt }
47
+ }
48
+
49
+ /**
50
+ * ```js
51
+ * import { getTopTrendingCommunities } from '@amityco/ts-sdk'
52
+ * const communities = getTopTrendingCommunities.locally()
53
+ * ```
54
+ *
55
+ * Gets a list of top trending {@link Amity.Community} objects from cache
56
+ *
57
+ * @param query The query parameters
58
+ * @returns communities
59
+ *
60
+ * @category Community API
61
+ */
62
+ getTopTrendingCommunities.locally = (
63
+ query: Parameters<typeof getTopTrendingCommunities>[0],
64
+ ): Amity.Cached<Amity.Community[]> | undefined => {
65
+ const client = getActiveClient()
66
+ client.log('community/getTopTrendingCommunities.locally', query)
67
+
68
+ if (!client.cache) return
69
+
70
+ const { limit = 5 } = query ?? {}
71
+
72
+ const queryKey = ['community', 'top-trending', { params: { options: { limit }} }];
73
+ const { data, cachedAt } = pullFromCache<{communities: Pick<Amity.Community, 'communityId'>[]}>(queryKey) ?? {}
74
+
75
+ if (!data?.communities.length)
76
+ return
77
+
78
+ const communities: Amity.Community[] = data.communities
79
+ .map(communityId => pullFromCache<Amity.Community>(['community', 'get', communityId])!)
80
+ .filter(Boolean)
81
+ .map(({ data }) => data)
82
+
83
+ return communities.length === data?.communities?.length
84
+ ? { data: communities, cachedAt }
85
+ : undefined
86
+ }
@@ -15,3 +15,6 @@ export * from './removeCommunityMembers'
15
15
 
16
16
  export * from './addCommunityMembersRole'
17
17
  export * from './removeCommunityMembersRole'
18
+
19
+ export * from './getTopTrendingCommunities'
20
+ export * from './getRecommendedCommunities'
@@ -24,6 +24,9 @@ const idResolvers: Resolvers = {
24
24
  comment: ({ commentId }) => commentId,
25
25
 
26
26
  stream: ({ streamId }) => streamId,
27
+
28
+ follow: ({ from, to }) => `${from}#${to}`,
29
+ followCount: ({ userId }) => userId,
27
30
  }
28
31
 
29
32
  /**
@@ -31,6 +31,8 @@ const CRITERIAS: Criterias = {
31
31
  post: ['postId', 'feedId'],
32
32
  comment: ['commentId', 'referenceId'],
33
33
  stream: ['streamId'],
34
+ follow: ['from', 'to'],
35
+ followCount: ['userId', 'followerCount']
34
36
  }
35
37
 
36
38
  /** @hidden */
@@ -20,4 +20,7 @@ export * from './identifyModel'
20
20
  postChildren: 'post',
21
21
  comments: 'comment',
22
22
  videoStreamings: 'stream',
23
+
24
+ follows: 'follow',
25
+ followCounts: 'followCount'
23
26
  }
@@ -44,7 +44,7 @@ export const isAfterBeforeRaw = (json: Object): json is Amity.AfterBeforeRawPagi
44
44
  *
45
45
  * @hidden
46
46
  */
47
- export const isPaged = <T extends unknown>(payload: any): payload is Amity.Paged<T> => {
47
+ export const isPaged = <T extends unknown>(payload: any): payload is Amity.Paged<T, any> => {
48
48
  return (
49
49
  payload?.hasOwnProperty('data')
50
50
  && payload?.hasOwnProperty('nextPage')
@@ -121,8 +121,8 @@ export const toToken = (
121
121
  *
122
122
  * @hidden
123
123
  */
124
- export const toPage = (token?: Amity.Token): Amity.Page | null => {
125
- if (!token) return null
124
+ export const toPage = (token?: Amity.Token): Amity.Page | undefined => {
125
+ if (!token) return undefined
126
126
 
127
127
  // don't try catch, let it throw
128
128
  const json = JSON.parse(decode(token))
@@ -131,22 +131,22 @@ export const toPage = (token?: Amity.Token): Amity.Page | null => {
131
131
  return {
132
132
  after: json.skip,
133
133
  limit: json.limit!,
134
- } as Amity.NextPage
134
+ } as Amity.NextPage<number>
135
135
  } else if (isAfterBefore(json)) {
136
136
  if ('before' in json) {
137
137
  return {
138
138
  before: json.before,
139
139
  limit: json.last,
140
- } as Amity.PrevPage
140
+ } as Amity.PrevPage<number>
141
141
  } else if ('after' in json) {
142
142
  return {
143
143
  after: json.after,
144
144
  limit: json.first,
145
- } as Amity.NextPage
145
+ } as Amity.NextPage<number>
146
146
  }
147
147
  }
148
148
 
149
- return null
149
+ return undefined
150
150
  }
151
151
 
152
152
  /**
@@ -157,8 +157,8 @@ export const toPage = (token?: Amity.Token): Amity.Page | null => {
157
157
  *
158
158
  * @hidden
159
159
  */
160
- export const toPageRaw = (token?: Amity.Token): Amity.PageRaw | null => {
161
- if (!token) return null
160
+ export const toPageRaw = (token?: Amity.Token): Amity.PageRaw | undefined => {
161
+ if (!token) return undefined
162
162
 
163
163
  // don't try catch, let it throw
164
164
  const json = JSON.parse(decode(token))
@@ -167,5 +167,5 @@ export const toPageRaw = (token?: Amity.Token): Amity.PageRaw | null => {
167
167
  return json as Amity.PageRaw
168
168
  }
169
169
 
170
- return null
170
+ return undefined
171
171
  }
@@ -1,6 +1,7 @@
1
1
  import { getActiveClient } from '~/client/api'
2
2
  import { ASCError } from '~/core/errors'
3
3
  import { proxyMqttEvents } from '~/core/events'
4
+ import { getActiveUser } from '~/client/api/activeUser'
4
5
 
5
6
  export enum SubscriptionLevels {
6
7
  COMMUNITY = 'community',
@@ -54,6 +55,22 @@ export const getCommentTopic = ({ path }: Amity.Subscribable): string => {
54
55
  return path;
55
56
  };
56
57
 
58
+ export const getMyFollowersTopic = (): string => {
59
+ const user = getActiveUser()
60
+
61
+ const [networkId] = user.path.split('/user/');
62
+
63
+ return `${networkId}/membership/${user._id}/+/+`;
64
+ }
65
+
66
+ export const getMyFollowingsTopic = (): string => {
67
+ const user = getActiveUser()
68
+
69
+ const [networkId] = user.path.split('/user/');
70
+
71
+ return `${networkId}/membership/+/${user._id}/+`;
72
+ }
73
+
57
74
  let mqttAccessToken: string;
58
75
  let mqttUserId: string;
59
76
 
@@ -61,11 +78,12 @@ export function subscribeTopic(
61
78
  topic: string,
62
79
  callback?: Amity.Listener<ASCError | void>
63
80
  ): Amity.Unsubscriber {
64
- const { mqtt, emitter, accessToken, _internalUserId } = getActiveClient()
81
+ const { mqtt, emitter, accessToken } = getActiveClient()
82
+ const user = getActiveUser();
65
83
 
66
- if (mqttAccessToken !== accessToken || mqttUserId !== _internalUserId) {
84
+ if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
67
85
  mqttAccessToken = accessToken!
68
- mqttUserId = _internalUserId!
86
+ mqttUserId = user._id!
69
87
 
70
88
  mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId })
71
89
  proxyMqttEvents(mqtt, emitter)
@@ -0,0 +1,32 @@
1
+ import { getActiveClient } from '~/client/api'
2
+ import { ingestInCache } from '~/cache/api/ingestInCache'
3
+ import { fireEvent } from '~/core/events'
4
+
5
+ /**
6
+ * ```js
7
+ * import { acceptFollower } from '@amityco/ts-sdk'
8
+ * await acceptFollower('foobar')
9
+ * ```
10
+ *
11
+ * Accept the follow request
12
+ *
13
+ * @param userId the ID of the {@link Amity.User} follower
14
+ * @returns A success boolean if the follow request was accepted
15
+ *
16
+ * @category Follow API
17
+ * @async
18
+ */
19
+ export const acceptFollower = async (userId: Amity.User['userId']): Promise<boolean> => {
20
+ const client = getActiveClient()
21
+ client.log('follow/acceptFollower', userId)
22
+
23
+ const { data } = await client.http.post<Amity.FollowStatusPayload>(`/api/v4/me/followers/${userId}`)
24
+
25
+ if (client.cache) {
26
+ ingestInCache(data)
27
+ }
28
+
29
+ fireEvent('follow.accepted', data.follows[0])
30
+
31
+ return true
32
+ }