@fytkit/sdk 3.5.0 → 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/CHANGELOG.md +23 -0
- package/README.md +46 -5
- package/dist/index.d.ts +2515 -944
- package/dist/index.js +122 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ORPCError, isORPCErrorJson, createORPCErrorFromJson, createORPCClient } from '@orpc/client';
|
|
2
2
|
import { RPCLink } from '@orpc/client/fetch';
|
|
3
3
|
|
|
4
4
|
// src/error.ts
|
|
@@ -20,7 +20,8 @@ function pickRefusal(data) {
|
|
|
20
20
|
if (!isRecord(data)) return {};
|
|
21
21
|
const { reason, ...rest } = data;
|
|
22
22
|
if (typeof reason === "string" && reason.length > 0) return { refusal: { reason, data: rest } };
|
|
23
|
-
if (data.quotaCode === MEMBER_CAP_QUOTA)
|
|
23
|
+
if (data.quotaCode === MEMBER_CAP_QUOTA)
|
|
24
|
+
return { refusal: { reason: MEMBER_CAP_QUOTA, data: {} } };
|
|
24
25
|
return {};
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -95,6 +96,28 @@ function normalizeError(err) {
|
|
|
95
96
|
return { kind: "server", status: 0 };
|
|
96
97
|
}
|
|
97
98
|
|
|
99
|
+
// src/app.ts
|
|
100
|
+
var UNEXPECTED_NOT_MODIFIED = { kind: "server", status: 304 };
|
|
101
|
+
function createAppNamespace(transport) {
|
|
102
|
+
const bootstrap = async (options = {}) => {
|
|
103
|
+
const etag = options.etag ?? null;
|
|
104
|
+
let output;
|
|
105
|
+
try {
|
|
106
|
+
output = await transport.client.app.bootstrap(void 0, {
|
|
107
|
+
context: etag === null ? {} : { ifNoneMatch: etag }
|
|
108
|
+
});
|
|
109
|
+
} catch (error) {
|
|
110
|
+
throw normalizeError(error);
|
|
111
|
+
}
|
|
112
|
+
if (output === void 0 || output === null) {
|
|
113
|
+
if (etag === null) throw UNEXPECTED_NOT_MODIFIED;
|
|
114
|
+
return { status: "unchanged", etag };
|
|
115
|
+
}
|
|
116
|
+
return { status: "ok", data: output.data, etag: output.meta.etag };
|
|
117
|
+
};
|
|
118
|
+
return { bootstrap };
|
|
119
|
+
}
|
|
120
|
+
|
|
98
121
|
// src/events.ts
|
|
99
122
|
function createEventBus() {
|
|
100
123
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -235,6 +258,10 @@ function createAuthNamespace(opts) {
|
|
|
235
258
|
const confirmEmail = async (input) => {
|
|
236
259
|
await call(() => opts.transport.client.auth.confirmEmail(input));
|
|
237
260
|
};
|
|
261
|
+
const resendVerification = async () => {
|
|
262
|
+
const result = await call(() => opts.transport.client.auth.resendVerification({}));
|
|
263
|
+
return result.data;
|
|
264
|
+
};
|
|
238
265
|
const verifyTotp = async (input) => {
|
|
239
266
|
const result = await call(
|
|
240
267
|
() => opts.transport.client.auth.verifyTotp({ token: input.challenge.token, code: input.code })
|
|
@@ -308,6 +335,9 @@ function createAuthNamespace(opts) {
|
|
|
308
335
|
const changeEmail = async (input) => {
|
|
309
336
|
await call(() => opts.transport.client.auth.changeEmail(input));
|
|
310
337
|
};
|
|
338
|
+
const confirmEmailChange = async (input) => {
|
|
339
|
+
await call(() => opts.transport.client.auth.confirmEmailChange(input));
|
|
340
|
+
};
|
|
311
341
|
const listSessions = async () => {
|
|
312
342
|
const result = await call(() => opts.transport.client.auth.listSessions());
|
|
313
343
|
return result.data;
|
|
@@ -364,6 +394,7 @@ function createAuthNamespace(opts) {
|
|
|
364
394
|
requestPasswordReset,
|
|
365
395
|
confirmPasswordReset,
|
|
366
396
|
confirmEmail,
|
|
397
|
+
resendVerification,
|
|
367
398
|
verifyTotp,
|
|
368
399
|
verifyBackupCode,
|
|
369
400
|
requestEmailOtp,
|
|
@@ -375,6 +406,7 @@ function createAuthNamespace(opts) {
|
|
|
375
406
|
regenerateBackupCodes,
|
|
376
407
|
changePassword,
|
|
377
408
|
changeEmail,
|
|
409
|
+
confirmEmailChange,
|
|
378
410
|
listSessions,
|
|
379
411
|
revokeSession,
|
|
380
412
|
revokeOtherSessions,
|
|
@@ -384,6 +416,9 @@ function createAuthNamespace(opts) {
|
|
|
384
416
|
};
|
|
385
417
|
}
|
|
386
418
|
|
|
419
|
+
// src/base-url.ts
|
|
420
|
+
var DEFAULT_BASE_URL = "https://api.fytkit.com";
|
|
421
|
+
|
|
387
422
|
// src/data.ts
|
|
388
423
|
function wrapSlice(slice) {
|
|
389
424
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -422,11 +457,15 @@ function createDataNamespaces(transport) {
|
|
|
422
457
|
sessionLogs: wrapSlice(c.sessionLog),
|
|
423
458
|
progression: wrapSlice(c.progression),
|
|
424
459
|
bodyMetrics: wrapSlice(c.bodyMetric),
|
|
460
|
+
bodyMeasurements: wrapSlice(c.bodyMeasurement),
|
|
461
|
+
progressPhotos: wrapSlice(c.progressPhoto),
|
|
425
462
|
checkIns: wrapSlice(c.checkin),
|
|
426
463
|
messages: wrapSlice(c.message),
|
|
464
|
+
timeline: wrapSlice(c.timeline),
|
|
465
|
+
health: wrapSlice(c.health),
|
|
466
|
+
habits: wrapSlice(c.habit),
|
|
427
467
|
progress: wrapSlice(c.progress),
|
|
428
468
|
media: wrapSlice(c.media),
|
|
429
|
-
appConfig: wrapSlice(c.appConfig),
|
|
430
469
|
subscription: wrapSlice(c.subscription),
|
|
431
470
|
profile: wrapSlice(c.profile),
|
|
432
471
|
nutritionLog: wrapSlice(c.nutritionLog),
|
|
@@ -548,7 +587,7 @@ function createTransport(options) {
|
|
|
548
587
|
};
|
|
549
588
|
const link = new RPCLink({
|
|
550
589
|
url: () => `${options.baseUrl}/rpc`,
|
|
551
|
-
headers: () => {
|
|
590
|
+
headers: ({ context }) => {
|
|
552
591
|
const session = options.getSession();
|
|
553
592
|
const headers = {
|
|
554
593
|
"X-Fytkit-Client-Id": options.clientId
|
|
@@ -556,6 +595,9 @@ function createTransport(options) {
|
|
|
556
595
|
if (session) {
|
|
557
596
|
headers.Authorization = `Bearer ${session.accessToken}`;
|
|
558
597
|
}
|
|
598
|
+
if (context.ifNoneMatch !== void 0) {
|
|
599
|
+
headers["If-None-Match"] = context.ifNoneMatch;
|
|
600
|
+
}
|
|
559
601
|
return headers;
|
|
560
602
|
},
|
|
561
603
|
fetch: wrappedFetch
|
|
@@ -575,6 +617,7 @@ var CREDENTIAL_PROCEDURES = [
|
|
|
575
617
|
"auth/requestPasswordReset",
|
|
576
618
|
"auth/confirmPasswordReset",
|
|
577
619
|
"auth/confirmEmail",
|
|
620
|
+
"auth/confirmEmailChange",
|
|
578
621
|
"auth/verifyTotp",
|
|
579
622
|
"auth/verifyBackupCode",
|
|
580
623
|
"auth/requestEmailOtp",
|
|
@@ -642,6 +685,73 @@ function attachRefreshInterceptor(opts) {
|
|
|
642
685
|
return retried;
|
|
643
686
|
});
|
|
644
687
|
}
|
|
688
|
+
var INACTIVE = {
|
|
689
|
+
kind: "not_found",
|
|
690
|
+
refusal: { reason: "join_code_inactive", data: {} }
|
|
691
|
+
};
|
|
692
|
+
var IGNORED_SEPARATORS = /[\s\-\u2010-\u2015\u2212]/g;
|
|
693
|
+
var PATH_SAFE_CODE = /^[A-Za-z0-9]{1,64}$/;
|
|
694
|
+
function pathSafeJoinCode(input) {
|
|
695
|
+
const candidate = input.replace(IGNORED_SEPARATORS, "");
|
|
696
|
+
return PATH_SAFE_CODE.test(candidate) ? candidate.toUpperCase() : null;
|
|
697
|
+
}
|
|
698
|
+
async function readJson(response) {
|
|
699
|
+
try {
|
|
700
|
+
return await response.json();
|
|
701
|
+
} catch {
|
|
702
|
+
return void 0;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
function refusalOf(response, body) {
|
|
706
|
+
const wait = () => retryAfterHeaderMs(response.headers.get("retry-after"), Date.now()) ?? 0;
|
|
707
|
+
if (isORPCErrorJson(body)) {
|
|
708
|
+
const error = normalizeError(createORPCErrorFromJson(body));
|
|
709
|
+
if (error.kind === "rate_limited" && error.retryAfter === 0) {
|
|
710
|
+
return { ...error, retryAfter: wait() };
|
|
711
|
+
}
|
|
712
|
+
return error;
|
|
713
|
+
}
|
|
714
|
+
if (response.status === 429) return { kind: "rate_limited", retryAfter: wait() };
|
|
715
|
+
return { kind: "server", status: response.status };
|
|
716
|
+
}
|
|
717
|
+
async function resolveJoinCode(code, options = {}) {
|
|
718
|
+
const canonical = pathSafeJoinCode(code);
|
|
719
|
+
if (canonical === null) throw INACTIVE;
|
|
720
|
+
const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
|
|
721
|
+
const doFetch = options.fetch ?? fetch.bind(globalThis);
|
|
722
|
+
let response;
|
|
723
|
+
try {
|
|
724
|
+
response = await doFetch(`${baseUrl}/api/v1/join/${canonical}`, {
|
|
725
|
+
method: "GET",
|
|
726
|
+
headers: { Accept: "application/json" }
|
|
727
|
+
});
|
|
728
|
+
} catch (error) {
|
|
729
|
+
throw normalizeError(error);
|
|
730
|
+
}
|
|
731
|
+
const body = await readJson(response);
|
|
732
|
+
if (response.ok) {
|
|
733
|
+
if (isRecord(body) && isRecord(body.data)) {
|
|
734
|
+
return body.data;
|
|
735
|
+
}
|
|
736
|
+
throw { kind: "server", status: response.status };
|
|
737
|
+
}
|
|
738
|
+
throw refusalOf(response, body);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// src/payment-policy.ts
|
|
742
|
+
var PLAN_INFO = { mode: "plan_info" };
|
|
743
|
+
function resolvePaymentMode(policy, options) {
|
|
744
|
+
if (!policy || !Array.isArray(policy.linkOut)) return PLAN_INFO;
|
|
745
|
+
const storefront = options.storefront?.trim().toUpperCase() ?? "";
|
|
746
|
+
if (storefront === "") return PLAN_INFO;
|
|
747
|
+
const rule = policy.linkOut.find(
|
|
748
|
+
(entry) => entry?.platform === options.platform && typeof entry.storefront === "string" && entry.storefront.toUpperCase() === storefront
|
|
749
|
+
);
|
|
750
|
+
if (!rule || !Array.isArray(rule.conditions)) return PLAN_INFO;
|
|
751
|
+
const met = new Set(options.conditionsMet ?? []);
|
|
752
|
+
if (!rule.conditions.every((condition) => met.has(condition))) return PLAN_INFO;
|
|
753
|
+
return { mode: "link_out", conditions: rule.conditions };
|
|
754
|
+
}
|
|
645
755
|
|
|
646
756
|
// src/realtime.ts
|
|
647
757
|
var MESSAGES_FALLBACK_POLL_MS = {
|
|
@@ -822,7 +932,8 @@ function subscribeToMessages(client, options) {
|
|
|
822
932
|
if (connection === null) {
|
|
823
933
|
let realtime;
|
|
824
934
|
try {
|
|
825
|
-
|
|
935
|
+
const bootstrap = await client.app.bootstrap();
|
|
936
|
+
realtime = bootstrap.status === "ok" ? bootstrap.data.realtime : void 0;
|
|
826
937
|
} catch (error) {
|
|
827
938
|
if (closed) return;
|
|
828
939
|
if (isFinalError(error)) {
|
|
@@ -899,7 +1010,6 @@ function subscribeToMessages(client, options) {
|
|
|
899
1010
|
}
|
|
900
1011
|
|
|
901
1012
|
// src/index.ts
|
|
902
|
-
var DEFAULT_BASE_URL = "https://api.fytkit.com";
|
|
903
1013
|
function createFytkitClient(options) {
|
|
904
1014
|
if (!options || typeof options.clientId !== "string" || options.clientId.length === 0) {
|
|
905
1015
|
throw new Error("createFytkitClient: `clientId` is required");
|
|
@@ -918,6 +1028,7 @@ function createFytkitClient(options) {
|
|
|
918
1028
|
attachRefreshInterceptor({ transport, auth: authInstance });
|
|
919
1029
|
const data = createDataNamespaces(transport);
|
|
920
1030
|
return {
|
|
1031
|
+
clientId: options.clientId,
|
|
921
1032
|
auth: {
|
|
922
1033
|
signUp: authInstance.signUp,
|
|
923
1034
|
signIn: authInstance.signIn,
|
|
@@ -927,6 +1038,7 @@ function createFytkitClient(options) {
|
|
|
927
1038
|
requestPasswordReset: authInstance.requestPasswordReset,
|
|
928
1039
|
confirmPasswordReset: authInstance.confirmPasswordReset,
|
|
929
1040
|
confirmEmail: authInstance.confirmEmail,
|
|
1041
|
+
resendVerification: authInstance.resendVerification,
|
|
930
1042
|
verifyTotp: authInstance.verifyTotp,
|
|
931
1043
|
verifyBackupCode: authInstance.verifyBackupCode,
|
|
932
1044
|
requestEmailOtp: authInstance.requestEmailOtp,
|
|
@@ -938,15 +1050,17 @@ function createFytkitClient(options) {
|
|
|
938
1050
|
regenerateBackupCodes: authInstance.regenerateBackupCodes,
|
|
939
1051
|
changePassword: authInstance.changePassword,
|
|
940
1052
|
changeEmail: authInstance.changeEmail,
|
|
1053
|
+
confirmEmailChange: authInstance.confirmEmailChange,
|
|
941
1054
|
listSessions: authInstance.listSessions,
|
|
942
1055
|
revokeSession: authInstance.revokeSession,
|
|
943
1056
|
revokeOtherSessions: authInstance.revokeOtherSessions,
|
|
944
1057
|
closeAccount: authInstance.closeAccount
|
|
945
1058
|
},
|
|
946
|
-
...data
|
|
1059
|
+
...data,
|
|
1060
|
+
app: createAppNamespace(transport)
|
|
947
1061
|
};
|
|
948
1062
|
}
|
|
949
1063
|
|
|
950
|
-
export { MESSAGES_FALLBACK_POLL_MS, createFytkitClient, createLocalStorageAdapter, createMemoryStorageAdapter, refusalData, subscribeToMessages };
|
|
1064
|
+
export { MESSAGES_FALLBACK_POLL_MS, createFytkitClient, createLocalStorageAdapter, createMemoryStorageAdapter, refusalData, resolveJoinCode, resolvePaymentMode, subscribeToMessages };
|
|
951
1065
|
//# sourceMappingURL=index.js.map
|
|
952
1066
|
//# sourceMappingURL=index.js.map
|