@amityco/ts-sdk 0.0.1-beta.25 → 0.0.1-beta.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +4 -1
- package/dist/@types/core/live.d.ts +23 -0
- package/dist/@types/core/live.d.ts.map +1 -0
- package/dist/@types/core/paging.d.ts +1 -1
- package/dist/@types/core/paging.d.ts.map +1 -1
- package/dist/@types/domains/comment.d.ts +14 -0
- package/dist/@types/domains/comment.d.ts.map +1 -1
- package/dist/@types/domains/post.d.ts +17 -0
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/@types/index.d.ts +1 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/cache/api/ingestInCache.d.ts +1 -1
- package/dist/cache/api/ingestInCache.d.ts.map +1 -1
- package/dist/cache/api/mergeInCache.d.ts +1 -1
- package/dist/cache/api/mergeInCache.d.ts.map +1 -1
- package/dist/category/api/queryCategories.d.ts +3 -3
- package/dist/category/api/queryCategories.d.ts.map +1 -1
- package/dist/channel/api/queryChannels.d.ts +6 -6
- package/dist/channel/api/queryChannels.d.ts.map +1 -1
- package/dist/client/api/connectClient.d.ts +1 -1
- package/dist/client/api/connectClient.d.ts.map +1 -1
- package/dist/client/api/createClient.d.ts +1 -1
- package/dist/client/api/createClient.d.ts.map +1 -1
- package/dist/comment/api/queryComments.d.ts +1 -9
- package/dist/comment/api/queryComments.d.ts.map +1 -1
- package/dist/comment/observers/index.d.ts +1 -0
- package/dist/comment/observers/index.d.ts.map +1 -1
- package/dist/comment/observers/liveComments.d.ts +22 -0
- package/dist/comment/observers/liveComments.d.ts.map +1 -0
- package/dist/comment/observers/observeComments.d.ts.map +1 -1
- package/dist/community/api/getRecommendedCommunities.d.ts +1 -1
- package/dist/community/api/getRecommendedCommunities.d.ts.map +1 -1
- package/dist/community/api/getTopTrendingCommunities.d.ts +1 -1
- package/dist/community/api/getTopTrendingCommunities.d.ts.map +1 -1
- package/dist/community/api/queryCommunities.d.ts +7 -7
- package/dist/community/api/queryCommunities.d.ts.map +1 -1
- package/dist/core/debug.d.ts +1 -1
- package/dist/core/debug.d.ts.map +1 -1
- package/dist/core/query/paging.d.ts +2 -2
- package/dist/core/query/paging.d.ts.map +1 -1
- package/dist/core/query/query.d.ts +1 -1
- package/dist/core/query/query.d.ts.map +1 -1
- package/dist/core/tests/query/filtering.test.d.ts +2 -0
- package/dist/core/tests/query/filtering.test.d.ts.map +1 -0
- package/dist/core/tests/query/query.test.d.ts +2 -0
- package/dist/core/tests/query/query.test.d.ts.map +1 -0
- package/dist/core/transports/ws.d.ts +1 -1
- package/dist/core/transports/ws.d.ts.map +1 -1
- package/dist/external/api/createUserToken.d.ts +1 -1
- package/dist/external/api/createUserToken.d.ts.map +1 -1
- package/dist/feed/api/queryGlobalFeed.d.ts +4 -4
- package/dist/feed/api/queryGlobalFeed.d.ts.map +1 -1
- package/dist/index.cjs.js +17789 -17577
- package/dist/index.esm.js +17788 -17578
- package/dist/index.umd.js +4 -19
- package/dist/post/api/queryPosts.d.ts +1 -12
- package/dist/post/api/queryPosts.d.ts.map +1 -1
- package/dist/post/observers/index.d.ts +1 -0
- package/dist/post/observers/index.d.ts.map +1 -1
- package/dist/post/observers/livePosts.d.ts +22 -0
- package/dist/post/observers/livePosts.d.ts.map +1 -0
- package/dist/post/observers/observePosts.d.ts.map +1 -1
- package/dist/post/tests/api/getPost.test.d.ts +2 -0
- package/dist/post/tests/api/getPost.test.d.ts.map +1 -0
- package/dist/post/tests/api/queryPosts.test.d.ts +2 -0
- package/dist/post/tests/api/queryPosts.test.d.ts.map +1 -0
- package/dist/reaction/api/queryReactions.d.ts +2 -2
- package/dist/reaction/api/queryReactions.d.ts.map +1 -1
- package/dist/role/api/queryRoles.d.ts +4 -4
- package/dist/role/api/queryRoles.d.ts.map +1 -1
- package/dist/stream/api/queryStreams.d.ts +6 -6
- package/dist/stream/api/queryStreams.d.ts.map +1 -1
- package/dist/utils/constants.d.ts +3 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/tests/client.d.ts +3 -0
- package/dist/utils/tests/client.d.ts.map +1 -0
- package/dist/utils/tests/dummy.d.ts +8 -0
- package/dist/utils/tests/dummy.d.ts.map +1 -0
- package/dist/utils/tests/index.d.ts +3 -0
- package/dist/utils/tests/index.d.ts.map +1 -0
- package/jest.config.ts +15 -0
- package/package.json +21 -16
- package/src/@types/core/live.ts +28 -0
- package/src/@types/core/paging.ts +1 -1
- package/src/@types/domains/comment.ts +31 -0
- package/src/@types/domains/post.ts +37 -0
- package/src/@types/index.ts +1 -0
- package/src/comment/api/queryComments.ts +3 -9
- package/src/comment/observers/index.ts +1 -0
- package/src/comment/observers/liveComments.ts +169 -0
- package/src/comment/observers/observeComments.ts +1 -11
- package/src/core/query/query.ts +15 -2
- package/src/core/tests/query/filtering.test.ts +11 -0
- package/src/core/tests/query/query.test.ts +19 -0
- package/src/post/api/queryPosts.ts +3 -12
- package/src/post/observers/index.ts +1 -0
- package/src/post/observers/livePosts.ts +170 -0
- package/src/post/observers/observePosts.ts +1 -13
- package/src/post/tests/api/getPost.test.ts +88 -0
- package/src/post/tests/api/queryPosts.test.ts +23 -0
- package/src/reaction/api/queryReactions.ts +10 -10
- package/src/utils/constants.ts +2 -0
- package/src/utils/tests/client.ts +5 -0
- package/src/utils/tests/dummy.ts +7 -0
- package/src/utils/tests/index.ts +2 -0
- package/tsconfig.json +23 -22
package/src/core/query/query.ts
CHANGED
|
@@ -215,8 +215,21 @@ export const runQuery = <Args extends any[], Returned extends any>(
|
|
|
215
215
|
if (isMutator(func)) {
|
|
216
216
|
// @ts-ignore
|
|
217
217
|
const modelKey = local && local.data && identifyModelKey(local.data);
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
if (modelKey) {
|
|
219
|
+
/*
|
|
220
|
+
* modal key is only required for create as update and delete queries pass
|
|
221
|
+
* the modal key in the param itself
|
|
222
|
+
* For update & delete the first argument is always an id which is of type
|
|
223
|
+
* string, whereas for create the first and only argument is the param object
|
|
224
|
+
*
|
|
225
|
+
* When creating an AmityObject optimistically we need to pass the modal key
|
|
226
|
+
* on to the server. ex: for create message modal key will be 'messageId`
|
|
227
|
+
*/
|
|
228
|
+
if (typeof args[0] !== 'string') {
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
optimisticArgs = [{ ...args[0], [modelKey]: local.data[modelKey] }];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
220
233
|
}
|
|
221
234
|
|
|
222
235
|
func(...optimisticArgs)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { filterByPropEquality } from '~/core/query';
|
|
2
|
+
|
|
3
|
+
describe('Core/Query/Filtering', () => {
|
|
4
|
+
test('check filterByPropEquality', () => {
|
|
5
|
+
const prop = 'prop';
|
|
6
|
+
const collection = [{ [prop]: 'value' }];
|
|
7
|
+
|
|
8
|
+
expect(filterByPropEquality(collection, prop, 'value')).toStrictEqual(collection);
|
|
9
|
+
expect(filterByPropEquality(collection, prop, 'otherValue')).toStrictEqual([]);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { isFetcher } from '~/core/query';
|
|
2
|
+
|
|
3
|
+
type isFetcherMockType = jest.Mock<any, any> & {
|
|
4
|
+
locally?: jest.Mock<any, any>;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
describe('Core/Query/Query', () => {
|
|
8
|
+
const isFetcherMock: isFetcherMockType = jest.fn();
|
|
9
|
+
|
|
10
|
+
test('isFetcher without locally', () => {
|
|
11
|
+
expect(isFetcher(isFetcherMock)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('isFetcher with locally', () => {
|
|
15
|
+
isFetcherMock.locally = jest.fn();
|
|
16
|
+
|
|
17
|
+
expect(isFetcher(isFetcherMock)).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -20,18 +20,9 @@ import { getResolver } from '~/core/model';
|
|
|
20
20
|
* @category Post API
|
|
21
21
|
* @async
|
|
22
22
|
*/
|
|
23
|
-
export const queryPosts = async (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
sortBy?: 'lastCreated' | 'firstCreated' | 'lastUpdated' | 'firstUpdated';
|
|
27
|
-
dataType?: string;
|
|
28
|
-
isDeleted?: Amity.Post['isDeleted'];
|
|
29
|
-
hasFlag?: boolean;
|
|
30
|
-
feedType?: 'reviewing' | 'published';
|
|
31
|
-
tags?: Amity.Taggable['tags'];
|
|
32
|
-
matchingOnlyParentPost?: boolean;
|
|
33
|
-
page?: Amity.PageRaw;
|
|
34
|
-
}): Promise<Amity.Cached<Amity.Paged<Amity.Post, Amity.PageRaw>>> => {
|
|
23
|
+
export const queryPosts = async (
|
|
24
|
+
query: Amity.QueryPosts,
|
|
25
|
+
): Promise<Amity.Cached<Amity.Paged<Amity.Post, Amity.PageRaw>>> => {
|
|
35
26
|
const client = getActiveClient();
|
|
36
27
|
client.log('post/queryPosts', query);
|
|
37
28
|
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/* eslint-disable no-use-before-define */
|
|
2
|
+
import { getResolver } from '~/core/model';
|
|
3
|
+
import { getActiveClient } from '~/client/api';
|
|
4
|
+
import { pushToCache, pullFromCache } from '~/cache/api';
|
|
5
|
+
import {
|
|
6
|
+
createQuery,
|
|
7
|
+
runQuery,
|
|
8
|
+
queryOptions,
|
|
9
|
+
filterByPropEquality,
|
|
10
|
+
sortByFirstCreated,
|
|
11
|
+
sortByLastCreated,
|
|
12
|
+
} from '~/core/query';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
COLLECTION_DEFAULT_CACHING_POLICY,
|
|
16
|
+
COLLECTION_DEFAULT_PAGINATION_LIMIT,
|
|
17
|
+
} from '~/utils/constants';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
onPostCreated,
|
|
21
|
+
onPostUpdated,
|
|
22
|
+
onPostDeleted,
|
|
23
|
+
onPostApproved,
|
|
24
|
+
onPostDeclined,
|
|
25
|
+
onPostFlagged,
|
|
26
|
+
onPostUnflagged,
|
|
27
|
+
onPostReactionAdded,
|
|
28
|
+
onPostReactionRemoved,
|
|
29
|
+
} from '../events';
|
|
30
|
+
import { queryPosts } from '../api';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* ```js
|
|
34
|
+
* import { livePosts } from '@amityco/ts-sdk'
|
|
35
|
+
*
|
|
36
|
+
* let posts = []
|
|
37
|
+
* const unsub = livePosts({
|
|
38
|
+
* targetType: Amity.PostTargetType,
|
|
39
|
+
* targetId: Amity.Post['targetId'],
|
|
40
|
+
* }, response => merge(posts, response.data))
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Observe all mutations on a list of {@link Amity.Post} for a given target object
|
|
44
|
+
*
|
|
45
|
+
* @param targetType the type of the target
|
|
46
|
+
* @param targetId the ID of the target
|
|
47
|
+
* @param callback the function to call when new data are available
|
|
48
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
|
|
49
|
+
*
|
|
50
|
+
* @category Posts Live Collection
|
|
51
|
+
*/
|
|
52
|
+
export const livePosts = (
|
|
53
|
+
params: Amity.PostLiveCollection,
|
|
54
|
+
callback: Amity.LiveCollectionCallback<Amity.Post>,
|
|
55
|
+
config?: Amity.LiveCollectionConfig,
|
|
56
|
+
): Amity.Unsubscriber => {
|
|
57
|
+
const { log, cache } = getActiveClient();
|
|
58
|
+
|
|
59
|
+
if (!cache) {
|
|
60
|
+
console.log('For using Live Collection feature you need to enable Cache!');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const timestamp = Date.now();
|
|
64
|
+
log(`livePosts(tmpid: ${timestamp}) > listen`);
|
|
65
|
+
|
|
66
|
+
const { limit: queryLimit, ...queryParams } = params;
|
|
67
|
+
|
|
68
|
+
const limit = queryLimit ?? COLLECTION_DEFAULT_PAGINATION_LIMIT;
|
|
69
|
+
const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
|
|
70
|
+
|
|
71
|
+
const disposers: Amity.Unsubscriber[] = [];
|
|
72
|
+
const cacheKey = [
|
|
73
|
+
'post',
|
|
74
|
+
'collection',
|
|
75
|
+
{ targetId: params.targetId, targetType: params.targetType },
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const responder = (data: Amity.PostLiveCollectionCache) => {
|
|
79
|
+
let posts: Amity.Post[] =
|
|
80
|
+
data.data
|
|
81
|
+
.map(postId => pullFromCache<Amity.Post>(['post', 'get', postId])!)
|
|
82
|
+
.filter(Boolean)
|
|
83
|
+
.map(({ data }) => data) ?? [];
|
|
84
|
+
|
|
85
|
+
posts = filterByPropEquality(posts, 'isDeleted', params.isDeleted);
|
|
86
|
+
|
|
87
|
+
const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
|
|
88
|
+
|
|
89
|
+
posts = posts.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
|
|
90
|
+
|
|
91
|
+
callback({
|
|
92
|
+
onNextPage: onFetch,
|
|
93
|
+
data: posts,
|
|
94
|
+
hasNextPage: !!data.params?.page,
|
|
95
|
+
loading: data.loading,
|
|
96
|
+
error: data.error,
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const realtimeRouter = (post: Amity.Post, action: Amity.PostActionType) => {
|
|
101
|
+
const collection = pullFromCache<Amity.PostLiveCollectionCache>(cacheKey)?.data;
|
|
102
|
+
|
|
103
|
+
if (params.targetId !== post.targetId || params.targetType !== post.targetType || !collection)
|
|
104
|
+
return;
|
|
105
|
+
|
|
106
|
+
if (action === 'onCreate') {
|
|
107
|
+
collection.data = [...new Set([post.postId, ...collection.data])];
|
|
108
|
+
} else if (['onDelete', 'onDeclined'].includes(action)) {
|
|
109
|
+
collection.data = collection.data.filter(p => p !== post.postId);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
pushToCache(cacheKey, collection);
|
|
113
|
+
|
|
114
|
+
responder(collection);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const onFetch = () => {
|
|
118
|
+
const collection = pullFromCache<Amity.PostLiveCollectionCache>(cacheKey)?.data;
|
|
119
|
+
|
|
120
|
+
const posts = collection?.data ?? [];
|
|
121
|
+
|
|
122
|
+
if (posts.length > 0 && !collection?.params?.page) return;
|
|
123
|
+
|
|
124
|
+
const query = createQuery(queryPosts, {
|
|
125
|
+
...queryParams,
|
|
126
|
+
page: collection?.params?.page ?? { limit },
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
runQuery(
|
|
130
|
+
query,
|
|
131
|
+
({ data: result, error, loading, nextPage: page }) => {
|
|
132
|
+
const data = {
|
|
133
|
+
loading,
|
|
134
|
+
error,
|
|
135
|
+
params: { page },
|
|
136
|
+
data: posts,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
if (result) {
|
|
140
|
+
data.data = [...new Set([...posts, ...result.map(getResolver('post'))])];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
pushToCache(cacheKey, data);
|
|
144
|
+
|
|
145
|
+
responder(data);
|
|
146
|
+
},
|
|
147
|
+
queryOptions(policy),
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
disposers.push(
|
|
152
|
+
onPostCreated(post => realtimeRouter(post, 'onCreate')),
|
|
153
|
+
onPostApproved(post => realtimeRouter(post, 'onApproved')),
|
|
154
|
+
onPostDeclined(post => realtimeRouter(post, 'onDeclined')),
|
|
155
|
+
onPostDeleted(post => realtimeRouter(post, 'onDelete')),
|
|
156
|
+
|
|
157
|
+
onPostUpdated(post => realtimeRouter(post, 'onUpdate')),
|
|
158
|
+
onPostFlagged(post => realtimeRouter(post, 'onFlagged')),
|
|
159
|
+
onPostUnflagged(post => realtimeRouter(post, 'onUnflagged')),
|
|
160
|
+
onPostReactionAdded(post => realtimeRouter(post, 'onReactionAdded')),
|
|
161
|
+
onPostReactionRemoved(post => realtimeRouter(post, 'onReactionRemoved')),
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
onFetch();
|
|
165
|
+
|
|
166
|
+
return () => {
|
|
167
|
+
log(`livePosts(tmpid: ${timestamp}) > dispose`);
|
|
168
|
+
disposers.forEach(fn => fn());
|
|
169
|
+
};
|
|
170
|
+
};
|
|
@@ -59,19 +59,7 @@ export const observePosts = (
|
|
|
59
59
|
|
|
60
60
|
const disposers: Amity.Unsubscriber[] = [];
|
|
61
61
|
|
|
62
|
-
const router = (
|
|
63
|
-
post: Amity.Post,
|
|
64
|
-
action:
|
|
65
|
-
| 'onCreate'
|
|
66
|
-
| 'onUpdate'
|
|
67
|
-
| 'onDelete'
|
|
68
|
-
| 'onApproved'
|
|
69
|
-
| 'onDeclined'
|
|
70
|
-
| 'onFlagged'
|
|
71
|
-
| 'onUnflagged'
|
|
72
|
-
| 'onReactionAdded'
|
|
73
|
-
| 'onReactionRemoved',
|
|
74
|
-
) => {
|
|
62
|
+
const router = (post: Amity.Post, action: Exclude<Amity.PostActionType, 'onFetch'>) => {
|
|
75
63
|
if (params.targetId !== post.targetId || params.targetType !== post.targetType) return;
|
|
76
64
|
|
|
77
65
|
if (callback instanceof Function) return callback(post);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ASCApiError } from '~/core/errors';
|
|
2
|
+
import { client, userPosts } from '~/utils/tests';
|
|
3
|
+
import { pushToCache, enableCache, disableCache } from '~/cache/api';
|
|
4
|
+
|
|
5
|
+
import { getPost } from '~/post/api';
|
|
6
|
+
|
|
7
|
+
describe('post/api', () => {
|
|
8
|
+
const post = { postId: userPosts.page1[0] };
|
|
9
|
+
const post2 = { postId: userPosts.page1[1] };
|
|
10
|
+
|
|
11
|
+
describe('getPost.locally', () => {
|
|
12
|
+
test('should return undefined if cache is turned off', () => {
|
|
13
|
+
expect(getPost.locally(post.postId)).toBeUndefined();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('should return undefined if post not in cache', () => {
|
|
17
|
+
enableCache();
|
|
18
|
+
|
|
19
|
+
const cachedAt = Date.now();
|
|
20
|
+
|
|
21
|
+
pushToCache(['post', 'get', post.postId], post, { cachedAt });
|
|
22
|
+
|
|
23
|
+
expect(getPost.locally(post2.postId)).toBeUndefined();
|
|
24
|
+
|
|
25
|
+
disableCache();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('should return post if post in cache', () => {
|
|
29
|
+
enableCache();
|
|
30
|
+
|
|
31
|
+
const cachedAt = Date.now();
|
|
32
|
+
|
|
33
|
+
pushToCache(['post', 'get', post.postId], post, { cachedAt });
|
|
34
|
+
|
|
35
|
+
const data = getPost.locally(post.postId);
|
|
36
|
+
|
|
37
|
+
expect(data).toBeDefined();
|
|
38
|
+
expect(data?.data).toEqual(post);
|
|
39
|
+
expect(data?.cachedAt).toEqual(cachedAt);
|
|
40
|
+
|
|
41
|
+
disableCache();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('getPost', () => {
|
|
46
|
+
test('should return a post', async () => {
|
|
47
|
+
client.http.get = jest.fn().mockReturnValueOnce({ data: { posts: [post] } });
|
|
48
|
+
|
|
49
|
+
const data = await getPost(post.postId);
|
|
50
|
+
|
|
51
|
+
expect(data).toBeDefined();
|
|
52
|
+
expect(data?.data).toEqual(post);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('should put post into the cache after fetch', async () => {
|
|
56
|
+
enableCache();
|
|
57
|
+
client.http.get = jest.fn().mockReturnValueOnce({ data: { posts: [post] } });
|
|
58
|
+
|
|
59
|
+
await getPost(post.postId);
|
|
60
|
+
|
|
61
|
+
expect(getPost.locally(post.postId)?.data).toEqual(post);
|
|
62
|
+
|
|
63
|
+
disableCache();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('should return an error', async () => {
|
|
67
|
+
client.http.get = jest.fn().mockRejectedValueOnce(new Error('error'));
|
|
68
|
+
|
|
69
|
+
await expect(getPost(post.postId)).rejects.toThrow('error');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('should return an error if post in cache but api throws not found', async () => {
|
|
73
|
+
enableCache();
|
|
74
|
+
pushToCache(['post', 'get', post.postId], post, { cachedAt: Date.now() });
|
|
75
|
+
|
|
76
|
+
client.http.get = jest
|
|
77
|
+
.fn()
|
|
78
|
+
.mockRejectedValueOnce(
|
|
79
|
+
new ASCApiError('not found!', Amity.ServerError.ITEM_NOT_FOUND, Amity.ErrorLevel.ERROR),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
await expect(getPost(post.postId)).rejects.toThrow();
|
|
83
|
+
|
|
84
|
+
expect(getPost.locally(post.postId)).toBeUndefined();
|
|
85
|
+
disableCache();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { queryPosts } from '~/post/api';
|
|
2
|
+
import { client, userPosts } from '~/utils/tests';
|
|
3
|
+
|
|
4
|
+
describe('post/api', () => {
|
|
5
|
+
test('should return a post query', async () => {
|
|
6
|
+
const returnValue = [{ postId: userPosts.page1[0] }];
|
|
7
|
+
|
|
8
|
+
client.http.get = jest.fn().mockResolvedValue({
|
|
9
|
+
data: {
|
|
10
|
+
posts: returnValue,
|
|
11
|
+
paging: {},
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const data = await queryPosts({
|
|
16
|
+
targetId: userPosts.targetId,
|
|
17
|
+
targetType: userPosts.targetType,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
expect(data).toBeDefined();
|
|
21
|
+
expect(data?.data).toEqual(returnValue);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getActiveClient } from '~/client/api/activeClient';
|
|
2
2
|
|
|
3
|
-
import { toToken,
|
|
3
|
+
import { toToken, toPageRaw } from '~/core/query';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* ```js
|
|
@@ -23,30 +23,30 @@ export const queryReactions = async (query: {
|
|
|
23
23
|
referenceId: Amity.Reaction['referenceId'];
|
|
24
24
|
referenceType: Amity.Reaction['referenceType'];
|
|
25
25
|
reactionName?: Amity.Reaction['reactionName'];
|
|
26
|
-
page?: Amity.Page
|
|
27
|
-
}): Promise<Amity.Paged<Amity.ReactionQuery, Amity.Page
|
|
26
|
+
page?: Amity.Page<string>;
|
|
27
|
+
}): Promise<Amity.Paged<Amity.ReactionQuery, Amity.Page<string>>> => {
|
|
28
28
|
const client = getActiveClient();
|
|
29
29
|
client.log('reaction/queryReactions', query);
|
|
30
30
|
|
|
31
31
|
const { page = { limit: 10 }, ...params } = query ?? {};
|
|
32
32
|
|
|
33
|
-
const { data } = await client.http.get<
|
|
34
|
-
`/api/
|
|
33
|
+
const { data } = await client.http.get<Amity.ReactionPayload & Amity.Pagination>(
|
|
34
|
+
`/api/v3/reactions`,
|
|
35
35
|
{
|
|
36
36
|
params: {
|
|
37
37
|
...params,
|
|
38
38
|
options: {
|
|
39
|
-
token: toToken(page, '
|
|
39
|
+
token: toToken(page, 'afterbeforeraw'),
|
|
40
40
|
},
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
);
|
|
44
44
|
|
|
45
|
-
const { paging,
|
|
46
|
-
const { reactions } =
|
|
45
|
+
const { paging, ...payload } = data;
|
|
46
|
+
const { reactions } = payload;
|
|
47
47
|
|
|
48
|
-
const nextPage =
|
|
49
|
-
const prevPage =
|
|
48
|
+
const nextPage = toPageRaw(paging.next);
|
|
49
|
+
const prevPage = toPageRaw(paging.previous);
|
|
50
50
|
|
|
51
51
|
return { data: reactions, prevPage, nextPage };
|
|
52
52
|
};
|
package/tsconfig.json
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
"include": ["./src"],
|
|
5
|
+
"exclude": ["node_modules", "**/*.spec.ts"],
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
"compilerOptions": {
|
|
8
|
+
"baseUrl": "./src",
|
|
9
|
+
"paths": {
|
|
10
|
+
"~/*": ["./*"]
|
|
11
|
+
},
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
"rootDir": "./src",
|
|
14
|
+
"outDir": "./dist",
|
|
15
|
+
"declaration": true,
|
|
16
|
+
"declarationDir": "./dist",
|
|
17
|
+
"noEmit": true,
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
"module": "es2020",
|
|
20
|
+
"target": "es2017",
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
"lib": [
|
|
23
|
+
"esnext",
|
|
24
|
+
"es7",
|
|
25
|
+
"es6",
|
|
26
|
+
"dom"
|
|
27
|
+
],
|
|
28
|
+
"resolveJsonModule": true
|
|
29
|
+
}
|
|
29
30
|
}
|