@layers/amba-react-native 3.0.2 → 4.0.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/dist/index.cjs +258 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +460 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +460 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +258 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
//#region src/async-storage-adapter.ts
|
|
2
|
-
let cachedStorage =
|
|
2
|
+
let cachedStorage = void 0;
|
|
3
|
+
/**
|
|
4
|
+
* Late-imports `@react-native-async-storage/async-storage` and returns
|
|
5
|
+
* it ONLY if the resolved module exposes the three methods we use
|
|
6
|
+
* (`getItem` / `setItem` / `removeItem`). Otherwise returns null and
|
|
7
|
+
* the persistence layer falls back to memory-only.
|
|
8
|
+
*
|
|
9
|
+
* Why the shape check: pnpm with auto-install-peers (default since
|
|
10
|
+
* pnpm 7) installs declared peer deps even in non-RN scratch
|
|
11
|
+
* directories (e.g., this SDK's docs-smoke harness). The installed
|
|
12
|
+
* package's Node entry point doesn't expose AsyncStorage's methods
|
|
13
|
+
* — it's a React Native native module — so the `await import(...)`
|
|
14
|
+
* succeeds (no catch fires) but the returned object has no
|
|
15
|
+
* `getItem`. Calling it throws `TypeError: storage.getItem is not a
|
|
16
|
+
* function` from inside `read()` (verified at PR #246 docs-react-native
|
|
17
|
+
* / docs-expo run on 547a1ff4). Checking method presence here turns
|
|
18
|
+
* that into the same fall-through as "peer dep not installed at all."
|
|
19
|
+
*/
|
|
20
|
+
function isAsyncStorageLike(mod) {
|
|
21
|
+
return typeof mod === "object" && mod !== null && typeof mod.getItem === "function" && typeof mod.setItem === "function" && typeof mod.removeItem === "function";
|
|
22
|
+
}
|
|
3
23
|
async function getStorage() {
|
|
4
|
-
if (cachedStorage !==
|
|
24
|
+
if (cachedStorage !== void 0) return cachedStorage;
|
|
5
25
|
try {
|
|
6
26
|
const mod = await import("@react-native-async-storage/async-storage");
|
|
7
|
-
|
|
27
|
+
const candidate = mod.default ?? mod;
|
|
28
|
+
if (!isAsyncStorageLike(candidate)) {
|
|
29
|
+
cachedStorage = null;
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
cachedStorage = candidate;
|
|
8
33
|
return cachedStorage;
|
|
9
34
|
} catch {
|
|
35
|
+
cachedStorage = null;
|
|
10
36
|
return null;
|
|
11
37
|
}
|
|
12
38
|
}
|
|
@@ -324,7 +350,7 @@ function freshSeed() {
|
|
|
324
350
|
//#endregion
|
|
325
351
|
//#region src/index.ts
|
|
326
352
|
/** SDK semver — burned in at build time. Bump alongside package.json. */
|
|
327
|
-
const SDK_VERSION = "
|
|
353
|
+
const SDK_VERSION = "4.0.0";
|
|
328
354
|
let state = null;
|
|
329
355
|
function getState() {
|
|
330
356
|
if (!state) throw new AmbaApiError("NOT_INITIALIZED", "@layers/amba-react-native: SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start.");
|
|
@@ -376,15 +402,34 @@ function requireEmail(email) {
|
|
|
376
402
|
function requirePassword(password) {
|
|
377
403
|
if (password.length < 8) throw new AmbaApiError("VALIDATION_ERROR", "password must be at least 8 characters");
|
|
378
404
|
}
|
|
405
|
+
function requireOtpCode(code) {
|
|
406
|
+
if (code.length !== 6 || !/^[0-9]{6}$/.test(code)) throw new AmbaApiError("VALIDATION_ERROR", "code must be 6 digits");
|
|
407
|
+
}
|
|
408
|
+
const E164_RE = /^\+[1-9][0-9]{6,14}$/;
|
|
409
|
+
function requireE164Phone(phone) {
|
|
410
|
+
if (!E164_RE.test(phone)) throw new AmbaApiError("VALIDATION_ERROR", "phone must be E.164 (starts with +, 8–15 digits)");
|
|
411
|
+
}
|
|
379
412
|
const P = {
|
|
380
413
|
authAnonymous: "/v1/client/auth/anonymous",
|
|
381
414
|
authEmailLogin: "/v1/client/auth/email/login",
|
|
382
415
|
authEmailSignup: "/v1/client/auth/email/signup",
|
|
416
|
+
authEmailOtpRequest: "/v1/client/auth/email-otp/request",
|
|
417
|
+
authSmsOtpRequest: "/v1/client/auth/sms-otp/request",
|
|
418
|
+
authSmsOtpVerify: "/v1/client/auth/sms-otp/verify",
|
|
419
|
+
authEmailOtpVerify: "/v1/client/auth/email-otp/verify",
|
|
383
420
|
authSocial: "/v1/client/auth/social",
|
|
421
|
+
authMagicLinkRequest: "/v1/client/auth/magic-link/request",
|
|
422
|
+
authMagicLinkVerify: "/v1/client/auth/magic-link/verify",
|
|
423
|
+
authLink: "/v1/client/auth/link",
|
|
384
424
|
authRefresh: "/v1/client/auth/refresh",
|
|
385
425
|
authLogout: "/v1/client/auth/logout",
|
|
386
426
|
authMe: "/v1/client/auth/me",
|
|
387
427
|
events: "/v1/client/events",
|
|
428
|
+
users: "/v1/client/users",
|
|
429
|
+
usersMe: "/v1/client/users/me",
|
|
430
|
+
sessions: "/v1/client/sessions",
|
|
431
|
+
sync: "/v1/client/sync",
|
|
432
|
+
leagues: "/v1/client/leagues",
|
|
388
433
|
collections: "/v1/client/collections",
|
|
389
434
|
storage: "/v1/client/media",
|
|
390
435
|
storagePresign: "/v1/client/media/presign",
|
|
@@ -399,6 +444,7 @@ const P = {
|
|
|
399
444
|
aiAnthropic: "/v1/client/ai/anthropic/messages",
|
|
400
445
|
config: "/v1/client/config",
|
|
401
446
|
flags: "/v1/client/flags",
|
|
447
|
+
diagnosticsPing: "/v1/client/diagnostics/ping",
|
|
402
448
|
achievements: "/v1/client/achievements",
|
|
403
449
|
challenges: "/v1/client/challenges",
|
|
404
450
|
catalog: "/v1/client/catalog",
|
|
@@ -417,7 +463,7 @@ const P = {
|
|
|
417
463
|
roles: "/v1/client/roles",
|
|
418
464
|
referrals: "/v1/client/referrals",
|
|
419
465
|
content: "/v1/client/content",
|
|
420
|
-
deepLinks: "/v1/client/
|
|
466
|
+
deepLinks: "/v1/client/deep-links",
|
|
421
467
|
onboarding: "/v1/client/onboarding"
|
|
422
468
|
};
|
|
423
469
|
function encodePathSegment(s) {
|
|
@@ -467,14 +513,16 @@ const Amba = {
|
|
|
467
513
|
setDebug: (enabled) => {
|
|
468
514
|
getState().debug = enabled;
|
|
469
515
|
},
|
|
470
|
-
events: { track: async (event, properties) => {
|
|
516
|
+
events: { track: async (event, properties, options) => {
|
|
471
517
|
const s = getState();
|
|
472
|
-
|
|
473
|
-
|
|
518
|
+
const body = {
|
|
519
|
+
event,
|
|
474
520
|
properties: properties ?? void 0,
|
|
475
521
|
anonymous_id: s.identity.getAnonymousId(),
|
|
476
522
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
477
|
-
}
|
|
523
|
+
};
|
|
524
|
+
if (options?.telemetry) body["telemetry"] = true;
|
|
525
|
+
await s.http.post(P.events, body);
|
|
478
526
|
} },
|
|
479
527
|
auth: {
|
|
480
528
|
signInAnonymously: async () => {
|
|
@@ -497,13 +545,65 @@ const Amba = {
|
|
|
497
545
|
password
|
|
498
546
|
});
|
|
499
547
|
},
|
|
500
|
-
|
|
548
|
+
signInWithApple: async (identityToken) => {
|
|
549
|
+
if (identityToken.trim() === "") throw new AmbaApiError("VALIDATION_ERROR", "identity_token must not be empty");
|
|
550
|
+
return postAuth(getState(), P.authSocial, {
|
|
551
|
+
provider: "apple",
|
|
552
|
+
id_token: identityToken
|
|
553
|
+
});
|
|
554
|
+
},
|
|
555
|
+
signInWithGoogle: async (idToken) => {
|
|
501
556
|
if (idToken.trim() === "") throw new AmbaApiError("VALIDATION_ERROR", "id_token must not be empty");
|
|
502
557
|
return postAuth(getState(), P.authSocial, {
|
|
503
|
-
provider,
|
|
558
|
+
provider: "google",
|
|
504
559
|
id_token: idToken
|
|
505
560
|
});
|
|
506
561
|
},
|
|
562
|
+
requestEmailOtp: async (email) => {
|
|
563
|
+
requireEmail(email);
|
|
564
|
+
await getState().http.post(P.authEmailOtpRequest, { email });
|
|
565
|
+
},
|
|
566
|
+
verifyEmailOtp: async (email, code) => {
|
|
567
|
+
requireEmail(email);
|
|
568
|
+
requireOtpCode(code);
|
|
569
|
+
return postAuth(getState(), P.authEmailOtpVerify, {
|
|
570
|
+
email,
|
|
571
|
+
code
|
|
572
|
+
});
|
|
573
|
+
},
|
|
574
|
+
requestSmsOtp: async (phone) => {
|
|
575
|
+
requireE164Phone(phone);
|
|
576
|
+
await getState().http.post(P.authSmsOtpRequest, { phone });
|
|
577
|
+
},
|
|
578
|
+
verifySmsOtp: async (phone, code) => {
|
|
579
|
+
requireE164Phone(phone);
|
|
580
|
+
requireOtpCode(code);
|
|
581
|
+
return postAuth(getState(), P.authSmsOtpVerify, {
|
|
582
|
+
phone,
|
|
583
|
+
code
|
|
584
|
+
});
|
|
585
|
+
},
|
|
586
|
+
requestMagicLink: async (email) => {
|
|
587
|
+
requireEmail(email);
|
|
588
|
+
await getState().http.post(P.authMagicLinkRequest, { email });
|
|
589
|
+
},
|
|
590
|
+
verifyMagicLink: async (token) => {
|
|
591
|
+
if (token.trim() === "") throw new AmbaApiError("VALIDATION_ERROR", "token must not be empty");
|
|
592
|
+
return postAuth(getState(), P.authMagicLinkVerify, { token });
|
|
593
|
+
},
|
|
594
|
+
linkAccount: async (provider, credential) => {
|
|
595
|
+
const providerTrimmed = provider?.trim() ?? "";
|
|
596
|
+
if (providerTrimmed === "") throw new AmbaApiError("VALIDATION_ERROR", "provider must not be empty");
|
|
597
|
+
if (typeof credential !== "string" || credential.trim() === "") throw new AmbaApiError("VALIDATION_ERROR", "credential must not be empty");
|
|
598
|
+
const s = getState();
|
|
599
|
+
const sessionToken = s.identity.getSessionToken();
|
|
600
|
+
if (!sessionToken) throw new AmbaApiError("UNAUTHORIZED", "no active session — call signIn* first");
|
|
601
|
+
return postAuth(s, P.authLink, {
|
|
602
|
+
provider: providerTrimmed,
|
|
603
|
+
token: credential,
|
|
604
|
+
session_token: sessionToken
|
|
605
|
+
});
|
|
606
|
+
},
|
|
507
607
|
signOut: async (rotateAnonymousId = false) => {
|
|
508
608
|
const s = getState();
|
|
509
609
|
if (s.identity.getSessionToken()) try {
|
|
@@ -540,6 +640,41 @@ const Amba = {
|
|
|
540
640
|
};
|
|
541
641
|
}
|
|
542
642
|
},
|
|
643
|
+
users: {
|
|
644
|
+
get: async (userId) => {
|
|
645
|
+
const s = getState();
|
|
646
|
+
if (!s.identity.getSessionToken()) throw new AmbaApiError("UNAUTHORIZED", "no active session — call signIn* first");
|
|
647
|
+
const path = userId === void 0 || userId === null || userId === "" ? P.usersMe : `${P.users}/${encodePathSegment(userId)}`;
|
|
648
|
+
return (await s.http.get(path)).data;
|
|
649
|
+
},
|
|
650
|
+
update: ((arg1, arg2) => {
|
|
651
|
+
const s = getState();
|
|
652
|
+
if (!s.identity.getSessionToken()) throw new AmbaApiError("UNAUTHORIZED", "no active session — call signIn* first");
|
|
653
|
+
const isById = typeof arg1 === "string";
|
|
654
|
+
const patch = isById ? arg2 ?? {} : arg1;
|
|
655
|
+
const path = isById ? `${P.users}/${encodePathSegment(arg1)}` : `${P.users}/me`;
|
|
656
|
+
return s.http.patch(path, patch).then((env) => env.data);
|
|
657
|
+
})
|
|
658
|
+
},
|
|
659
|
+
sessions: {
|
|
660
|
+
list: async () => {
|
|
661
|
+
return (await getState().http.get(P.sessions)).data;
|
|
662
|
+
},
|
|
663
|
+
revoke: async (sessionId) => {
|
|
664
|
+
await getState().http.post(`${P.sessions}/${encodePathSegment(sessionId)}/end`, {});
|
|
665
|
+
}
|
|
666
|
+
},
|
|
667
|
+
sync: {
|
|
668
|
+
pushChanges: async (changes) => {
|
|
669
|
+
return (await getState().http.post(P.sync, { changes })).data;
|
|
670
|
+
},
|
|
671
|
+
pullChanges: async (since) => {
|
|
672
|
+
if (!since.entity_type || since.entity_type.trim() === "") throw new AmbaApiError("VALIDATION_ERROR", "pullChanges requires a non-empty entity_type");
|
|
673
|
+
const query = { entity_type: since.entity_type };
|
|
674
|
+
if (since.checkpoint_token !== void 0) query["checkpoint_token"] = since.checkpoint_token;
|
|
675
|
+
return (await getState().http.get(P.sync, query)).data;
|
|
676
|
+
}
|
|
677
|
+
},
|
|
543
678
|
collections: {
|
|
544
679
|
find: async (name, options = {}) => {
|
|
545
680
|
return getState().http.post(`${P.collections}/${encodePathSegment(name)}/find`, options);
|
|
@@ -547,6 +682,20 @@ const Amba = {
|
|
|
547
682
|
findOne: async (name, id) => {
|
|
548
683
|
return (await getState().http.get(`${P.collections}/${encodePathSegment(name)}/${encodePathSegment(id)}`)).data;
|
|
549
684
|
},
|
|
685
|
+
findNearest: async (name, vector, k, where) => {
|
|
686
|
+
const s = getState();
|
|
687
|
+
const body = {
|
|
688
|
+
to_vector: vector,
|
|
689
|
+
k
|
|
690
|
+
};
|
|
691
|
+
if (where !== void 0) body.where = where;
|
|
692
|
+
return (await s.http.post(`${P.collections}/${encodePathSegment(name)}/find-nearest`, body)).data;
|
|
693
|
+
},
|
|
694
|
+
count: async (name, where) => {
|
|
695
|
+
const s = getState();
|
|
696
|
+
const query = where !== void 0 ? { query: JSON.stringify({ where }) } : void 0;
|
|
697
|
+
return (await s.http.get(`${P.collections}/${encodePathSegment(name)}/count`, query)).data.count;
|
|
698
|
+
},
|
|
550
699
|
insert: async (name, row) => {
|
|
551
700
|
return (await getState().http.post(`${P.collections}/${encodePathSegment(name)}`, row)).data;
|
|
552
701
|
},
|
|
@@ -635,6 +784,33 @@ const Amba = {
|
|
|
635
784
|
upload_id: uploadId,
|
|
636
785
|
asset_id: assetId
|
|
637
786
|
})).data;
|
|
787
|
+
},
|
|
788
|
+
list: async (prefix) => {
|
|
789
|
+
const env = await getState().http.get(P.storage, prefix !== void 0 ? { prefix } : void 0);
|
|
790
|
+
return {
|
|
791
|
+
data: env.data ?? [],
|
|
792
|
+
next_cursor: env.next_cursor ?? null
|
|
793
|
+
};
|
|
794
|
+
},
|
|
795
|
+
delete: async (assetId) => {
|
|
796
|
+
await getState().http.delete(`${P.storage}/${encodePathSegment(assetId)}`);
|
|
797
|
+
},
|
|
798
|
+
download: async (assetId) => {
|
|
799
|
+
const assetEnv = await getState().http.get(`${P.storage}/${encodePathSegment(assetId)}`);
|
|
800
|
+
const cdnUrl = assetEnv.data.url ?? assetEnv.data.storage_url ?? "";
|
|
801
|
+
if (!cdnUrl) throw new AmbaApiError("NOT_FOUND", "asset has no resolvable CDN url");
|
|
802
|
+
let response;
|
|
803
|
+
try {
|
|
804
|
+
response = await (globalThis.fetch ?? fetch)(cdnUrl, { method: "GET" });
|
|
805
|
+
} catch (err) {
|
|
806
|
+
throw new AmbaApiError("NETWORK_ERROR", `Network error: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
807
|
+
}
|
|
808
|
+
if (!response.ok) {
|
|
809
|
+
const text = await response.text();
|
|
810
|
+
const ct = response.headers.get("content-type") ?? "";
|
|
811
|
+
throw mapHttpError(response, text, ct.includes("application/json"));
|
|
812
|
+
}
|
|
813
|
+
return response.blob();
|
|
638
814
|
}
|
|
639
815
|
},
|
|
640
816
|
push: {
|
|
@@ -705,8 +881,21 @@ const Amba = {
|
|
|
705
881
|
values: parsed.data ?? {}
|
|
706
882
|
};
|
|
707
883
|
} },
|
|
708
|
-
flags: {
|
|
709
|
-
|
|
884
|
+
flags: {
|
|
885
|
+
fetch: async () => {
|
|
886
|
+
return (await getState().http.get(P.flags)).data;
|
|
887
|
+
},
|
|
888
|
+
get: async (key) => {
|
|
889
|
+
try {
|
|
890
|
+
return (await getState().http.get(`${P.flags}/${encodePathSegment(key)}`)).data;
|
|
891
|
+
} catch (err) {
|
|
892
|
+
if (err instanceof AmbaApiError && err.code === "NOT_FOUND") return null;
|
|
893
|
+
throw err;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
},
|
|
897
|
+
diagnostics: { ping: async () => {
|
|
898
|
+
return await getState().http.post(P.diagnosticsPing, {});
|
|
710
899
|
} },
|
|
711
900
|
achievements: {
|
|
712
901
|
getAll: async () => {
|
|
@@ -735,7 +924,7 @@ const Amba = {
|
|
|
735
924
|
return (await getState().http.get(P.currencies)).data;
|
|
736
925
|
},
|
|
737
926
|
getTransactions: async (currencyKey) => {
|
|
738
|
-
return (await getState().http.get(`${P.currencies}
|
|
927
|
+
return (await getState().http.get(`${P.currencies}/transactions`, { currency_code: currencyKey })).data;
|
|
739
928
|
}
|
|
740
929
|
},
|
|
741
930
|
inventory: {
|
|
@@ -749,7 +938,8 @@ const Amba = {
|
|
|
749
938
|
return (await getState().http.post(`${P.inventory}/purchase`, request)).data;
|
|
750
939
|
},
|
|
751
940
|
consume: async (request) => {
|
|
752
|
-
|
|
941
|
+
const { item_id,...body } = request;
|
|
942
|
+
return (await getState().http.post(`${P.inventory}/${encodePathSegment(item_id)}/consume`, body)).data;
|
|
753
943
|
}
|
|
754
944
|
},
|
|
755
945
|
leaderboards: {
|
|
@@ -763,6 +953,14 @@ const Amba = {
|
|
|
763
953
|
return (await getState().http.get(`${P.leaderboards}/${encodePathSegment(key)}/me`)).data;
|
|
764
954
|
}
|
|
765
955
|
},
|
|
956
|
+
leagues: {
|
|
957
|
+
me: async () => {
|
|
958
|
+
return (await getState().http.get(`${P.leagues}/me`)).data;
|
|
959
|
+
},
|
|
960
|
+
cohort: async () => {
|
|
961
|
+
return (await getState().http.get(`${P.leagues}/me/cohort`)).data;
|
|
962
|
+
}
|
|
963
|
+
},
|
|
766
964
|
stores: {
|
|
767
965
|
list: async () => {
|
|
768
966
|
return (await getState().http.get(P.stores)).data;
|
|
@@ -773,7 +971,7 @@ const Amba = {
|
|
|
773
971
|
purchase: async (storeKey, purchaseOptionId, receipt) => {
|
|
774
972
|
return (await getState().http.post(`${P.stores}/${encodePathSegment(storeKey)}/purchase`, {
|
|
775
973
|
purchase_option_id: purchaseOptionId,
|
|
776
|
-
receipt
|
|
974
|
+
receipt: receipt ?? {}
|
|
777
975
|
})).data;
|
|
778
976
|
}
|
|
779
977
|
},
|
|
@@ -807,6 +1005,15 @@ const Amba = {
|
|
|
807
1005
|
getFriends: async () => {
|
|
808
1006
|
return (await getState().http.get(P.friends, { state: "accepted" })).data;
|
|
809
1007
|
},
|
|
1008
|
+
sendRequest: async (userId) => {
|
|
1009
|
+
return (await getState().http.post(`${P.friends}/request`, { user_id: userId })).data;
|
|
1010
|
+
},
|
|
1011
|
+
acceptRequest: async (friendshipId) => {
|
|
1012
|
+
return (await getState().http.post(`${P.friends}/${encodePathSegment(friendshipId)}/accept`, {})).data;
|
|
1013
|
+
},
|
|
1014
|
+
declineRequest: async (friendshipId) => {
|
|
1015
|
+
await getState().http.post(`${P.friends}/${encodePathSegment(friendshipId)}/reject`, {});
|
|
1016
|
+
},
|
|
810
1017
|
blockUser: async (userId) => {
|
|
811
1018
|
return (await getState().http.post(`${P.friends}/block`, { user_id: userId })).data;
|
|
812
1019
|
},
|
|
@@ -815,6 +1022,9 @@ const Amba = {
|
|
|
815
1022
|
},
|
|
816
1023
|
removeBlock: async (friendshipId) => {
|
|
817
1024
|
await getState().http.delete(`${P.friends}/${encodePathSegment(friendshipId)}`);
|
|
1025
|
+
},
|
|
1026
|
+
removeFriend: async (userId) => {
|
|
1027
|
+
await getState().http.delete(`${P.friends}/by-user/${encodePathSegment(userId)}`);
|
|
818
1028
|
}
|
|
819
1029
|
},
|
|
820
1030
|
groups: {
|
|
@@ -847,10 +1057,7 @@ const Amba = {
|
|
|
847
1057
|
createConversation: async (request) => {
|
|
848
1058
|
return (await getState().http.post(`${P.messaging}/conversations`, request)).data;
|
|
849
1059
|
},
|
|
850
|
-
|
|
851
|
-
return (await getState().http.get(`${P.messaging}/conversations`)).data;
|
|
852
|
-
},
|
|
853
|
-
listConversations: async () => {
|
|
1060
|
+
conversations: async () => {
|
|
854
1061
|
return (await getState().http.get(`${P.messaging}/conversations`)).data;
|
|
855
1062
|
},
|
|
856
1063
|
sendMessage: async (conversationId, request) => {
|
|
@@ -864,6 +1071,24 @@ const Amba = {
|
|
|
864
1071
|
},
|
|
865
1072
|
markRead: async (conversationId) => {
|
|
866
1073
|
return (await getState().http.post(`${P.messaging}/conversations/${encodePathSegment(conversationId)}/read`, {})).data;
|
|
1074
|
+
},
|
|
1075
|
+
getMessage: async (conversationId, messageId) => {
|
|
1076
|
+
const PAGE_SIZE = 100;
|
|
1077
|
+
const MAX_PAGES = 50;
|
|
1078
|
+
const s = getState();
|
|
1079
|
+
const path = `${P.messaging}/conversations/${encodePathSegment(conversationId)}/messages`;
|
|
1080
|
+
let offset = 0;
|
|
1081
|
+
for (let i = 0; i < MAX_PAGES; i++) {
|
|
1082
|
+
const page = (await s.http.get(path, {
|
|
1083
|
+
limit: PAGE_SIZE,
|
|
1084
|
+
offset
|
|
1085
|
+
})).data;
|
|
1086
|
+
const hit = page.find((m) => m.id === messageId);
|
|
1087
|
+
if (hit) return hit;
|
|
1088
|
+
if (page.length < PAGE_SIZE) return null;
|
|
1089
|
+
offset += PAGE_SIZE;
|
|
1090
|
+
}
|
|
1091
|
+
return null;
|
|
867
1092
|
}
|
|
868
1093
|
},
|
|
869
1094
|
moderation: {
|
|
@@ -904,7 +1129,7 @@ const Amba = {
|
|
|
904
1129
|
},
|
|
905
1130
|
referrals: {
|
|
906
1131
|
getReferralCode: async () => {
|
|
907
|
-
return (await getState().http.get(`${P.referrals}/
|
|
1132
|
+
return (await getState().http.get(`${P.referrals}/my-code`)).data;
|
|
908
1133
|
},
|
|
909
1134
|
claimReferral: async (code) => {
|
|
910
1135
|
return (await getState().http.post(`${P.referrals}/claim`, { code })).data;
|
|
@@ -916,20 +1141,25 @@ const Amba = {
|
|
|
916
1141
|
return (await getState().http.post(P.referrals, body)).data;
|
|
917
1142
|
}
|
|
918
1143
|
},
|
|
919
|
-
catalog: {
|
|
920
|
-
|
|
921
|
-
|
|
1144
|
+
catalog: {
|
|
1145
|
+
list: async () => {
|
|
1146
|
+
return (await getState().http.get(P.catalog)).data;
|
|
1147
|
+
},
|
|
1148
|
+
get: async (id) => {
|
|
1149
|
+
return (await getState().http.get(`${P.catalog}/${encodePathSegment(id)}`)).data;
|
|
1150
|
+
}
|
|
1151
|
+
},
|
|
922
1152
|
content: {
|
|
923
|
-
|
|
1153
|
+
today: async (channel = "default") => {
|
|
924
1154
|
return (await getState().http.get(`${P.content}/today/${encodePathSegment(channel)}`)).data ?? null;
|
|
925
1155
|
},
|
|
926
|
-
|
|
1156
|
+
library: async (channel = "default", options) => {
|
|
927
1157
|
return (await getState().http.get(`${P.content}/library/${encodePathSegment(channel)}`, {
|
|
928
1158
|
limit: options?.limit,
|
|
929
1159
|
cursor: options?.cursor
|
|
930
1160
|
})).data;
|
|
931
1161
|
},
|
|
932
|
-
|
|
1162
|
+
item: async (id) => {
|
|
933
1163
|
return (await getState().http.get(`${P.content}/${encodePathSegment(id)}`)).data;
|
|
934
1164
|
},
|
|
935
1165
|
updateItem: async (id, state_) => {
|
|
@@ -941,7 +1171,7 @@ const Amba = {
|
|
|
941
1171
|
},
|
|
942
1172
|
deepLinks: {
|
|
943
1173
|
get: async (shortCode) => {
|
|
944
|
-
return (await getState().http.get(`${P.deepLinks}/${encodePathSegment(shortCode)}`)).data;
|
|
1174
|
+
return (await getState().http.get(`${P.deepLinks}/resolve/${encodePathSegment(shortCode)}`)).data;
|
|
945
1175
|
},
|
|
946
1176
|
create: async (params) => {
|
|
947
1177
|
return (await getState().http.post(P.deepLinks, params)).data;
|