@layers/amba-react-native 4.0.2 → 4.0.3
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 +105 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +68 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +105 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -91,12 +91,14 @@ var AmbaHttpClient = class {
|
|
|
91
91
|
sdkVersionHeader;
|
|
92
92
|
identity;
|
|
93
93
|
fetchImpl;
|
|
94
|
+
ensureSession;
|
|
94
95
|
constructor(opts) {
|
|
95
96
|
this.apiKey = opts.apiKey;
|
|
96
97
|
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
97
98
|
this.sdkPlatform = opts.sdkPlatform;
|
|
98
99
|
this.sdkVersionHeader = opts.sdkVersionHeader;
|
|
99
100
|
this.identity = opts.identity;
|
|
101
|
+
this.ensureSession = opts.ensureSession;
|
|
100
102
|
this.fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
101
103
|
}
|
|
102
104
|
/** Build the absolute URL for an API path, optionally with a query string. */
|
|
@@ -139,6 +141,7 @@ var AmbaHttpClient = class {
|
|
|
139
141
|
return this.request("DELETE", path);
|
|
140
142
|
}
|
|
141
143
|
async request(method, path, body, query) {
|
|
144
|
+
if (this.ensureSession && !this.identity.getSessionToken()) await this.ensureSession(path);
|
|
142
145
|
const url = this.url(path, query);
|
|
143
146
|
const init = {
|
|
144
147
|
method,
|
|
@@ -351,7 +354,13 @@ function freshSeed() {
|
|
|
351
354
|
//#endregion
|
|
352
355
|
//#region src/index.ts
|
|
353
356
|
/** SDK semver — burned in at build time. Bump alongside package.json. */
|
|
354
|
-
const SDK_VERSION = "4.0.
|
|
357
|
+
const SDK_VERSION = "4.0.3";
|
|
358
|
+
/**
|
|
359
|
+
* Default host that serves deployed functions. `Amba.functions.invoke(name)`
|
|
360
|
+
* targets `https://<projectId>.<DEFAULT_FUNCTIONS_HOST>/<name>` unless a
|
|
361
|
+
* `functionsBaseUrl` override is configured.
|
|
362
|
+
*/
|
|
363
|
+
const DEFAULT_FUNCTIONS_HOST = "fn.amba.host";
|
|
355
364
|
let state = null;
|
|
356
365
|
function getState() {
|
|
357
366
|
if (!state) throw new AmbaApiError("NOT_INITIALIZED", "@layers/amba-react-native: SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start.");
|
|
@@ -395,6 +404,26 @@ async function postAuth(state_, path, body) {
|
|
|
395
404
|
await notifyFromAuthResult(result);
|
|
396
405
|
return result;
|
|
397
406
|
}
|
|
407
|
+
/** Paths that must NOT trigger lazy anonymous sign-in. */
|
|
408
|
+
function pathSkipsLazySession(path) {
|
|
409
|
+
if (path.startsWith("/v1/client/auth/")) return true;
|
|
410
|
+
if (path === P.events || path.startsWith(`${P.events}/`)) return true;
|
|
411
|
+
if (path === P.diagnosticsPing) return true;
|
|
412
|
+
if (path === P.config || path.startsWith(`${P.config}/`)) return true;
|
|
413
|
+
if (path === P.flags || path.startsWith(`${P.flags}/`)) return true;
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
async function ensureAnonymousSession(state_) {
|
|
417
|
+
if (state_.identity.getSessionToken()) return;
|
|
418
|
+
if (!state_.anonSignInInflight) state_.anonSignInInflight = (async () => {
|
|
419
|
+
try {
|
|
420
|
+
await postAuth(state_, P.authAnonymous, { anonymous_id: state_.identity.getAnonymousId() });
|
|
421
|
+
} finally {
|
|
422
|
+
state_.anonSignInInflight = null;
|
|
423
|
+
}
|
|
424
|
+
})();
|
|
425
|
+
await state_.anonSignInInflight;
|
|
426
|
+
}
|
|
398
427
|
/**
|
|
399
428
|
* POST helper for endpoints that return `{ data: { user } }` WITHOUT
|
|
400
429
|
* minting new tokens. Used by `linkSmsOtp` / `linkEmailOtp` / `unlink*`
|
|
@@ -491,6 +520,22 @@ function encodePathSegment(s) {
|
|
|
491
520
|
return encodeURIComponent(s);
|
|
492
521
|
}
|
|
493
522
|
/**
|
|
523
|
+
* Resolve the full invocation URL for a deployed function. With
|
|
524
|
+
* `functionsBaseUrl` configured we POST to `<base>/<name>` verbatim;
|
|
525
|
+
* otherwise we resolve the server-side project id once (via
|
|
526
|
+
* `diagnostics.ping`, cached) and target
|
|
527
|
+
* `https://<projectId>.fn.amba.host/<name>`.
|
|
528
|
+
*/
|
|
529
|
+
async function resolveFunctionUrl(s, name) {
|
|
530
|
+
if (s.functionsBaseUrl) return `${s.functionsBaseUrl.replace(/\/$/, "")}/${encodeURIComponent(name)}`;
|
|
531
|
+
if (!s.resolvedFunctionsProjectId) {
|
|
532
|
+
const ping = await Amba.diagnostics.ping();
|
|
533
|
+
if (!ping.ok || !ping.server_project_id) throw new AmbaApiError("FUNCTIONS_HOST_UNRESOLVED", "Could not resolve the functions host for this project. Pass `functionsBaseUrl` to Amba.configure() to invoke functions explicitly.", ping);
|
|
534
|
+
s.resolvedFunctionsProjectId = ping.server_project_id;
|
|
535
|
+
}
|
|
536
|
+
return `https://${s.resolvedFunctionsProjectId}.${DEFAULT_FUNCTIONS_HOST}/${encodeURIComponent(name)}`;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
494
539
|
* Top-level SDK namespace for React Native.
|
|
495
540
|
*/
|
|
496
541
|
const Amba = {
|
|
@@ -508,11 +553,17 @@ const Amba = {
|
|
|
508
553
|
baseUrl,
|
|
509
554
|
sdkPlatform: "react-native",
|
|
510
555
|
sdkVersionHeader,
|
|
511
|
-
identity
|
|
556
|
+
identity,
|
|
557
|
+
ensureSession: config.autoAnonymousSession === false ? void 0 : async (path) => {
|
|
558
|
+
if (pathSkipsLazySession(path)) return;
|
|
559
|
+
await ensureAnonymousSession(getState());
|
|
560
|
+
}
|
|
512
561
|
}),
|
|
513
562
|
identity,
|
|
514
563
|
debug: config.debug ?? false,
|
|
515
|
-
projectId: config.projectId
|
|
564
|
+
projectId: config.projectId,
|
|
565
|
+
functionsBaseUrl: config.functionsBaseUrl ?? null,
|
|
566
|
+
resolvedFunctionsProjectId: null
|
|
516
567
|
};
|
|
517
568
|
},
|
|
518
569
|
_reset: () => {
|
|
@@ -651,6 +702,19 @@ const Amba = {
|
|
|
651
702
|
session_token: sessionToken
|
|
652
703
|
});
|
|
653
704
|
},
|
|
705
|
+
linkEmailPassword: async (email, password) => {
|
|
706
|
+
requireEmail(email);
|
|
707
|
+
requirePassword(password);
|
|
708
|
+
const s = getState();
|
|
709
|
+
const sessionToken = s.identity.getSessionToken();
|
|
710
|
+
if (!sessionToken) throw new AmbaApiError("UNAUTHORIZED", "no active session — call signIn* first");
|
|
711
|
+
return postUserNoRotate(s, P.authLink, {
|
|
712
|
+
provider: "email_password",
|
|
713
|
+
email,
|
|
714
|
+
password,
|
|
715
|
+
session_token: sessionToken
|
|
716
|
+
});
|
|
717
|
+
},
|
|
654
718
|
unlinkSmsOtp: async () => unlinkProvider("sms_otp"),
|
|
655
719
|
unlinkEmailOtp: async () => unlinkProvider("email_otp"),
|
|
656
720
|
unlinkApple: async () => unlinkProvider("apple"),
|
|
@@ -899,8 +963,41 @@ const Amba = {
|
|
|
899
963
|
}
|
|
900
964
|
},
|
|
901
965
|
ai: { anthropic: { messages: { create: async (request) => {
|
|
902
|
-
|
|
966
|
+
const env = await getState().http.post(P.aiAnthropic, request);
|
|
967
|
+
if (!env || typeof env !== "object" || env.data === void 0) throw new AmbaApiError("MALFORMED_RESPONSE", "AI response was not wrapped in the expected { data } envelope", env);
|
|
968
|
+
return env.data;
|
|
903
969
|
} } } },
|
|
970
|
+
functions: { invoke: async (name, body, options) => {
|
|
971
|
+
const s = getState();
|
|
972
|
+
if (!name || name.trim() === "") throw new AmbaApiError("INVALID_ARGUMENT", "Amba.functions.invoke: a function name is required.");
|
|
973
|
+
const url = await resolveFunctionUrl(s, name);
|
|
974
|
+
const method = options?.method ?? "POST";
|
|
975
|
+
const headers = s.http.buildHeaders(options?.headers);
|
|
976
|
+
let requestBody;
|
|
977
|
+
if (body !== void 0 && method !== "GET") requestBody = JSON.stringify(body);
|
|
978
|
+
else delete headers["Content-Type"];
|
|
979
|
+
let response;
|
|
980
|
+
try {
|
|
981
|
+
response = await (globalThis.fetch ?? fetch)(url, {
|
|
982
|
+
method,
|
|
983
|
+
headers,
|
|
984
|
+
body: requestBody
|
|
985
|
+
});
|
|
986
|
+
} catch (err) {
|
|
987
|
+
throw new AmbaApiError("NETWORK_ERROR", `Amba.functions.invoke("${name}") network error: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
988
|
+
}
|
|
989
|
+
const text = await response.text();
|
|
990
|
+
if (!response.ok) {
|
|
991
|
+
const ct = response.headers.get("content-type") ?? "";
|
|
992
|
+
throw mapHttpError(response, text, ct.includes("application/json"));
|
|
993
|
+
}
|
|
994
|
+
if (!text) return void 0;
|
|
995
|
+
try {
|
|
996
|
+
return JSON.parse(text);
|
|
997
|
+
} catch {
|
|
998
|
+
return text;
|
|
999
|
+
}
|
|
1000
|
+
} },
|
|
904
1001
|
config: { fetch: async () => {
|
|
905
1002
|
const s = getState();
|
|
906
1003
|
const url = s.http.url(P.config);
|
|
@@ -1210,19 +1307,19 @@ const Amba = {
|
|
|
1210
1307
|
return (await getState().http.get(`${P.content}/today/${encodePathSegment(channel)}`)).data ?? null;
|
|
1211
1308
|
},
|
|
1212
1309
|
library: async (channel = "default", options) => {
|
|
1213
|
-
return (await getState().http.get(`${P.content}/
|
|
1310
|
+
return (await getState().http.get(`${P.content}/libraries/${encodePathSegment(channel)}`, {
|
|
1214
1311
|
limit: options?.limit,
|
|
1215
1312
|
cursor: options?.cursor
|
|
1216
1313
|
})).data;
|
|
1217
1314
|
},
|
|
1218
1315
|
item: async (id) => {
|
|
1219
|
-
return (await getState().http.get(`${P.content}/${encodePathSegment(id)}`)).data;
|
|
1316
|
+
return (await getState().http.get(`${P.content}/items/${encodePathSegment(id)}`)).data;
|
|
1220
1317
|
},
|
|
1221
1318
|
updateItem: async (id, state_) => {
|
|
1222
|
-
return (await getState().http.
|
|
1319
|
+
return (await getState().http.patch(`${P.content}/items/${encodePathSegment(id)}`, state_)).data;
|
|
1223
1320
|
},
|
|
1224
1321
|
createItem: async (channel, item) => {
|
|
1225
|
-
return (await getState().http.post(`${P.content}/${encodePathSegment(channel)}`, item)).data;
|
|
1322
|
+
return (await getState().http.post(`${P.content}/libraries/${encodePathSegment(channel)}/items`, item)).data;
|
|
1226
1323
|
}
|
|
1227
1324
|
},
|
|
1228
1325
|
deepLinks: {
|