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