@nadohq/mobile-client 0.66.0 → 0.67.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/README.md +110 -17
- package/dist/{MobileClient-M4oC4lrX.cjs → MobileClient-vuI5wlB_.cjs} +69 -29
- package/dist/MobileClient-vuI5wlB_.cjs.map +1 -0
- package/dist/MobileClient.cjs +1 -1
- package/dist/MobileClient.d.cts +50 -25
- package/dist/MobileClient.d.cts.map +1 -1
- package/dist/MobileClient.d.ts +50 -25
- package/dist/MobileClient.d.ts.map +1 -1
- package/dist/MobileClient.js +69 -29
- package/dist/MobileClient.js.map +1 -1
- package/dist/{MobileServerFailureError-MtS2reel.d.cts → MobileServerFailureError-BeCCNShj.d.cts} +2 -2
- package/dist/{MobileServerFailureError-MtS2reel.d.cts.map → MobileServerFailureError-BeCCNShj.d.cts.map} +1 -1
- package/dist/{MobileServerFailureError-C9iqNsxI.d.ts → MobileServerFailureError-hHv28weI.d.ts} +2 -2
- package/dist/{MobileServerFailureError-C9iqNsxI.d.ts.map → MobileServerFailureError-hHv28weI.d.ts.map} +1 -1
- package/dist/{buildSignedMobileRequest-DyKCK34Y.d.cts → buildSignedMobileRequest-DcEMKU_4.d.cts} +2 -2
- package/dist/{buildSignedMobileRequest-DyKCK34Y.d.cts.map → buildSignedMobileRequest-DcEMKU_4.d.cts.map} +1 -1
- package/dist/{buildSignedMobileRequest-BR-KJhIF.d.ts → buildSignedMobileRequest-DlTMvoXR.d.ts} +2 -2
- package/dist/{buildSignedMobileRequest-BR-KJhIF.d.ts.map → buildSignedMobileRequest-DlTMvoXR.d.ts.map} +1 -1
- package/dist/{canonicalize-Bv6UIAbR.d.ts → canonicalize-BOZlflI3.d.ts} +2 -2
- package/dist/canonicalize-BOZlflI3.d.ts.map +1 -0
- package/dist/{canonicalize-CWh3XZzj.d.cts → canonicalize-BvCozzvJ.d.cts} +2 -2
- package/dist/canonicalize-BvCozzvJ.d.cts.map +1 -0
- package/dist/{clientTypes-DOpUcu80.d.cts → clientTypes-KpHlCDGZ.d.cts} +75 -49
- package/dist/clientTypes-KpHlCDGZ.d.cts.map +1 -0
- package/dist/{clientTypes-BUn5_OzK.d.ts → clientTypes-XRI41VdC.d.ts} +75 -49
- package/dist/clientTypes-XRI41VdC.d.ts.map +1 -0
- package/dist/dataMappers.cjs +56 -17
- package/dist/dataMappers.cjs.map +1 -1
- package/dist/dataMappers.d.cts +33 -13
- package/dist/dataMappers.d.cts.map +1 -1
- package/dist/dataMappers.d.ts +33 -13
- package/dist/dataMappers.d.ts.map +1 -1
- package/dist/dataMappers.js +53 -17
- package/dist/dataMappers.js.map +1 -1
- package/dist/{eip712MethodByType-CJ6BoayT.d.cts → eip712MethodByType-DyAmzH7b.d.cts} +2 -2
- package/dist/eip712MethodByType-DyAmzH7b.d.cts.map +1 -0
- package/dist/{eip712MethodByType-Dx4mvgni.d.ts → eip712MethodByType-qSSAF6i2.d.ts} +2 -2
- package/dist/eip712MethodByType-qSSAF6i2.d.ts.map +1 -0
- package/dist/feed-BrgkFqP3.d.cts +23 -0
- package/dist/feed-BrgkFqP3.d.cts.map +1 -0
- package/dist/feed-DcbhLoo1.d.ts +23 -0
- package/dist/feed-DcbhLoo1.d.ts.map +1 -0
- package/dist/index-BVVgDSdq.d.cts +1 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.js +2 -2
- package/dist/{mobileErrorCodes-vD6rbFuF.d.ts → mobileErrorCodes-CdwX6QTO.d.cts} +3 -3
- package/dist/{mobileErrorCodes-vD6rbFuF.d.cts.map → mobileErrorCodes-CdwX6QTO.d.cts.map} +1 -1
- package/dist/{mobileErrorCodes-vD6rbFuF.d.cts → mobileErrorCodes-CdwX6QTO.d.ts} +3 -3
- package/dist/{mobileErrorCodes-vD6rbFuF.d.ts.map → mobileErrorCodes-CdwX6QTO.d.ts.map} +1 -1
- package/dist/{payloadHash-CdkF2Ocr.d.cts → payloadHash-BgGSZock.d.cts} +2 -2
- package/dist/payloadHash-BgGSZock.d.cts.map +1 -0
- package/dist/{payloadHash-HD29K77M.d.ts → payloadHash-Bi6upCLQ.d.ts} +2 -2
- package/dist/payloadHash-Bi6upCLQ.d.ts.map +1 -0
- package/dist/{serverExecuteTypes-5JyyIXRK.d.ts → serverExecuteTypes-DuCWe_H_.d.cts} +7 -14
- package/dist/{serverExecuteTypes-CHrQ9Rtq.d.cts.map → serverExecuteTypes-DuCWe_H_.d.cts.map} +1 -1
- package/dist/{serverExecuteTypes-CHrQ9Rtq.d.cts → serverExecuteTypes-usJ6HMJv.d.ts} +7 -14
- package/dist/{serverExecuteTypes-5JyyIXRK.d.ts.map → serverExecuteTypes-usJ6HMJv.d.ts.map} +1 -1
- package/dist/{serverModelTypes-CGUZCi0y.d.ts → serverModelTypes-CTHMNIQS.d.cts} +16 -14
- package/dist/serverModelTypes-CTHMNIQS.d.cts.map +1 -0
- package/dist/{serverModelTypes-CGUZCi0y.d.cts → serverModelTypes-CTHMNIQS.d.ts} +16 -14
- package/dist/serverModelTypes-CTHMNIQS.d.ts.map +1 -0
- package/dist/{serverResponseGuards-i1njcYKN.d.cts → serverResponseGuards-CzmldAad.d.cts} +2 -2
- package/dist/{serverResponseGuards-i1njcYKN.d.cts.map → serverResponseGuards-CzmldAad.d.cts.map} +1 -1
- package/dist/{serverResponseGuards-Bvw8ltYJ.d.ts → serverResponseGuards-Dvkbjp2_.d.ts} +2 -2
- package/dist/{serverResponseGuards-Bvw8ltYJ.d.ts.map → serverResponseGuards-Dvkbjp2_.d.ts.map} +1 -1
- package/dist/signing/buildSignedMobileRequest.d.cts +1 -1
- package/dist/signing/buildSignedMobileRequest.d.ts +1 -1
- package/dist/signing/canonicalize.cjs +4 -2
- package/dist/signing/canonicalize.cjs.map +1 -1
- package/dist/signing/canonicalize.d.cts +1 -1
- package/dist/signing/canonicalize.d.ts +1 -1
- package/dist/signing/canonicalize.js +4 -2
- package/dist/signing/canonicalize.js.map +1 -1
- package/dist/signing/eip712MethodByType.d.cts +1 -1
- package/dist/signing/eip712MethodByType.d.ts +1 -1
- package/dist/signing/index.d.cts +5 -5
- package/dist/signing/index.d.ts +5 -5
- package/dist/signing/payloadHash.d.cts +1 -1
- package/dist/signing/payloadHash.d.ts +1 -1
- package/dist/signing/types.d.cts +1 -1
- package/dist/signing/types.d.ts +1 -1
- package/dist/types/MobileServerFailureError.d.cts +1 -1
- package/dist/types/MobileServerFailureError.d.ts +1 -1
- package/dist/types/clientTypes.d.cts +2 -2
- package/dist/types/clientTypes.d.ts +2 -2
- package/dist/types/index.d.cts +7 -7
- package/dist/types/index.d.ts +7 -7
- package/dist/types/mobileErrorCodes.cjs +2 -2
- package/dist/types/mobileErrorCodes.cjs.map +1 -1
- package/dist/types/mobileErrorCodes.d.cts +1 -1
- package/dist/types/mobileErrorCodes.d.ts +1 -1
- package/dist/types/mobileErrorCodes.js +2 -2
- package/dist/types/mobileErrorCodes.js.map +1 -1
- package/dist/types/serverBaseTypes.d.cts +1 -1
- package/dist/types/serverBaseTypes.d.ts +1 -1
- package/dist/types/serverExecuteTypes.d.cts +2 -2
- package/dist/types/serverExecuteTypes.d.ts +2 -2
- package/dist/types/serverModelTypes.cjs.map +1 -1
- package/dist/types/serverModelTypes.d.cts +2 -2
- package/dist/types/serverModelTypes.d.ts +2 -2
- package/dist/types/serverModelTypes.js.map +1 -1
- package/dist/types/serverQueryTypes.d.cts +2 -2
- package/dist/types/serverQueryTypes.d.ts +2 -2
- package/dist/types/serverRequestTypes.d.cts +1 -1
- package/dist/types/serverRequestTypes.d.ts +1 -1
- package/dist/{types-C9YE4EIt.d.cts → types-CByl_NyJ.d.ts} +49 -18
- package/dist/types-CByl_NyJ.d.ts.map +1 -0
- package/dist/{types-Cwy1y_9x.d.ts → types-CR5iaKR4.d.cts} +49 -18
- package/dist/types-CR5iaKR4.d.cts.map +1 -0
- package/dist/utils/feed.cjs +9 -0
- package/dist/utils/feed.cjs.map +1 -1
- package/dist/utils/feed.d.cts +2 -2
- package/dist/utils/feed.d.ts +2 -2
- package/dist/utils/feed.js +9 -1
- package/dist/utils/feed.js.map +1 -1
- package/dist/utils/index.cjs +1 -0
- package/dist/utils/index.d.cts +3 -3
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +2 -2
- package/dist/utils/serverResponseGuards.d.cts +1 -1
- package/dist/utils/serverResponseGuards.d.ts +1 -1
- package/package.json +3 -3
- package/src/MobileClient.ts +82 -34
- package/src/dataMappers.test.ts +408 -9
- package/src/dataMappers.ts +76 -23
- package/src/signing/canonicalize.ts +6 -0
- package/src/signing/signing.test.ts +51 -0
- package/src/signing/types.ts +4 -0
- package/src/socialFeed.test.ts +53 -28
- package/src/types/clientTypes.ts +82 -47
- package/src/types/mobileErrorCodes.ts +2 -2
- package/src/types/serverExecuteTypes.ts +4 -12
- package/src/types/serverModelTypes.ts +19 -13
- package/src/types/serverQueryTypes.ts +32 -4
- package/src/types/serverRequestTypes.ts +20 -12
- package/src/utils/feed.ts +13 -0
- package/dist/MobileClient-M4oC4lrX.cjs.map +0 -1
- package/dist/canonicalize-Bv6UIAbR.d.ts.map +0 -1
- package/dist/canonicalize-CWh3XZzj.d.cts.map +0 -1
- package/dist/clientTypes-BUn5_OzK.d.ts.map +0 -1
- package/dist/clientTypes-DOpUcu80.d.cts.map +0 -1
- package/dist/eip712MethodByType-CJ6BoayT.d.cts.map +0 -1
- package/dist/eip712MethodByType-Dx4mvgni.d.ts.map +0 -1
- package/dist/feed-DErOLaoY.d.cts +0 -16
- package/dist/feed-DErOLaoY.d.cts.map +0 -1
- package/dist/feed-DErOLaoY.d.ts +0 -16
- package/dist/feed-DErOLaoY.d.ts.map +0 -1
- package/dist/payloadHash-CdkF2Ocr.d.cts.map +0 -1
- package/dist/payloadHash-HD29K77M.d.ts.map +0 -1
- package/dist/serverModelTypes-CGUZCi0y.d.cts.map +0 -1
- package/dist/serverModelTypes-CGUZCi0y.d.ts.map +0 -1
- package/dist/types-C9YE4EIt.d.cts.map +0 -1
- package/dist/types-Cwy1y_9x.d.ts.map +0 -1
package/src/dataMappers.test.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import { createWalletClient, http } from 'viem';
|
|
3
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
4
|
+
import { ink } from 'viem/chains';
|
|
2
5
|
import {
|
|
3
6
|
mapMobileSocialFeedActionCandidate,
|
|
4
7
|
mapMobileSocialFeedCommentsPage,
|
|
@@ -13,16 +16,22 @@ import {
|
|
|
13
16
|
mapMobileSocialFeedPositionChart,
|
|
14
17
|
mapMobileSocialFeedPositionHistory,
|
|
15
18
|
mapMobileSocialFeedPositionPatch,
|
|
19
|
+
mapMobileSocialFeedPositionThoughts,
|
|
16
20
|
mapMobileSocialFeedPresence,
|
|
17
21
|
mapMobileSocialFeedTradeCard,
|
|
18
22
|
} from './dataMappers';
|
|
23
|
+
import { MobileClient } from './MobileClient';
|
|
19
24
|
import { MobileUnsupportedFeedItemError } from './types/MobileUnsupportedFeedItemError';
|
|
20
25
|
import {
|
|
21
26
|
MobileServerSocialFeedItem,
|
|
22
27
|
MobileServerSocialFeedPost,
|
|
23
28
|
MobileServerSocialFeedReply,
|
|
24
29
|
} from './types/serverModelTypes';
|
|
25
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
MobileServerSocialFeedPositionHistoryResponse,
|
|
32
|
+
MobileServerSocialFeedPositionThoughtsResponse,
|
|
33
|
+
} from './types/serverQueryTypes';
|
|
34
|
+
import { isMobileSocialFeedUploadedImage } from './utils';
|
|
26
35
|
|
|
27
36
|
const post: MobileServerSocialFeedPost = {
|
|
28
37
|
id: '88888888-8888-4888-8888-888888888888',
|
|
@@ -182,6 +191,7 @@ const reply: MobileServerSocialFeedReply = {
|
|
|
182
191
|
drawing: null,
|
|
183
192
|
};
|
|
184
193
|
const history: MobileServerSocialFeedPositionHistoryResponse = {
|
|
194
|
+
owner: post.author,
|
|
185
195
|
position: {
|
|
186
196
|
position_id: '22222222-2222-4222-8222-222222222222',
|
|
187
197
|
product_id: 2,
|
|
@@ -365,9 +375,6 @@ const history: MobileServerSocialFeedPositionHistoryResponse = {
|
|
|
365
375
|
expires_at_ms: 1791072900000,
|
|
366
376
|
update_cursor: null,
|
|
367
377
|
viewer_token: 'viewer_example_opaque',
|
|
368
|
-
view_tracking: {
|
|
369
|
-
mode: 'detail_visit',
|
|
370
|
-
},
|
|
371
378
|
},
|
|
372
379
|
};
|
|
373
380
|
|
|
@@ -549,8 +556,9 @@ describe('[mobile-client]: content mapping', () => {
|
|
|
549
556
|
).toMatchObject({ kind: item.kind, images: [] });
|
|
550
557
|
}
|
|
551
558
|
const comments = mapMobileSocialFeedCommentsPage({
|
|
552
|
-
comments: [serverReply],
|
|
559
|
+
comments: [{ ...serverReply, replies: [] }],
|
|
553
560
|
total_count: 1,
|
|
561
|
+
top_level_count: 1,
|
|
554
562
|
next_cursor: null,
|
|
555
563
|
previous_cursor: null,
|
|
556
564
|
anchor_reply_id: null,
|
|
@@ -559,7 +567,7 @@ describe('[mobile-client]: content mapping', () => {
|
|
|
559
567
|
expect(comments.comments).toMatchObject([{ kind: 'reply', images: [] }]);
|
|
560
568
|
});
|
|
561
569
|
|
|
562
|
-
it('maps feed images and
|
|
570
|
+
it('maps feed images and read sessions without obsolete view tracking', () => {
|
|
563
571
|
const mapped = mapMobileSocialFeedItem({
|
|
564
572
|
...post,
|
|
565
573
|
images: [
|
|
@@ -601,8 +609,14 @@ describe('[mobile-client]: content mapping', () => {
|
|
|
601
609
|
next_cursor: null,
|
|
602
610
|
watermark: 'w',
|
|
603
611
|
read_session: history.read_session,
|
|
604
|
-
}).readSession
|
|
605
|
-
).toEqual({
|
|
612
|
+
}).readSession,
|
|
613
|
+
).toEqual({
|
|
614
|
+
sessionId: history.read_session.session_id,
|
|
615
|
+
mode: history.read_session.mode,
|
|
616
|
+
expiresAtMs: history.read_session.expires_at_ms,
|
|
617
|
+
updateCursor: history.read_session.update_cursor,
|
|
618
|
+
viewerToken: history.read_session.viewer_token,
|
|
619
|
+
});
|
|
606
620
|
});
|
|
607
621
|
|
|
608
622
|
it('maps posts, drawings, reply previews, and nullable badges from the documented response', () => {
|
|
@@ -805,16 +819,18 @@ describe('[mobile-client]: content mapping', () => {
|
|
|
805
819
|
|
|
806
820
|
it('maps comment cursors and anchor without inventing an observation timestamp', () => {
|
|
807
821
|
const result = mapMobileSocialFeedCommentsPage({
|
|
808
|
-
comments: [reply],
|
|
822
|
+
comments: [{ ...reply, replies: [] }],
|
|
809
823
|
next_cursor: 'NextOpaque',
|
|
810
824
|
previous_cursor: 'PreviousOpaque',
|
|
811
825
|
total_count: 8,
|
|
826
|
+
top_level_count: 3,
|
|
812
827
|
anchor_reply_id: reply.id,
|
|
813
828
|
read_session: history.read_session,
|
|
814
829
|
});
|
|
815
830
|
expect(result.nextCursor).toBe('NextOpaque');
|
|
816
831
|
expect(result.previousCursor).toBe('PreviousOpaque');
|
|
817
832
|
expect(result.anchorReplyId).toBe(reply.id);
|
|
833
|
+
expect(result.topLevelCount).toBe(3);
|
|
818
834
|
expect(result).not.toHaveProperty('asOfMs');
|
|
819
835
|
});
|
|
820
836
|
|
|
@@ -832,6 +848,85 @@ describe('[mobile-client]: content mapping', () => {
|
|
|
832
848
|
expect(result).not.toHaveProperty('asOfMs');
|
|
833
849
|
});
|
|
834
850
|
|
|
851
|
+
it('preserves complete flat comment groups, descendant parents, counts, and an anchor at any depth', () => {
|
|
852
|
+
const child = {
|
|
853
|
+
...reply,
|
|
854
|
+
id: '44444444-4444-4444-8444-444444444444',
|
|
855
|
+
reply_to_item_id: reply.id,
|
|
856
|
+
reply_to_author: reply.author,
|
|
857
|
+
};
|
|
858
|
+
const grandchild = {
|
|
859
|
+
...child,
|
|
860
|
+
id: '55555555-5555-4555-8555-555555555555',
|
|
861
|
+
reply_to_item_id: child.id,
|
|
862
|
+
images: [{ url: 'https://example.com/reply.png' }],
|
|
863
|
+
};
|
|
864
|
+
const mapped = mapMobileSocialFeedCommentsPage({
|
|
865
|
+
comments: [
|
|
866
|
+
{
|
|
867
|
+
...reply,
|
|
868
|
+
reply_to_item_id: undefined,
|
|
869
|
+
reply_to_author: null,
|
|
870
|
+
replies: [child, grandchild],
|
|
871
|
+
},
|
|
872
|
+
{ ...reply, id: '66666666-6666-4666-8666-666666666666', replies: [] },
|
|
873
|
+
],
|
|
874
|
+
total_count: 12,
|
|
875
|
+
top_level_count: 5,
|
|
876
|
+
next_cursor: 'NextGroup',
|
|
877
|
+
previous_cursor: 'PreviousGroup',
|
|
878
|
+
anchor_reply_id: grandchild.id,
|
|
879
|
+
read_session: history.read_session,
|
|
880
|
+
});
|
|
881
|
+
expect(mapped.comments.map((group) => group.id)).toEqual([
|
|
882
|
+
reply.id,
|
|
883
|
+
'66666666-6666-4666-8666-666666666666',
|
|
884
|
+
]);
|
|
885
|
+
expect(mapped.comments[0]).not.toHaveProperty('replyToItemId');
|
|
886
|
+
expect(mapped.comments[0].replyToAuthor).toBeNull();
|
|
887
|
+
expect(mapped.comments[0].replies.map((item) => item.id)).toEqual([
|
|
888
|
+
child.id,
|
|
889
|
+
grandchild.id,
|
|
890
|
+
]);
|
|
891
|
+
expect(
|
|
892
|
+
mapped.comments[0].replies.map((item) => item.replyToItemId),
|
|
893
|
+
).toEqual([reply.id, child.id]);
|
|
894
|
+
expect(mapped.comments[0].replies[1].images).toEqual(grandchild.images);
|
|
895
|
+
expect(mapped.comments[0].replies[1].replyToAuthor?.displayName).toBe(
|
|
896
|
+
reply.author.display_name,
|
|
897
|
+
);
|
|
898
|
+
expect(mapped.comments[0].replies[1].interaction.viewCount).toBe(
|
|
899
|
+
reply.interaction.view_count,
|
|
900
|
+
);
|
|
901
|
+
expect(mapped.comments[0].replies[0]).not.toHaveProperty('replies');
|
|
902
|
+
expect(mapped.comments[1].replies).toEqual([]);
|
|
903
|
+
expect(mapped).toMatchObject({
|
|
904
|
+
totalCount: 12,
|
|
905
|
+
topLevelCount: 5,
|
|
906
|
+
nextCursor: 'NextGroup',
|
|
907
|
+
previousCursor: 'PreviousGroup',
|
|
908
|
+
anchorReplyId: grandchild.id,
|
|
909
|
+
});
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
it('preserves an empty comment window with continuation and whole-thread counts', () => {
|
|
913
|
+
const mapped = mapMobileSocialFeedCommentsPage({
|
|
914
|
+
comments: [],
|
|
915
|
+
total_count: 8,
|
|
916
|
+
top_level_count: 3,
|
|
917
|
+
next_cursor: 'NextGroup',
|
|
918
|
+
previous_cursor: null,
|
|
919
|
+
anchor_reply_id: null,
|
|
920
|
+
read_session: history.read_session,
|
|
921
|
+
});
|
|
922
|
+
expect(mapped.comments).toEqual([]);
|
|
923
|
+
expect(mapped).toMatchObject({
|
|
924
|
+
totalCount: 8,
|
|
925
|
+
topLevelCount: 3,
|
|
926
|
+
nextCursor: 'NextGroup',
|
|
927
|
+
});
|
|
928
|
+
});
|
|
929
|
+
|
|
835
930
|
it('keeps mention labels and code-point offsets intact', () => {
|
|
836
931
|
const result = mapMobileSocialFeedMentionToServer({
|
|
837
932
|
subaccount: {
|
|
@@ -846,3 +941,307 @@ describe('[mobile-client]: content mapping', () => {
|
|
|
846
941
|
expect(result.subaccount).toMatch(/^0x[0-9a-f]{64}$/);
|
|
847
942
|
});
|
|
848
943
|
});
|
|
944
|
+
|
|
945
|
+
describe('[mobile-client]: position feed changes', () => {
|
|
946
|
+
it('keeps an unnamed owner even when no timeline content is available', () => {
|
|
947
|
+
const mapped = mapMobileSocialFeedPositionHistory({
|
|
948
|
+
...history,
|
|
949
|
+
owner: {
|
|
950
|
+
...post.author,
|
|
951
|
+
username: null,
|
|
952
|
+
display_name: null,
|
|
953
|
+
avatar_url: null,
|
|
954
|
+
is_following: null,
|
|
955
|
+
},
|
|
956
|
+
timeline: [],
|
|
957
|
+
summary: { action_count: 0, take_count: 0 },
|
|
958
|
+
});
|
|
959
|
+
expect(mapped.owner).toEqual({
|
|
960
|
+
subaccount: post.author.subaccount,
|
|
961
|
+
username: null,
|
|
962
|
+
displayName: null,
|
|
963
|
+
avatarUrl: null,
|
|
964
|
+
isFollowing: null,
|
|
965
|
+
traderBadge: null,
|
|
966
|
+
traderDataStatus: 'unavailable',
|
|
967
|
+
});
|
|
968
|
+
expect(mapped.timeline).toEqual([]);
|
|
969
|
+
expect(mapped.summary).toEqual({ actionCount: 0, takeCount: 0 });
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
it('maps recent actions without manufacturing related takes or complete-history counts', () => {
|
|
973
|
+
const entry = history.timeline[0];
|
|
974
|
+
if (entry.kind !== 'action') throw new Error('Expected action fixture');
|
|
975
|
+
const mapped = mapMobileSocialFeedPositionHistory({
|
|
976
|
+
...history,
|
|
977
|
+
timeline: [{ ...entry, related_take: null }],
|
|
978
|
+
next_cursor: null,
|
|
979
|
+
summary: { action_count: 1, take_count: 0 },
|
|
980
|
+
});
|
|
981
|
+
expect(mapped.timeline[0].kind).toBe('action');
|
|
982
|
+
if (mapped.timeline[0].kind !== 'action') {
|
|
983
|
+
throw new Error('Expected mapped action');
|
|
984
|
+
}
|
|
985
|
+
expect(mapped.timeline[0].relatedTake).toBeNull();
|
|
986
|
+
expect(mapped.timeline[0].relatedItemId).toBe(entry.related_item_id);
|
|
987
|
+
expect(mapped.timeline[0].action.executedQuantity.toFixed()).toBe(
|
|
988
|
+
entry.action.executed_quantity_x18,
|
|
989
|
+
);
|
|
990
|
+
expect(mapped.owner.subaccount).toBe(post.author.subaccount);
|
|
991
|
+
expect(mapped.summary).toEqual({ actionCount: 1, takeCount: 0 });
|
|
992
|
+
expect(mapped.nextCursor).toBeNull();
|
|
993
|
+
});
|
|
994
|
+
|
|
995
|
+
function thoughtsPage(): MobileServerSocialFeedPositionThoughtsResponse {
|
|
996
|
+
return {
|
|
997
|
+
items: [
|
|
998
|
+
{
|
|
999
|
+
...post,
|
|
1000
|
+
has_analysis: true,
|
|
1001
|
+
drawing: { data: false, created_at_ms: 20, updated_at_ms: 40 },
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
...post,
|
|
1005
|
+
id: '77777777-7777-4777-8777-777777777777',
|
|
1006
|
+
kind: 'trade_card',
|
|
1007
|
+
action: 'opened',
|
|
1008
|
+
display_at_ms: post.display_at_ms + 100,
|
|
1009
|
+
has_analysis: true,
|
|
1010
|
+
drawing: {
|
|
1011
|
+
data: { lines: [] },
|
|
1012
|
+
created_at_ms: 10,
|
|
1013
|
+
updated_at_ms: 50,
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
1016
|
+
],
|
|
1017
|
+
next_cursor: 'Continue',
|
|
1018
|
+
read_session: { ...history.read_session, mode: 'position' },
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
it('preserves thoughts order and complete parsed drawings independently of display/update time', () => {
|
|
1023
|
+
const server = thoughtsPage();
|
|
1024
|
+
const mapped = mapMobileSocialFeedPositionThoughts(server);
|
|
1025
|
+
expect(mapped.items.map((item) => item.id)).toEqual(
|
|
1026
|
+
server.items.map((item) => item.id),
|
|
1027
|
+
);
|
|
1028
|
+
expect(mapped.items[0].drawing).toEqual({
|
|
1029
|
+
data: false,
|
|
1030
|
+
createdAtMs: 20,
|
|
1031
|
+
updatedAtMs: 40,
|
|
1032
|
+
});
|
|
1033
|
+
expect(mapped.items[1].drawing.data).toEqual({ lines: [] });
|
|
1034
|
+
expect(mapped.items[1].kind).toBe('trade_card');
|
|
1035
|
+
expect(mapped.items[1].position.quantity.toFixed()).toBe(
|
|
1036
|
+
post.position.quantity_x18,
|
|
1037
|
+
);
|
|
1038
|
+
expect(mapped.nextCursor).toBe('Continue');
|
|
1039
|
+
expect(mapped.readSession.mode).toBe('position');
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
it.each([null, 'Continue'])(
|
|
1043
|
+
'preserves empty thought pages with cursor %s',
|
|
1044
|
+
(cursor) => {
|
|
1045
|
+
const mapped = mapMobileSocialFeedPositionThoughts({
|
|
1046
|
+
...thoughtsPage(),
|
|
1047
|
+
items: [],
|
|
1048
|
+
next_cursor: cursor,
|
|
1049
|
+
});
|
|
1050
|
+
expect(mapped.items).toEqual([]);
|
|
1051
|
+
expect(mapped.nextCursor).toBe(cursor);
|
|
1052
|
+
},
|
|
1053
|
+
);
|
|
1054
|
+
|
|
1055
|
+
it('maps mixed uploaded/external images in posts and replies without inventing metadata', () => {
|
|
1056
|
+
const images = [
|
|
1057
|
+
{
|
|
1058
|
+
image_id: '66666666-6666-4666-8666-666666666666',
|
|
1059
|
+
url: '/v1/mobile/feed/images/test/standard',
|
|
1060
|
+
width: 1024,
|
|
1061
|
+
height: 512,
|
|
1062
|
+
content_type: 'image/png' as const,
|
|
1063
|
+
byte_size: 100,
|
|
1064
|
+
thumbnail: {
|
|
1065
|
+
url: '/v1/mobile/feed/images/test/thumbnail',
|
|
1066
|
+
width: 512,
|
|
1067
|
+
height: 256,
|
|
1068
|
+
},
|
|
1069
|
+
},
|
|
1070
|
+
{ url: 'https://example.com/first.png' },
|
|
1071
|
+
{ url: 'https://example.com/second.png' },
|
|
1072
|
+
];
|
|
1073
|
+
for (const item of [post, reply]) {
|
|
1074
|
+
const mapped = mapMobileSocialFeedItem({ ...item, images });
|
|
1075
|
+
if (mapped.kind === 'trade_row')
|
|
1076
|
+
throw new Error('Expected authored content');
|
|
1077
|
+
expect(mapped.images[0]).toMatchObject({
|
|
1078
|
+
imageId: images[0].image_id,
|
|
1079
|
+
thumbnail: { width: 512 },
|
|
1080
|
+
});
|
|
1081
|
+
expect(mapped.images.slice(1)).toEqual(images.slice(1));
|
|
1082
|
+
expect(
|
|
1083
|
+
mapped.images
|
|
1084
|
+
.filter(isMobileSocialFeedUploadedImage)
|
|
1085
|
+
.map((image) => image.imageId),
|
|
1086
|
+
).toEqual([images[0].image_id]);
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
describe('[mobile-client]: position and image transport', () => {
|
|
1092
|
+
function clientWithResponse(data: Record<string, unknown>) {
|
|
1093
|
+
const client = new MobileClient({
|
|
1094
|
+
url: 'https://mobile.example/v1/mobile',
|
|
1095
|
+
});
|
|
1096
|
+
const requests: Record<string, unknown>[] = [];
|
|
1097
|
+
client.axiosInstance.defaults.adapter = (config) => {
|
|
1098
|
+
requests.push(JSON.parse(String(config.data)) as Record<string, unknown>);
|
|
1099
|
+
expect(config.url).toBe(
|
|
1100
|
+
`https://mobile.example/v1/mobile/${client.opts.walletClient ? 'execute' : 'public_query'}`,
|
|
1101
|
+
);
|
|
1102
|
+
return Promise.resolve({
|
|
1103
|
+
data: { status: 'success', ...data },
|
|
1104
|
+
status: 200,
|
|
1105
|
+
statusText: 'OK',
|
|
1106
|
+
headers: {},
|
|
1107
|
+
config,
|
|
1108
|
+
});
|
|
1109
|
+
};
|
|
1110
|
+
return { client, requests };
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
it('routes thoughts publicly, preserving continuation credentials after an empty page', async () => {
|
|
1114
|
+
const { client, requests } = clientWithResponse({
|
|
1115
|
+
items: [],
|
|
1116
|
+
next_cursor: 'Next',
|
|
1117
|
+
read_session: history.read_session,
|
|
1118
|
+
});
|
|
1119
|
+
const first = await client.getPositionThoughts({
|
|
1120
|
+
positionId: post.position.position_id,
|
|
1121
|
+
limit: 2,
|
|
1122
|
+
});
|
|
1123
|
+
await client.getPositionThoughts({
|
|
1124
|
+
positionId: post.position.position_id,
|
|
1125
|
+
limit: 2,
|
|
1126
|
+
sessionId: first.readSession.sessionId,
|
|
1127
|
+
viewerToken: first.readSession.viewerToken,
|
|
1128
|
+
cursor: first.nextCursor ?? undefined,
|
|
1129
|
+
});
|
|
1130
|
+
expect(requests).toEqual([
|
|
1131
|
+
{
|
|
1132
|
+
type: 'position_thoughts',
|
|
1133
|
+
position_id: post.position.position_id,
|
|
1134
|
+
limit: 2,
|
|
1135
|
+
},
|
|
1136
|
+
{
|
|
1137
|
+
type: 'position_thoughts',
|
|
1138
|
+
position_id: post.position.position_id,
|
|
1139
|
+
limit: 2,
|
|
1140
|
+
session_id: history.read_session.session_id,
|
|
1141
|
+
viewer_token: history.read_session.viewer_token,
|
|
1142
|
+
cursor: 'Next',
|
|
1143
|
+
},
|
|
1144
|
+
]);
|
|
1145
|
+
});
|
|
1146
|
+
|
|
1147
|
+
it('reads grouped comments through the public API and preserves paging credentials', async () => {
|
|
1148
|
+
const { client, requests } = clientWithResponse({
|
|
1149
|
+
comments: [{ ...reply, replies: [] }],
|
|
1150
|
+
total_count: 12,
|
|
1151
|
+
top_level_count: 5,
|
|
1152
|
+
next_cursor: 'NextGroup',
|
|
1153
|
+
previous_cursor: null,
|
|
1154
|
+
anchor_reply_id: null,
|
|
1155
|
+
read_session: history.read_session,
|
|
1156
|
+
});
|
|
1157
|
+
const page = await client.getFeedComments({
|
|
1158
|
+
rootItemId: post.id,
|
|
1159
|
+
limit: 1,
|
|
1160
|
+
});
|
|
1161
|
+
expect(page.comments[0].replies).toEqual([]);
|
|
1162
|
+
expect(page).toMatchObject({ totalCount: 12, topLevelCount: 5 });
|
|
1163
|
+
await client.getFeedComments({
|
|
1164
|
+
rootItemId: post.id,
|
|
1165
|
+
limit: 1,
|
|
1166
|
+
cursor: page.nextCursor ?? undefined,
|
|
1167
|
+
sessionId: page.readSession.sessionId,
|
|
1168
|
+
viewerToken: page.readSession.viewerToken,
|
|
1169
|
+
});
|
|
1170
|
+
expect(requests).toEqual([
|
|
1171
|
+
{ type: 'feed_comments', root_item_id: post.id, limit: 1 },
|
|
1172
|
+
{
|
|
1173
|
+
type: 'feed_comments',
|
|
1174
|
+
root_item_id: post.id,
|
|
1175
|
+
limit: 1,
|
|
1176
|
+
cursor: 'NextGroup',
|
|
1177
|
+
session_id: history.read_session.session_id,
|
|
1178
|
+
viewer_token: history.read_session.viewer_token,
|
|
1179
|
+
},
|
|
1180
|
+
]);
|
|
1181
|
+
});
|
|
1182
|
+
|
|
1183
|
+
it('routes recent actions publicly without pagination fields and maps the owner', async () => {
|
|
1184
|
+
const { client, requests } = clientWithResponse({
|
|
1185
|
+
...history,
|
|
1186
|
+
timeline: [],
|
|
1187
|
+
summary: { action_count: 0, take_count: 0 },
|
|
1188
|
+
next_cursor: null,
|
|
1189
|
+
});
|
|
1190
|
+
const result = await client.getPositionHistoryAll({
|
|
1191
|
+
positionId: post.position.position_id,
|
|
1192
|
+
viewerToken: 'ExistingViewer',
|
|
1193
|
+
});
|
|
1194
|
+
expect(requests).toEqual([
|
|
1195
|
+
{
|
|
1196
|
+
type: 'position_history_all',
|
|
1197
|
+
position_id: post.position.position_id,
|
|
1198
|
+
viewer_token: 'ExistingViewer',
|
|
1199
|
+
},
|
|
1200
|
+
]);
|
|
1201
|
+
expect(result.owner.subaccount).toBe(post.author.subaccount);
|
|
1202
|
+
expect(result.timeline).toEqual([]);
|
|
1203
|
+
});
|
|
1204
|
+
|
|
1205
|
+
it.each(['post', 'comment'] as const)(
|
|
1206
|
+
'passes image URL arrays through signed %s publication',
|
|
1207
|
+
async (kind) => {
|
|
1208
|
+
const { client, requests } = clientWithResponse(
|
|
1209
|
+
kind === 'post'
|
|
1210
|
+
? { item: post }
|
|
1211
|
+
: { comment: reply, root_comment_count: 1 },
|
|
1212
|
+
);
|
|
1213
|
+
const account = privateKeyToAccount(
|
|
1214
|
+
'0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b786907',
|
|
1215
|
+
);
|
|
1216
|
+
client.opts.walletClient = createWalletClient({
|
|
1217
|
+
account,
|
|
1218
|
+
chain: ink,
|
|
1219
|
+
transport: http(),
|
|
1220
|
+
});
|
|
1221
|
+
const params = {
|
|
1222
|
+
subaccountOwner: account.address,
|
|
1223
|
+
subaccountName: 'default',
|
|
1224
|
+
chainId: ink.id,
|
|
1225
|
+
verifyingAddr: '0x0000000000000000000000000000000000000001' as const,
|
|
1226
|
+
clientRequestId: '11111111-1111-4111-8111-111111111111',
|
|
1227
|
+
text: 'external images',
|
|
1228
|
+
mentions: [],
|
|
1229
|
+
imageIds: [],
|
|
1230
|
+
imageUrls: ['https://example.com/A.png', 'https://example.com/B.png'],
|
|
1231
|
+
};
|
|
1232
|
+
if (kind === 'post')
|
|
1233
|
+
await client.createFeedPost({
|
|
1234
|
+
...params,
|
|
1235
|
+
positionId: post.position.position_id,
|
|
1236
|
+
});
|
|
1237
|
+
else await client.createFeedComment({ ...params, rootItemId: post.id });
|
|
1238
|
+
expect(requests[0]).toMatchObject({
|
|
1239
|
+
type: `create_feed_${kind}`,
|
|
1240
|
+
image_ids: [],
|
|
1241
|
+
image_urls: params.imageUrls,
|
|
1242
|
+
signature: expect.stringMatching(/^0x[0-9a-f]+$/),
|
|
1243
|
+
});
|
|
1244
|
+
expect(requests[0]).not.toHaveProperty('image_url');
|
|
1245
|
+
},
|
|
1246
|
+
);
|
|
1247
|
+
});
|
package/src/dataMappers.ts
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
MobileSocialFeedActionResolutionResult,
|
|
33
33
|
MobileSocialFeedAuthor,
|
|
34
34
|
MobileSocialFeedCandle,
|
|
35
|
+
MobileSocialFeedCommentGroup,
|
|
35
36
|
MobileSocialFeedCommentResult,
|
|
36
37
|
MobileSocialFeedCommentsPage,
|
|
37
38
|
MobileSocialFeedCompactCard,
|
|
@@ -59,6 +60,8 @@ import {
|
|
|
59
60
|
MobileSocialFeedPositionHistory,
|
|
60
61
|
MobileSocialFeedPositionPatch,
|
|
61
62
|
MobileSocialFeedPositionResolutionResult,
|
|
63
|
+
MobileSocialFeedPositionThought,
|
|
64
|
+
MobileSocialFeedPositionThoughtsPage,
|
|
62
65
|
MobileSocialFeedPositionsPage,
|
|
63
66
|
MobileSocialFeedPost,
|
|
64
67
|
MobileSocialFeedPresence,
|
|
@@ -76,7 +79,7 @@ import {
|
|
|
76
79
|
MobileSocialFeedTradingContext,
|
|
77
80
|
MobileSocialFeedTradingTarget,
|
|
78
81
|
MobileSocialFeedUpdates,
|
|
79
|
-
|
|
82
|
+
MobileSocialFeedUploadedImage,
|
|
80
83
|
MobileSocialFeedWatchers,
|
|
81
84
|
SearchMobileProfilesParams,
|
|
82
85
|
} from './types/clientTypes';
|
|
@@ -90,7 +93,6 @@ import {
|
|
|
90
93
|
MobileServerSocialFeedDrawingMutationResponse,
|
|
91
94
|
MobileServerSocialFeedLikeResponse,
|
|
92
95
|
MobileServerSocialFeedPresenceResponse,
|
|
93
|
-
MobileServerSocialFeedViewsResponse,
|
|
94
96
|
} from './types/serverExecuteTypes';
|
|
95
97
|
import {
|
|
96
98
|
MobileServerAvatarPreset,
|
|
@@ -109,6 +111,7 @@ import {
|
|
|
109
111
|
MobileServerSocialFeedActionMarker,
|
|
110
112
|
MobileServerSocialFeedAuthor,
|
|
111
113
|
MobileServerSocialFeedCandle,
|
|
114
|
+
MobileServerSocialFeedCommentGroup,
|
|
112
115
|
MobileServerSocialFeedCompactCard,
|
|
113
116
|
MobileServerSocialFeedContentBase,
|
|
114
117
|
MobileServerSocialFeedDrawing,
|
|
@@ -135,6 +138,7 @@ import {
|
|
|
135
138
|
MobileServerSocialFeedTraderBadge,
|
|
136
139
|
MobileServerSocialFeedTradingContext,
|
|
137
140
|
MobileServerSocialFeedTradingTarget,
|
|
141
|
+
MobileServerSocialFeedUploadedImage,
|
|
138
142
|
MobileSocialFeedMention,
|
|
139
143
|
} from './types/serverModelTypes';
|
|
140
144
|
import {
|
|
@@ -153,6 +157,8 @@ import {
|
|
|
153
157
|
MobileServerSocialFeedPositionChartResponse,
|
|
154
158
|
MobileServerSocialFeedPositionHistoryResponse,
|
|
155
159
|
MobileServerSocialFeedPositionResolutionResponse,
|
|
160
|
+
MobileServerSocialFeedPositionThought,
|
|
161
|
+
MobileServerSocialFeedPositionThoughtsResponse,
|
|
156
162
|
MobileServerSocialFeedPositionsResponse,
|
|
157
163
|
MobileServerSocialFeedRankedResponse,
|
|
158
164
|
MobileServerSocialFeedResponse,
|
|
@@ -799,9 +805,9 @@ export function mapMobileSocialFeedInteraction(
|
|
|
799
805
|
* @param server - The service response.
|
|
800
806
|
* @returns The mapped feed image.
|
|
801
807
|
*/
|
|
802
|
-
export function
|
|
803
|
-
server:
|
|
804
|
-
):
|
|
808
|
+
export function mapMobileSocialFeedUploadedImage(
|
|
809
|
+
server: MobileServerSocialFeedUploadedImage,
|
|
810
|
+
): MobileSocialFeedUploadedImage {
|
|
805
811
|
return {
|
|
806
812
|
imageId: server.image_id,
|
|
807
813
|
url: server.url,
|
|
@@ -817,6 +823,20 @@ export function mapMobileSocialFeedImage(
|
|
|
817
823
|
};
|
|
818
824
|
}
|
|
819
825
|
|
|
826
|
+
/**
|
|
827
|
+
* Maps either protected upload metadata or an external URL without inventing metadata.
|
|
828
|
+
* @param server - The service response.
|
|
829
|
+
* @returns The mapped uploaded image or external URL.
|
|
830
|
+
*/
|
|
831
|
+
export function mapMobileSocialFeedImage(
|
|
832
|
+
server: MobileServerSocialFeedImage,
|
|
833
|
+
): MobileSocialFeedImage {
|
|
834
|
+
if ('image_id' in server) {
|
|
835
|
+
return mapMobileSocialFeedUploadedImage(server);
|
|
836
|
+
}
|
|
837
|
+
return { url: server.url };
|
|
838
|
+
}
|
|
839
|
+
|
|
820
840
|
/**
|
|
821
841
|
* Maps common item metadata and server capabilities.
|
|
822
842
|
* @param server - The service response.
|
|
@@ -976,7 +996,6 @@ export function mapMobileSocialFeedReadSession(
|
|
|
976
996
|
sessionId: server.session_id,
|
|
977
997
|
mode: server.mode,
|
|
978
998
|
expiresAtMs: server.expires_at_ms,
|
|
979
|
-
viewTracking: { mode: server.view_tracking.mode },
|
|
980
999
|
updateCursor: server.update_cursor,
|
|
981
1000
|
viewerToken: server.viewer_token,
|
|
982
1001
|
};
|
|
@@ -1546,16 +1565,31 @@ export function mapMobileSocialFeedDrawingMutationResult(
|
|
|
1546
1565
|
}
|
|
1547
1566
|
|
|
1548
1567
|
/**
|
|
1549
|
-
* Maps
|
|
1568
|
+
* Maps a top-level comment and its complete flat descendants without sorting or dropping content.
|
|
1569
|
+
* @param server - A comment group from the service thread snapshot.
|
|
1570
|
+
* @returns The mapped top-level comment with each descendant's original parent relationship.
|
|
1571
|
+
*/
|
|
1572
|
+
export function mapMobileSocialFeedCommentGroup(
|
|
1573
|
+
server: MobileServerSocialFeedCommentGroup,
|
|
1574
|
+
): MobileSocialFeedCommentGroup {
|
|
1575
|
+
return {
|
|
1576
|
+
...mapMobileSocialFeedReply(server),
|
|
1577
|
+
replies: server.replies.map(mapMobileSocialFeedReply),
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
/**
|
|
1582
|
+
* Maps complete comment groups in server order and the actual returned session.
|
|
1550
1583
|
* @param server - Service payload with its original wire fields.
|
|
1551
|
-
* @returns Mapped
|
|
1584
|
+
* @returns Mapped groups, whole-thread counts, bidirectional cursors, nullable anchor, and reading session.
|
|
1552
1585
|
*/
|
|
1553
1586
|
export function mapMobileSocialFeedCommentsPage(
|
|
1554
1587
|
server: MobileServerSocialFeedCommentsResponse,
|
|
1555
1588
|
): MobileSocialFeedCommentsPage {
|
|
1556
1589
|
return {
|
|
1557
|
-
comments: server.comments.map(
|
|
1590
|
+
comments: server.comments.map(mapMobileSocialFeedCommentGroup),
|
|
1558
1591
|
totalCount: server.total_count,
|
|
1592
|
+
topLevelCount: server.top_level_count,
|
|
1559
1593
|
nextCursor: server.next_cursor,
|
|
1560
1594
|
previousCursor: server.previous_cursor,
|
|
1561
1595
|
anchorReplyId: server.anchor_reply_id,
|
|
@@ -1593,20 +1627,6 @@ export function mapMobileSocialFeedLikeResult(
|
|
|
1593
1627
|
};
|
|
1594
1628
|
}
|
|
1595
1629
|
|
|
1596
|
-
/**
|
|
1597
|
-
* Maps exposure deduplication results without adding timestamps.
|
|
1598
|
-
* @param server - Service payload with its original wire fields.
|
|
1599
|
-
* @returns Newly accepted and duplicate item ID lists without inventing an observation timestamp.
|
|
1600
|
-
*/
|
|
1601
|
-
export function mapMobileSocialFeedViewsResult(
|
|
1602
|
-
server: MobileServerSocialFeedViewsResponse,
|
|
1603
|
-
): MobileSocialFeedViewsResult {
|
|
1604
|
-
return {
|
|
1605
|
-
acceptedItemIds: server.accepted_item_ids,
|
|
1606
|
-
duplicateItemIds: server.duplicate_item_ids,
|
|
1607
|
-
};
|
|
1608
|
-
}
|
|
1609
|
-
|
|
1610
1630
|
/**
|
|
1611
1631
|
* Maps a published history take without treating unknown kinds as posts.
|
|
1612
1632
|
* @param server - The published service item.
|
|
@@ -1668,6 +1688,7 @@ export function mapMobileSocialFeedPositionHistory(
|
|
|
1668
1688
|
server: MobileServerSocialFeedPositionHistoryResponse,
|
|
1669
1689
|
): MobileSocialFeedPositionHistory {
|
|
1670
1690
|
return {
|
|
1691
|
+
owner: mapMobileSocialFeedAuthor(server.owner),
|
|
1671
1692
|
position: {
|
|
1672
1693
|
...mapMobileSocialFeedPositionCard(server.position),
|
|
1673
1694
|
...mapMobileSocialFeedHistoryMetrics(server.position),
|
|
@@ -1738,3 +1759,35 @@ export function mapMobileSocialFeedPresence(
|
|
|
1738
1759
|
expiresInSeconds: server.expires_in_seconds,
|
|
1739
1760
|
};
|
|
1740
1761
|
}
|
|
1762
|
+
|
|
1763
|
+
/**
|
|
1764
|
+
* Maps a published thought, keeping its guaranteed analysis flag and drawing.
|
|
1765
|
+
* @param server - Service payload with its original wire fields.
|
|
1766
|
+
* @returns The mapped post or trade card with a non-null drawing.
|
|
1767
|
+
* @throws {MobileUnsupportedFeedItemError} If the service returns an unsupported take kind.
|
|
1768
|
+
*/
|
|
1769
|
+
export function mapMobileSocialFeedPositionThought(
|
|
1770
|
+
server: MobileServerSocialFeedPositionThought,
|
|
1771
|
+
): MobileSocialFeedPositionThought {
|
|
1772
|
+
return {
|
|
1773
|
+
...mapMobileSocialFeedHistoryTake(server),
|
|
1774
|
+
hasAnalysis: server.has_analysis,
|
|
1775
|
+
drawing: mapMobileSocialFeedDrawing(server.drawing),
|
|
1776
|
+
};
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
/**
|
|
1780
|
+
* Maps a thoughts page in server order, preserving empty pages with continuation cursors.
|
|
1781
|
+
* @param server - Service payload with its original wire fields.
|
|
1782
|
+
* @returns Thoughts, the next cursor, and the position reading session.
|
|
1783
|
+
* @throws {MobileUnsupportedFeedItemError} If an item is not a post or trade card.
|
|
1784
|
+
*/
|
|
1785
|
+
export function mapMobileSocialFeedPositionThoughts(
|
|
1786
|
+
server: MobileServerSocialFeedPositionThoughtsResponse,
|
|
1787
|
+
): MobileSocialFeedPositionThoughtsPage {
|
|
1788
|
+
return {
|
|
1789
|
+
items: server.items.map(mapMobileSocialFeedPositionThought),
|
|
1790
|
+
nextCursor: server.next_cursor,
|
|
1791
|
+
readSession: mapMobileSocialFeedReadSession(server.read_session),
|
|
1792
|
+
};
|
|
1793
|
+
}
|