@metamask/social-controllers 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -1
- package/dist/SocialRealtimeService.d.ts +1 -1
- package/dist/SocialRealtimeService.d.ts.map +1 -1
- package/dist/SocialRealtimeService.js +13 -6
- package/dist/SocialRealtimeService.js.map +1 -1
- package/dist/SocialService-method-action-types.d.ts +98 -2
- package/dist/SocialService-method-action-types.d.ts.map +1 -1
- package/dist/SocialService-method-action-types.js.map +1 -1
- package/dist/SocialService.d.ts +80 -2
- package/dist/SocialService.d.ts.map +1 -1
- package/dist/SocialService.js +261 -33
- package/dist/SocialService.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/social-constants.d.ts +9 -0
- package/dist/social-constants.d.ts.map +1 -1
- package/dist/social-constants.js +9 -0
- package/dist/social-constants.js.map +1 -1
- package/dist/social-types.d.ts +107 -6
- package/dist/social-types.d.ts.map +1 -1
- package/dist/social-types.js.map +1 -1
- package/package.json +5 -5
package/dist/SocialService.js
CHANGED
|
@@ -33,10 +33,13 @@ const PositionStruct = structType({
|
|
|
33
33
|
chain: string(),
|
|
34
34
|
positionAmount: number(),
|
|
35
35
|
isOpen: optional(boolean()),
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
// Incomplete Clicker metrics serialize these as `null` (`undefined + n`
|
|
37
|
+
// becomes `NaN`, then JSON `null`). Rejecting the field used to fail the
|
|
38
|
+
// entire feed page, so they are nullable here.
|
|
39
|
+
boughtUsd: nullable(number()),
|
|
40
|
+
soldUsd: nullable(number()),
|
|
41
|
+
realizedPnl: nullable(number()),
|
|
42
|
+
costBasis: nullable(number()),
|
|
40
43
|
trades: array(TradeStruct),
|
|
41
44
|
lastTradeAt: number(),
|
|
42
45
|
tokenImageUrl: optional(nullable(string())),
|
|
@@ -182,6 +185,34 @@ const FeedResponseStruct = structType({
|
|
|
182
185
|
items: array(FeedItemStruct),
|
|
183
186
|
pagination: FeedPaginationStruct,
|
|
184
187
|
});
|
|
188
|
+
/**
|
|
189
|
+
* One malformed feed item must not blank the page. When the envelope is
|
|
190
|
+
* well-shaped, keep items that match {@link FeedItemStruct} and drop the rest.
|
|
191
|
+
* Still throw when `items` or `pagination` themselves are unusable.
|
|
192
|
+
*
|
|
193
|
+
* @param feedData - Parsed JSON body from a feed endpoint.
|
|
194
|
+
* @param invalidMessage - Error message to throw when the envelope is unusable.
|
|
195
|
+
* @returns The validated feed response, possibly with invalid items dropped.
|
|
196
|
+
*/
|
|
197
|
+
const parseFeedResponse = (feedData, invalidMessage) => {
|
|
198
|
+
if (is(feedData, FeedResponseStruct)) {
|
|
199
|
+
return feedData;
|
|
200
|
+
}
|
|
201
|
+
if (typeof feedData !== 'object' ||
|
|
202
|
+
feedData === null ||
|
|
203
|
+
!('items' in feedData) ||
|
|
204
|
+
!('pagination' in feedData)) {
|
|
205
|
+
throw new Error(invalidMessage);
|
|
206
|
+
}
|
|
207
|
+
const { items, pagination } = feedData;
|
|
208
|
+
if (!Array.isArray(items) || !is(pagination, FeedPaginationStruct)) {
|
|
209
|
+
throw new Error(invalidMessage);
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
items: items.filter((item) => is(item, FeedItemStruct)),
|
|
213
|
+
pagination,
|
|
214
|
+
};
|
|
215
|
+
};
|
|
185
216
|
const FollowersResponseStruct = structType({
|
|
186
217
|
followers: array(ProfileSummaryStruct),
|
|
187
218
|
count: number(),
|
|
@@ -196,6 +227,28 @@ const FollowResponseStruct = structType({
|
|
|
196
227
|
const UnfollowResponseStruct = structType({
|
|
197
228
|
unfollowed: array(ProfileSummaryStruct),
|
|
198
229
|
});
|
|
230
|
+
const BlockedProfileStruct = structType({
|
|
231
|
+
blockedAt: number(),
|
|
232
|
+
reason: nullable(string()),
|
|
233
|
+
profile: ProfileSummaryStruct,
|
|
234
|
+
});
|
|
235
|
+
const BlockedProfilesResponseStruct = structType({
|
|
236
|
+
items: array(BlockedProfileStruct),
|
|
237
|
+
cursor: nullable(string()),
|
|
238
|
+
});
|
|
239
|
+
const BlockedContentStruct = structType({
|
|
240
|
+
blockedAt: number(),
|
|
241
|
+
reason: nullable(string()),
|
|
242
|
+
type: enums(['comment', 'reply']),
|
|
243
|
+
id: string(),
|
|
244
|
+
text: string(),
|
|
245
|
+
createdAt: number(),
|
|
246
|
+
author: nullable(ProfileSummaryStruct),
|
|
247
|
+
});
|
|
248
|
+
const BlockedContentResponseStruct = structType({
|
|
249
|
+
items: array(BlockedContentStruct),
|
|
250
|
+
cursor: nullable(string()),
|
|
251
|
+
});
|
|
199
252
|
// ---------------------------------------------------------------------------
|
|
200
253
|
// Messenger types
|
|
201
254
|
// ---------------------------------------------------------------------------
|
|
@@ -205,7 +258,10 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
205
258
|
'fetchOpenPositions',
|
|
206
259
|
'fetchClosedPositions',
|
|
207
260
|
'fetchFollowers',
|
|
261
|
+
'fetchTraderFollowing',
|
|
208
262
|
'fetchFollowing',
|
|
263
|
+
'fetchMyFollowing',
|
|
264
|
+
'fetchMyFollowers',
|
|
209
265
|
'fetchPositionById',
|
|
210
266
|
'fetchFeed',
|
|
211
267
|
'fetchTraderFeed',
|
|
@@ -218,6 +274,9 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
218
274
|
'optOutOfLeaderboard',
|
|
219
275
|
'optInToLeaderboard',
|
|
220
276
|
'refreshNotificationPreferencesCache',
|
|
277
|
+
'block',
|
|
278
|
+
'fetchBlockedProfiles',
|
|
279
|
+
'fetchBlockedContent',
|
|
221
280
|
];
|
|
222
281
|
// ---------------------------------------------------------------------------
|
|
223
282
|
// Service
|
|
@@ -289,7 +348,7 @@ export class SocialService extends BaseDataService {
|
|
|
289
348
|
headers: authHeaders,
|
|
290
349
|
});
|
|
291
350
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_LEADERBOARD_FAILED);
|
|
292
|
-
const leaderboardData = await response.json();
|
|
351
|
+
const leaderboardData = (await response.json());
|
|
293
352
|
if (!is(leaderboardData, LeaderboardResponseStruct)) {
|
|
294
353
|
throw new Error(SocialServiceErrorMessage.FETCH_LEADERBOARD_INVALID_RESPONSE);
|
|
295
354
|
}
|
|
@@ -316,7 +375,7 @@ export class SocialService extends BaseDataService {
|
|
|
316
375
|
const authHeaders = await this.#getAuthHeaders();
|
|
317
376
|
const response = await fetch(url, { headers: authHeaders });
|
|
318
377
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_TRADER_PROFILE_FAILED);
|
|
319
|
-
const traderProfileData = await response.json();
|
|
378
|
+
const traderProfileData = (await response.json());
|
|
320
379
|
if (!is(traderProfileData, TraderProfileResponseStruct)) {
|
|
321
380
|
throw new Error(SocialServiceErrorMessage.FETCH_TRADER_PROFILE_INVALID_RESPONSE);
|
|
322
381
|
}
|
|
@@ -360,22 +419,31 @@ export class SocialService extends BaseDataService {
|
|
|
360
419
|
/**
|
|
361
420
|
* Fetches a trader's MetaMask followers.
|
|
362
421
|
*
|
|
363
|
-
* Calls `GET ${baseUrl}/traders/${addressOrId}/followers`.
|
|
422
|
+
* Calls `GET ${baseUrl}/traders/${addressOrId}/followers`. Pass
|
|
423
|
+
* `mutuals: true` to append `?mutuals=true` (profiles that follow both this
|
|
424
|
+
* trader and the authenticated user; `count` is the mutual total). Requires a
|
|
425
|
+
* bearer token; the trader is identified by `addressOrId`, not the JWT
|
|
426
|
+
* subject (see {@link fetchMyFollowers} for the current user's inbound list).
|
|
364
427
|
*
|
|
365
428
|
* @param options - Options bag.
|
|
366
429
|
* @param options.addressOrId - Wallet address or Clicker profile ID.
|
|
430
|
+
* @param options.mutuals - When true, request mutual followers only.
|
|
367
431
|
* @returns The followers response.
|
|
368
432
|
*/
|
|
369
433
|
async fetchFollowers(options) {
|
|
370
|
-
const { addressOrId } = options;
|
|
434
|
+
const { addressOrId, mutuals } = options;
|
|
435
|
+
const mutualsOnly = mutuals === true;
|
|
371
436
|
const followersResponse = await this.fetchQuery({
|
|
372
|
-
queryKey: [`${this.name}:fetchFollowers`, addressOrId],
|
|
437
|
+
queryKey: [`${this.name}:fetchFollowers`, addressOrId, mutualsOnly],
|
|
373
438
|
queryFn: async () => {
|
|
374
|
-
const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/followers
|
|
439
|
+
const url = new URL(`${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/followers`);
|
|
440
|
+
if (mutualsOnly) {
|
|
441
|
+
url.searchParams.append('mutuals', 'true');
|
|
442
|
+
}
|
|
375
443
|
const authHeaders = await this.#getAuthHeaders();
|
|
376
|
-
const response = await fetch(url, { headers: authHeaders });
|
|
444
|
+
const response = await fetch(url.toString(), { headers: authHeaders });
|
|
377
445
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_FOLLOWERS_FAILED);
|
|
378
|
-
const followersData = await response.json();
|
|
446
|
+
const followersData = (await response.json());
|
|
379
447
|
if (!is(followersData, FollowersResponseStruct)) {
|
|
380
448
|
throw new Error(SocialServiceErrorMessage.FETCH_FOLLOWERS_INVALID_RESPONSE);
|
|
381
449
|
}
|
|
@@ -384,6 +452,35 @@ export class SocialService extends BaseDataService {
|
|
|
384
452
|
});
|
|
385
453
|
return followersResponse;
|
|
386
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Fetches the list of traders a profile follows.
|
|
457
|
+
*
|
|
458
|
+
* Calls `GET ${baseUrl}/traders/${addressOrId}/following`. Requires a bearer
|
|
459
|
+
* token; the trader is identified by `addressOrId`, not the JWT subject (see
|
|
460
|
+
* {@link fetchFollowing} for the current user's outbound list).
|
|
461
|
+
*
|
|
462
|
+
* @param options - Options bag.
|
|
463
|
+
* @param options.addressOrId - Wallet address or Clicker profile ID.
|
|
464
|
+
* @returns The following response.
|
|
465
|
+
*/
|
|
466
|
+
async fetchTraderFollowing(options) {
|
|
467
|
+
const { addressOrId } = options;
|
|
468
|
+
const followingResponse = await this.fetchQuery({
|
|
469
|
+
queryKey: [`${this.name}:fetchTraderFollowing`, addressOrId],
|
|
470
|
+
queryFn: async () => {
|
|
471
|
+
const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/following`;
|
|
472
|
+
const authHeaders = await this.#getAuthHeaders();
|
|
473
|
+
const response = await fetch(url, { headers: authHeaders });
|
|
474
|
+
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_TRADER_FOLLOWING_FAILED);
|
|
475
|
+
const followingData = (await response.json());
|
|
476
|
+
if (!is(followingData, FollowingResponseStruct)) {
|
|
477
|
+
throw new Error(SocialServiceErrorMessage.FETCH_TRADER_FOLLOWING_INVALID_RESPONSE);
|
|
478
|
+
}
|
|
479
|
+
return followingData;
|
|
480
|
+
},
|
|
481
|
+
});
|
|
482
|
+
return followingResponse;
|
|
483
|
+
}
|
|
387
484
|
/**
|
|
388
485
|
* Fetches a single position by its unique ID.
|
|
389
486
|
*
|
|
@@ -402,7 +499,7 @@ export class SocialService extends BaseDataService {
|
|
|
402
499
|
const authHeaders = await this.#getAuthHeaders();
|
|
403
500
|
const response = await fetch(url, { headers: authHeaders });
|
|
404
501
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_POSITION_BY_ID_FAILED);
|
|
405
|
-
const positionData = await response.json();
|
|
502
|
+
const positionData = (await response.json());
|
|
406
503
|
if (!is(positionData, PositionStruct)) {
|
|
407
504
|
throw new Error(SocialServiceErrorMessage.FETCH_POSITION_BY_ID_INVALID_RESPONSE);
|
|
408
505
|
}
|
|
@@ -459,11 +556,8 @@ export class SocialService extends BaseDataService {
|
|
|
459
556
|
headers: authHeaders,
|
|
460
557
|
});
|
|
461
558
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_FEED_FAILED);
|
|
462
|
-
const feedData = await response.json();
|
|
463
|
-
|
|
464
|
-
throw new Error(SocialServiceErrorMessage.FETCH_FEED_INVALID_RESPONSE);
|
|
465
|
-
}
|
|
466
|
-
return feedData;
|
|
559
|
+
const feedData = (await response.json());
|
|
560
|
+
return parseFeedResponse(feedData, SocialServiceErrorMessage.FETCH_FEED_INVALID_RESPONSE);
|
|
467
561
|
},
|
|
468
562
|
});
|
|
469
563
|
return feedResponse;
|
|
@@ -516,11 +610,8 @@ export class SocialService extends BaseDataService {
|
|
|
516
610
|
headers: authHeaders,
|
|
517
611
|
});
|
|
518
612
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_TRADER_FEED_FAILED);
|
|
519
|
-
const feedData = await response.json();
|
|
520
|
-
|
|
521
|
-
throw new Error(SocialServiceErrorMessage.FETCH_TRADER_FEED_INVALID_RESPONSE);
|
|
522
|
-
}
|
|
523
|
-
return feedData;
|
|
613
|
+
const feedData = (await response.json());
|
|
614
|
+
return parseFeedResponse(feedData, SocialServiceErrorMessage.FETCH_TRADER_FEED_INVALID_RESPONSE);
|
|
524
615
|
},
|
|
525
616
|
});
|
|
526
617
|
return traderFeedResponse;
|
|
@@ -575,10 +666,7 @@ export class SocialService extends BaseDataService {
|
|
|
575
666
|
});
|
|
576
667
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_TOKEN_FEED_FAILED);
|
|
577
668
|
const feedData = (await response.json());
|
|
578
|
-
|
|
579
|
-
throw new Error(SocialServiceErrorMessage.FETCH_TOKEN_FEED_INVALID_RESPONSE);
|
|
580
|
-
}
|
|
581
|
-
return feedData;
|
|
669
|
+
return parseFeedResponse(feedData, SocialServiceErrorMessage.FETCH_TOKEN_FEED_INVALID_RESPONSE);
|
|
582
670
|
},
|
|
583
671
|
});
|
|
584
672
|
return tokenFeedResponse;
|
|
@@ -608,7 +696,7 @@ export class SocialService extends BaseDataService {
|
|
|
608
696
|
body: JSON.stringify({ emotion }),
|
|
609
697
|
});
|
|
610
698
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.REACT_TO_COMMENT_FAILED);
|
|
611
|
-
const metrics = await response.json();
|
|
699
|
+
const metrics = (await response.json());
|
|
612
700
|
if (!is(metrics, CommentEngagementStruct)) {
|
|
613
701
|
throw new Error(SocialServiceErrorMessage.REACT_TO_COMMENT_INVALID_RESPONSE);
|
|
614
702
|
}
|
|
@@ -639,7 +727,7 @@ export class SocialService extends BaseDataService {
|
|
|
639
727
|
headers: authHeaders,
|
|
640
728
|
});
|
|
641
729
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.REMOVE_COMMENT_REACTION_FAILED);
|
|
642
|
-
const metrics = await response.json();
|
|
730
|
+
const metrics = (await response.json());
|
|
643
731
|
if (!is(metrics, CommentEngagementStruct)) {
|
|
644
732
|
throw new Error(SocialServiceErrorMessage.REMOVE_COMMENT_REACTION_INVALID_RESPONSE);
|
|
645
733
|
}
|
|
@@ -704,6 +792,10 @@ export class SocialService extends BaseDataService {
|
|
|
704
792
|
* Calls `GET ${baseUrl}/users/me/following`. The caller is identified
|
|
705
793
|
* server-side from the JWT sub claim carried in the Authorization header.
|
|
706
794
|
*
|
|
795
|
+
* Prefer {@link fetchMyFollowing} in new code (pairs with
|
|
796
|
+
* {@link fetchMyFollowers}). This method is unchanged and remains the
|
|
797
|
+
* `/users/me/following` read.
|
|
798
|
+
*
|
|
707
799
|
* @returns The following response.
|
|
708
800
|
*/
|
|
709
801
|
async fetchFollowing() {
|
|
@@ -715,7 +807,7 @@ export class SocialService extends BaseDataService {
|
|
|
715
807
|
const authHeaders = await this.#getAuthHeaders();
|
|
716
808
|
const response = await fetch(url, { headers: authHeaders });
|
|
717
809
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_FOLLOWING_FAILED);
|
|
718
|
-
const followingData = await response.json();
|
|
810
|
+
const followingData = (await response.json());
|
|
719
811
|
if (!is(followingData, FollowingResponseStruct)) {
|
|
720
812
|
throw new Error(SocialServiceErrorMessage.FETCH_FOLLOWING_INVALID_RESPONSE);
|
|
721
813
|
}
|
|
@@ -724,6 +816,43 @@ export class SocialService extends BaseDataService {
|
|
|
724
816
|
});
|
|
725
817
|
return followingResponse;
|
|
726
818
|
}
|
|
819
|
+
/**
|
|
820
|
+
* Fetches the list of traders the current user is following.
|
|
821
|
+
*
|
|
822
|
+
* Alias of {@link fetchFollowing}. Calls `GET ${baseUrl}/users/me/following`.
|
|
823
|
+
* Preferred name in new code so `/users/me` reads are both `fetchMy*`.
|
|
824
|
+
*
|
|
825
|
+
* @returns The following response.
|
|
826
|
+
*/
|
|
827
|
+
async fetchMyFollowing() {
|
|
828
|
+
return this.fetchFollowing();
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Fetches the list of traders following the current user.
|
|
832
|
+
*
|
|
833
|
+
* Calls `GET ${baseUrl}/users/me/followers`. The caller is identified
|
|
834
|
+
* server-side from the JWT sub claim carried in the Authorization header.
|
|
835
|
+
*
|
|
836
|
+
* @returns The followers response.
|
|
837
|
+
*/
|
|
838
|
+
async fetchMyFollowers() {
|
|
839
|
+
const followersResponse = await this.fetchQuery({
|
|
840
|
+
queryKey: [`${this.name}:fetchMyFollowers`],
|
|
841
|
+
staleTime: 0,
|
|
842
|
+
queryFn: async () => {
|
|
843
|
+
const url = `${this.#v1Url}/users/me/followers`;
|
|
844
|
+
const authHeaders = await this.#getAuthHeaders();
|
|
845
|
+
const response = await fetch(url, { headers: authHeaders });
|
|
846
|
+
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_MY_FOLLOWERS_FAILED);
|
|
847
|
+
const followersData = (await response.json());
|
|
848
|
+
if (!is(followersData, FollowersResponseStruct)) {
|
|
849
|
+
throw new Error(SocialServiceErrorMessage.FETCH_MY_FOLLOWERS_INVALID_RESPONSE);
|
|
850
|
+
}
|
|
851
|
+
return followersData;
|
|
852
|
+
},
|
|
853
|
+
});
|
|
854
|
+
return followersResponse;
|
|
855
|
+
}
|
|
727
856
|
/**
|
|
728
857
|
* Follows one or more traders on behalf of the current user.
|
|
729
858
|
*
|
|
@@ -748,7 +877,7 @@ export class SocialService extends BaseDataService {
|
|
|
748
877
|
body: JSON.stringify({ targets }),
|
|
749
878
|
});
|
|
750
879
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FOLLOW_FAILED);
|
|
751
|
-
const followData = await response.json();
|
|
880
|
+
const followData = (await response.json());
|
|
752
881
|
if (!is(followData, FollowResponseStruct)) {
|
|
753
882
|
throw new Error(SocialServiceErrorMessage.FOLLOW_INVALID_RESPONSE);
|
|
754
883
|
}
|
|
@@ -785,7 +914,7 @@ export class SocialService extends BaseDataService {
|
|
|
785
914
|
headers: authHeaders,
|
|
786
915
|
});
|
|
787
916
|
_a.#throwIfNotOk(response, SocialServiceErrorMessage.UNFOLLOW_FAILED);
|
|
788
|
-
const unfollowData = await response.json();
|
|
917
|
+
const unfollowData = (await response.json());
|
|
789
918
|
if (!is(unfollowData, UnfollowResponseStruct)) {
|
|
790
919
|
throw new Error(SocialServiceErrorMessage.UNFOLLOW_INVALID_RESPONSE);
|
|
791
920
|
}
|
|
@@ -864,6 +993,105 @@ export class SocialService extends BaseDataService {
|
|
|
864
993
|
},
|
|
865
994
|
});
|
|
866
995
|
}
|
|
996
|
+
/**
|
|
997
|
+
* Blocks a trader, swap comment, or reply for the current user.
|
|
998
|
+
*
|
|
999
|
+
* Calls `PUT ${baseUrl}/moderation/block`. Provide exactly one of
|
|
1000
|
+
* `profileId`, `commentId`, or `replyId`. Blocking the same target again
|
|
1001
|
+
* replaces `reason` when one is given. The caller is identified server-side
|
|
1002
|
+
* from the JWT sub claim carried in the Authorization header.
|
|
1003
|
+
*
|
|
1004
|
+
* @param options - Options bag. Exactly one target, plus an optional reason.
|
|
1005
|
+
* @param options.profileId - Profile id (UUID) of the trader to block.
|
|
1006
|
+
* @param options.commentId - Swap comment to block.
|
|
1007
|
+
* @param options.replyId - Comment reply to block.
|
|
1008
|
+
* @param options.reason - Free-form reason stored on the block.
|
|
1009
|
+
*/
|
|
1010
|
+
async block(options) {
|
|
1011
|
+
await this.fetchQuery({
|
|
1012
|
+
queryKey: [`${this.name}:block`, options],
|
|
1013
|
+
staleTime: 0,
|
|
1014
|
+
queryFn: async () => {
|
|
1015
|
+
const url = `${this.#v1Url}/moderation/block`;
|
|
1016
|
+
const authHeaders = await this.#getAuthHeaders();
|
|
1017
|
+
const response = await fetch(url, {
|
|
1018
|
+
method: 'PUT',
|
|
1019
|
+
headers: { ...authHeaders, 'Content-Type': 'application/json' },
|
|
1020
|
+
body: JSON.stringify(options),
|
|
1021
|
+
});
|
|
1022
|
+
_a.#throwIfNotOk(response, SocialServiceErrorMessage.BLOCK_FAILED);
|
|
1023
|
+
return null;
|
|
1024
|
+
},
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Fetches traders the current user has blocked.
|
|
1029
|
+
*
|
|
1030
|
+
* Calls `GET ${baseUrl}/moderation/blocks/profiles`. Results are most
|
|
1031
|
+
* recently blocked first, 250 per page. The caller is identified
|
|
1032
|
+
* server-side from the JWT sub claim carried in the Authorization header.
|
|
1033
|
+
*
|
|
1034
|
+
* @param options - Options bag.
|
|
1035
|
+
* @param options.cursor - Cursor from the previous page. Omit for the first page.
|
|
1036
|
+
* @returns The blocked profiles page.
|
|
1037
|
+
*/
|
|
1038
|
+
async fetchBlockedProfiles(options) {
|
|
1039
|
+
const cursor = options?.cursor;
|
|
1040
|
+
return await this.fetchQuery({
|
|
1041
|
+
queryKey: [`${this.name}:fetchBlockedProfiles`, cursor ?? null],
|
|
1042
|
+
staleTime: 0,
|
|
1043
|
+
queryFn: async () => {
|
|
1044
|
+
const url = new URL(`${this.#v1Url}/moderation/blocks/profiles`);
|
|
1045
|
+
if (cursor) {
|
|
1046
|
+
url.searchParams.append('cursor', cursor);
|
|
1047
|
+
}
|
|
1048
|
+
const authHeaders = await this.#getAuthHeaders();
|
|
1049
|
+
const response = await fetch(url.toString(), {
|
|
1050
|
+
headers: authHeaders,
|
|
1051
|
+
});
|
|
1052
|
+
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_BLOCKED_PROFILES_FAILED);
|
|
1053
|
+
const blockedProfiles = (await response.json());
|
|
1054
|
+
if (!is(blockedProfiles, BlockedProfilesResponseStruct)) {
|
|
1055
|
+
throw new Error(SocialServiceErrorMessage.FETCH_BLOCKED_PROFILES_INVALID_RESPONSE);
|
|
1056
|
+
}
|
|
1057
|
+
return blockedProfiles;
|
|
1058
|
+
},
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Fetches comments and replies the current user has blocked.
|
|
1063
|
+
*
|
|
1064
|
+
* Calls `GET ${baseUrl}/moderation/blocks/content`. Results are most
|
|
1065
|
+
* recently blocked first, 250 per page. The caller is identified
|
|
1066
|
+
* server-side from the JWT sub claim carried in the Authorization header.
|
|
1067
|
+
*
|
|
1068
|
+
* @param options - Options bag.
|
|
1069
|
+
* @param options.cursor - Cursor from the previous page. Omit for the first page.
|
|
1070
|
+
* @returns The blocked content page.
|
|
1071
|
+
*/
|
|
1072
|
+
async fetchBlockedContent(options) {
|
|
1073
|
+
const cursor = options?.cursor;
|
|
1074
|
+
return await this.fetchQuery({
|
|
1075
|
+
queryKey: [`${this.name}:fetchBlockedContent`, cursor ?? null],
|
|
1076
|
+
staleTime: 0,
|
|
1077
|
+
queryFn: async () => {
|
|
1078
|
+
const url = new URL(`${this.#v1Url}/moderation/blocks/content`);
|
|
1079
|
+
if (cursor) {
|
|
1080
|
+
url.searchParams.append('cursor', cursor);
|
|
1081
|
+
}
|
|
1082
|
+
const authHeaders = await this.#getAuthHeaders();
|
|
1083
|
+
const response = await fetch(url.toString(), {
|
|
1084
|
+
headers: authHeaders,
|
|
1085
|
+
});
|
|
1086
|
+
_a.#throwIfNotOk(response, SocialServiceErrorMessage.FETCH_BLOCKED_CONTENT_FAILED);
|
|
1087
|
+
const blockedContent = (await response.json());
|
|
1088
|
+
if (!is(blockedContent, BlockedContentResponseStruct)) {
|
|
1089
|
+
throw new Error(SocialServiceErrorMessage.FETCH_BLOCKED_CONTENT_INVALID_RESPONSE);
|
|
1090
|
+
}
|
|
1091
|
+
return blockedContent;
|
|
1092
|
+
},
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
867
1095
|
/**
|
|
868
1096
|
* Shared helper for fetching open/closed positions.
|
|
869
1097
|
*
|
|
@@ -911,7 +1139,7 @@ export class SocialService extends BaseDataService {
|
|
|
911
1139
|
headers: authHeaders,
|
|
912
1140
|
});
|
|
913
1141
|
_a.#throwIfNotOk(response, failedMessage);
|
|
914
|
-
const positionsData = await response.json();
|
|
1142
|
+
const positionsData = (await response.json());
|
|
915
1143
|
if (!is(positionsData, PositionsResponseStruct)) {
|
|
916
1144
|
throw new Error(invalidMessage);
|
|
917
1145
|
}
|