@fytkit/sdk 0.3.0 → 0.5.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 +14 -0
- package/README.md +32 -1
- package/dist/index.d.ts +440 -12
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to `@fytkit/sdk` are documented in this file.
|
|
|
4
4
|
Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
Versioning: [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.5.0](https://github.com/cbarlow1993/fytkit-web/compare/@fytkit/sdk@0.4.0...@fytkit/sdk@0.5.0) (2026-07-05)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **sdk:** ad-hoc workout logging, stored PR history and streak endpoints ([#116](https://github.com/cbarlow1993/fytkit-web/issues/116)) ([5b069f9](https://github.com/cbarlow1993/fytkit-web/commit/5b069f993ee66d5aa4d54b04f2096d39a4ca7a37))
|
|
13
|
+
|
|
14
|
+
## [0.4.0](https://github.com/cbarlow1993/fytkit-web/compare/@fytkit/sdk@0.3.0...@fytkit/sdk@0.4.0) (2026-06-13)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **monetization:** per-plan member entitlements + public checkout via API/SDK ([#111](https://github.com/cbarlow1993/fytkit-web/issues/111)) ([47f828f](https://github.com/cbarlow1993/fytkit-web/commit/47f828f10e27f34731bae1c4087c5a31aca4a0d8))
|
|
20
|
+
|
|
7
21
|
## [0.3.0](https://github.com/cbarlow1993/fytkit-web/compare/@fytkit/sdk@0.2.2...@fytkit/sdk@0.3.0) (2026-06-03)
|
|
8
22
|
|
|
9
23
|
|
package/README.md
CHANGED
|
@@ -48,11 +48,42 @@ await fytkit.auth.signOut();
|
|
|
48
48
|
off();
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
## Tracking a workout
|
|
52
|
+
|
|
53
|
+
Log a workout ad-hoc (no program enrollment needed), record sets, complete
|
|
54
|
+
it, then read back progress:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
// Start an ad-hoc log against any workout — or pass { sessionId, enrollmentId }
|
|
58
|
+
// instead to log a scheduled program session.
|
|
59
|
+
const { data: log } = await fytkit.sessionLogs.create({ workoutId });
|
|
60
|
+
|
|
61
|
+
await fytkit.sessionLogs.addSet({
|
|
62
|
+
id: log.id,
|
|
63
|
+
exerciseId,
|
|
64
|
+
setNumber: 1,
|
|
65
|
+
reps: 8,
|
|
66
|
+
weightKg: "80.00",
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await fytkit.sessionLogs.update({ id: log.id, completedAt: new Date().toISOString() });
|
|
70
|
+
|
|
71
|
+
// Workout-by-workout history for that workout
|
|
72
|
+
const { data: history } = await fytkit.sessionLogs.list({ workoutId });
|
|
73
|
+
|
|
74
|
+
// Stored progress: streak, PR history, aggregate summary
|
|
75
|
+
const { data: streak } = await fytkit.progress.getStreak({});
|
|
76
|
+
const { data: prs } = await fytkit.progression.listPrHistory({ exerciseId });
|
|
77
|
+
const { data: summary } = await fytkit.progress.getSummary({ period: "12w" });
|
|
78
|
+
```
|
|
79
|
+
|
|
51
80
|
## What's included in this preview
|
|
52
81
|
|
|
53
82
|
- `auth.signUp` / `signIn` / `signOut` / `getSession` / `onAuthStateChange`
|
|
54
83
|
- `auth.requestPasswordReset` / `confirmPasswordReset` / `confirmEmail`
|
|
55
|
-
- Data namespaces: `workouts`, `programs`, `recipes`, `nutrition`, `articles`, `enrollments`, `sessionLogs`, `progression`, `media`, `appConfig`, `subscription`
|
|
84
|
+
- Data namespaces: `workouts`, `programs`, `recipes`, `nutrition`, `nutritionLog`, `profile`, `articles`, `enrollments`, `sessionLogs`, `progression`, `progress`, `bodyMetrics`, `media`, `appConfig`, `subscription`
|
|
85
|
+
- Workout tracking: program session logs and ad-hoc workout logs (`sessionLogs.create` with `workoutId`), set logging, per-workout history (`sessionLogs.list({ workoutId })`)
|
|
86
|
+
- Progress: `progress.getSummary` / `getAdherence` / `getStreak` (stored streaks), `progression.getPrSummary` / `listPrHistory` (stored PR history) / `getHistory`, `bodyMetrics.list` / `record` / `delete`
|
|
56
87
|
- Automatic header injection (`X-Fytkit-Client-Id`, `Authorization: Bearer …`)
|
|
57
88
|
- Proactive refresh ~60 s before token expiry + reactive 401 retry
|
|
58
89
|
- Pluggable token storage (`localStorage` default, in-memory + cookie for SSR)
|
package/dist/index.d.ts
CHANGED
|
@@ -18,12 +18,15 @@ import { ZodObject } from 'zod';
|
|
|
18
18
|
import { ZodOptional } from 'zod';
|
|
19
19
|
import { ZodReadonly } from 'zod';
|
|
20
20
|
import { ZodString } from 'zod';
|
|
21
|
+
import { ZodUnion } from 'zod';
|
|
21
22
|
|
|
22
23
|
declare interface ApiKeyContext {
|
|
23
24
|
readonly trainerId: string;
|
|
24
25
|
readonly clientId?: string;
|
|
25
26
|
readonly hasActiveSubscription: boolean;
|
|
27
|
+
readonly clientEntitlements: ClientEntitlements;
|
|
26
28
|
readonly authMode: "session" | "api-key" | "dev-app";
|
|
29
|
+
readonly appAllowedOrigins?: readonly string[];
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
/** Auth-state events emitted on `onAuthStateChange`. */
|
|
@@ -47,6 +50,19 @@ export declare type AuthState = {
|
|
|
47
50
|
readonly type: "signed_out_due_to_token_reuse";
|
|
48
51
|
};
|
|
49
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Member-facing plan features. Each code maps 1:1 onto a premium content
|
|
55
|
+
* domain gated by the public API (`src/server/public-api/content-gating.ts`).
|
|
56
|
+
* A trainer toggles these per pricing tier; a member's active subscription
|
|
57
|
+
* grants the codes attached to the tier they bought.
|
|
58
|
+
*
|
|
59
|
+
* Distinct from `catalogue.ts`, which is the *trainer*-side entitlement
|
|
60
|
+
* catalogue driven by the trainer's fytkit subscription.
|
|
61
|
+
*/
|
|
62
|
+
declare type ClientEntitlementCode = "premium_workouts" | "premium_programs" | "premium_nutrition" | "premium_recipes" | "premium_articles";
|
|
63
|
+
|
|
64
|
+
declare type ClientEntitlements = readonly ClientEntitlementCode[] | "all";
|
|
65
|
+
|
|
50
66
|
export declare function createFytkitClient(options: FytkitClientOptions): FytkitClient;
|
|
51
67
|
|
|
52
68
|
/**
|
|
@@ -154,7 +170,9 @@ declare const publicRouter: {
|
|
|
154
170
|
appId: string;
|
|
155
171
|
clientId: string | undefined;
|
|
156
172
|
hasActiveSubscription: boolean;
|
|
173
|
+
clientEntitlements: ClientEntitlements;
|
|
157
174
|
authMode: "dev-app";
|
|
175
|
+
appAllowedOrigins: readonly string[];
|
|
158
176
|
}>, ZodObject< {
|
|
159
177
|
email: ZodString;
|
|
160
178
|
password: ZodString;
|
|
@@ -184,7 +202,9 @@ declare const publicRouter: {
|
|
|
184
202
|
appId: string;
|
|
185
203
|
clientId: string | undefined;
|
|
186
204
|
hasActiveSubscription: boolean;
|
|
205
|
+
clientEntitlements: ClientEntitlements;
|
|
187
206
|
authMode: "dev-app";
|
|
207
|
+
appAllowedOrigins: readonly string[];
|
|
188
208
|
}>, ZodObject< {
|
|
189
209
|
email: ZodString;
|
|
190
210
|
password: ZodString;
|
|
@@ -222,7 +242,9 @@ declare const publicRouter: {
|
|
|
222
242
|
appId: string;
|
|
223
243
|
clientId: string | undefined;
|
|
224
244
|
hasActiveSubscription: boolean;
|
|
245
|
+
clientEntitlements: ClientEntitlements;
|
|
225
246
|
authMode: "dev-app";
|
|
247
|
+
appAllowedOrigins: readonly string[];
|
|
226
248
|
}>, ZodObject< {
|
|
227
249
|
token: ZodString;
|
|
228
250
|
}, $strip>, ZodObject< {
|
|
@@ -243,7 +265,9 @@ declare const publicRouter: {
|
|
|
243
265
|
appId: string;
|
|
244
266
|
clientId: string | undefined;
|
|
245
267
|
hasActiveSubscription: boolean;
|
|
268
|
+
clientEntitlements: ClientEntitlements;
|
|
246
269
|
authMode: "dev-app";
|
|
270
|
+
appAllowedOrigins: readonly string[];
|
|
247
271
|
}>, ZodObject< {
|
|
248
272
|
token: ZodString;
|
|
249
273
|
}, $strip>, ZodObject< {
|
|
@@ -271,7 +295,9 @@ declare const publicRouter: {
|
|
|
271
295
|
appId: string;
|
|
272
296
|
clientId: string | undefined;
|
|
273
297
|
hasActiveSubscription: boolean;
|
|
298
|
+
clientEntitlements: ClientEntitlements;
|
|
274
299
|
authMode: "dev-app";
|
|
300
|
+
appAllowedOrigins: readonly string[];
|
|
275
301
|
}>, ZodObject< {
|
|
276
302
|
email: ZodString;
|
|
277
303
|
}, $strip>, ZodObject< {
|
|
@@ -292,7 +318,9 @@ declare const publicRouter: {
|
|
|
292
318
|
appId: string;
|
|
293
319
|
clientId: string | undefined;
|
|
294
320
|
hasActiveSubscription: boolean;
|
|
321
|
+
clientEntitlements: ClientEntitlements;
|
|
295
322
|
authMode: "dev-app";
|
|
323
|
+
appAllowedOrigins: readonly string[];
|
|
296
324
|
}>, ZodObject< {
|
|
297
325
|
token: ZodString;
|
|
298
326
|
password: ZodString;
|
|
@@ -314,7 +342,9 @@ declare const publicRouter: {
|
|
|
314
342
|
appId: string;
|
|
315
343
|
clientId: string | undefined;
|
|
316
344
|
hasActiveSubscription: boolean;
|
|
345
|
+
clientEntitlements: ClientEntitlements;
|
|
317
346
|
authMode: "dev-app";
|
|
347
|
+
appAllowedOrigins: readonly string[];
|
|
318
348
|
}>, ZodObject< {
|
|
319
349
|
token: ZodString;
|
|
320
350
|
}, $strip>, ZodObject< {
|
|
@@ -335,7 +365,9 @@ declare const publicRouter: {
|
|
|
335
365
|
appId: string;
|
|
336
366
|
clientId: string | undefined;
|
|
337
367
|
hasActiveSubscription: boolean;
|
|
368
|
+
clientEntitlements: ClientEntitlements;
|
|
338
369
|
authMode: "dev-app";
|
|
370
|
+
appAllowedOrigins: readonly string[];
|
|
339
371
|
}>, ZodObject< {
|
|
340
372
|
password: ZodString;
|
|
341
373
|
}, $strip>, ZodObject< {
|
|
@@ -357,7 +389,9 @@ declare const publicRouter: {
|
|
|
357
389
|
appId: string;
|
|
358
390
|
clientId: string | undefined;
|
|
359
391
|
hasActiveSubscription: boolean;
|
|
392
|
+
clientEntitlements: ClientEntitlements;
|
|
360
393
|
authMode: "dev-app";
|
|
394
|
+
appAllowedOrigins: readonly string[];
|
|
361
395
|
}>, ZodObject< {
|
|
362
396
|
code: ZodString;
|
|
363
397
|
}, $strip>, ZodObject< {
|
|
@@ -379,7 +413,9 @@ declare const publicRouter: {
|
|
|
379
413
|
appId: string;
|
|
380
414
|
clientId: string | undefined;
|
|
381
415
|
hasActiveSubscription: boolean;
|
|
416
|
+
clientEntitlements: ClientEntitlements;
|
|
382
417
|
authMode: "dev-app";
|
|
418
|
+
appAllowedOrigins: readonly string[];
|
|
383
419
|
}>, ZodObject< {
|
|
384
420
|
password: ZodString;
|
|
385
421
|
}, $strip>, ZodObject< {
|
|
@@ -400,7 +436,9 @@ declare const publicRouter: {
|
|
|
400
436
|
appId: string;
|
|
401
437
|
clientId: string | undefined;
|
|
402
438
|
hasActiveSubscription: boolean;
|
|
439
|
+
clientEntitlements: ClientEntitlements;
|
|
403
440
|
authMode: "dev-app";
|
|
441
|
+
appAllowedOrigins: readonly string[];
|
|
404
442
|
}>, ZodObject< {
|
|
405
443
|
password: ZodString;
|
|
406
444
|
}, $strip>, ZodObject< {
|
|
@@ -421,7 +459,9 @@ declare const publicRouter: {
|
|
|
421
459
|
appId: string;
|
|
422
460
|
clientId: string | undefined;
|
|
423
461
|
hasActiveSubscription: boolean;
|
|
462
|
+
clientEntitlements: ClientEntitlements;
|
|
424
463
|
authMode: "dev-app";
|
|
464
|
+
appAllowedOrigins: readonly string[];
|
|
425
465
|
}>, ZodObject< {
|
|
426
466
|
token: ZodString;
|
|
427
467
|
code: ZodString;
|
|
@@ -450,7 +490,9 @@ declare const publicRouter: {
|
|
|
450
490
|
appId: string;
|
|
451
491
|
clientId: string | undefined;
|
|
452
492
|
hasActiveSubscription: boolean;
|
|
493
|
+
clientEntitlements: ClientEntitlements;
|
|
453
494
|
authMode: "dev-app";
|
|
495
|
+
appAllowedOrigins: readonly string[];
|
|
454
496
|
}>, ZodObject< {
|
|
455
497
|
token: ZodString;
|
|
456
498
|
code: ZodString;
|
|
@@ -479,7 +521,9 @@ declare const publicRouter: {
|
|
|
479
521
|
appId: string;
|
|
480
522
|
clientId: string | undefined;
|
|
481
523
|
hasActiveSubscription: boolean;
|
|
524
|
+
clientEntitlements: ClientEntitlements;
|
|
482
525
|
authMode: "dev-app";
|
|
526
|
+
appAllowedOrigins: readonly string[];
|
|
483
527
|
}>, ZodObject< {
|
|
484
528
|
token: ZodString;
|
|
485
529
|
}, $strip>, ZodObject< {
|
|
@@ -500,7 +544,9 @@ declare const publicRouter: {
|
|
|
500
544
|
appId: string;
|
|
501
545
|
clientId: string | undefined;
|
|
502
546
|
hasActiveSubscription: boolean;
|
|
547
|
+
clientEntitlements: ClientEntitlements;
|
|
503
548
|
authMode: "dev-app";
|
|
549
|
+
appAllowedOrigins: readonly string[];
|
|
504
550
|
}>, ZodObject< {
|
|
505
551
|
token: ZodString;
|
|
506
552
|
code: ZodString;
|
|
@@ -529,7 +575,9 @@ declare const publicRouter: {
|
|
|
529
575
|
appId: string;
|
|
530
576
|
clientId: string | undefined;
|
|
531
577
|
hasActiveSubscription: boolean;
|
|
578
|
+
clientEntitlements: ClientEntitlements;
|
|
532
579
|
authMode: "dev-app";
|
|
580
|
+
appAllowedOrigins: readonly string[];
|
|
533
581
|
}>, ZodOptional<ZodObject< {}, $strip>>, ZodObject< {
|
|
534
582
|
data: ZodObject< {
|
|
535
583
|
twoFactorEnabled: ZodBoolean;
|
|
@@ -551,6 +599,12 @@ declare const publicRouter: {
|
|
|
551
599
|
cursor: ZodOptional<ZodString>;
|
|
552
600
|
limit: ZodDefault<ZodCoercedNumber<unknown>>;
|
|
553
601
|
categoryId: ZodOptional<ZodString>;
|
|
602
|
+
q: ZodOptional<ZodString>;
|
|
603
|
+
difficulty: ZodOptional<ZodEnum< {
|
|
604
|
+
beginner: "beginner";
|
|
605
|
+
intermediate: "intermediate";
|
|
606
|
+
advanced: "advanced";
|
|
607
|
+
}>>;
|
|
554
608
|
}, $strip>, ZodObject< {
|
|
555
609
|
data: ZodArray<ZodObject< {
|
|
556
610
|
id: ZodString;
|
|
@@ -566,6 +620,12 @@ declare const publicRouter: {
|
|
|
566
620
|
published: "published";
|
|
567
621
|
archived: "archived";
|
|
568
622
|
}>;
|
|
623
|
+
durationMinutes: ZodNullable<ZodNumber>;
|
|
624
|
+
difficulty: ZodNullable<ZodEnum< {
|
|
625
|
+
beginner: "beginner";
|
|
626
|
+
intermediate: "intermediate";
|
|
627
|
+
advanced: "advanced";
|
|
628
|
+
}>>;
|
|
569
629
|
publishedAt: ZodNullable<ZodDate>;
|
|
570
630
|
videoAssetId: ZodNullable<ZodString>;
|
|
571
631
|
headerImageId: ZodNullable<ZodString>;
|
|
@@ -601,6 +661,12 @@ declare const publicRouter: {
|
|
|
601
661
|
published: "published";
|
|
602
662
|
archived: "archived";
|
|
603
663
|
}>;
|
|
664
|
+
durationMinutes: ZodNullable<ZodNumber>;
|
|
665
|
+
difficulty: ZodNullable<ZodEnum< {
|
|
666
|
+
beginner: "beginner";
|
|
667
|
+
intermediate: "intermediate";
|
|
668
|
+
advanced: "advanced";
|
|
669
|
+
}>>;
|
|
604
670
|
publishedAt: ZodNullable<ZodDate>;
|
|
605
671
|
videoAssetId: ZodNullable<ZodString>;
|
|
606
672
|
headerImageId: ZodNullable<ZodString>;
|
|
@@ -688,6 +754,12 @@ declare const publicRouter: {
|
|
|
688
754
|
published: "published";
|
|
689
755
|
archived: "archived";
|
|
690
756
|
}>;
|
|
757
|
+
durationMinutes: ZodNullable<ZodNumber>;
|
|
758
|
+
difficulty: ZodNullable<ZodEnum< {
|
|
759
|
+
beginner: "beginner";
|
|
760
|
+
intermediate: "intermediate";
|
|
761
|
+
advanced: "advanced";
|
|
762
|
+
}>>;
|
|
691
763
|
publishedAt: ZodNullable<ZodDate>;
|
|
692
764
|
videoAssetId: ZodNullable<ZodString>;
|
|
693
765
|
headerImageId: ZodNullable<ZodString>;
|
|
@@ -713,6 +785,12 @@ declare const publicRouter: {
|
|
|
713
785
|
published: "published";
|
|
714
786
|
archived: "archived";
|
|
715
787
|
}>;
|
|
788
|
+
durationMinutes: ZodNullable<ZodNumber>;
|
|
789
|
+
difficulty: ZodNullable<ZodEnum< {
|
|
790
|
+
beginner: "beginner";
|
|
791
|
+
intermediate: "intermediate";
|
|
792
|
+
advanced: "advanced";
|
|
793
|
+
}>>;
|
|
716
794
|
publishedAt: ZodNullable<ZodDate>;
|
|
717
795
|
videoAssetId: ZodNullable<ZodString>;
|
|
718
796
|
headerImageId: ZodNullable<ZodString>;
|
|
@@ -831,6 +909,252 @@ declare const publicRouter: {
|
|
|
831
909
|
}, $strip>;
|
|
832
910
|
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
833
911
|
};
|
|
912
|
+
nutritionLog: {
|
|
913
|
+
getDay: DecoratedProcedure<MergedInitialContext< {
|
|
914
|
+
headers: Headers;
|
|
915
|
+
} & Record<never, never>, {
|
|
916
|
+
headers: Headers;
|
|
917
|
+
} & Record<never, never>, {
|
|
918
|
+
headers: Headers;
|
|
919
|
+
}>, MergedCurrentContext< {
|
|
920
|
+
headers: Headers;
|
|
921
|
+
}, ApiKeyContext>, ZodObject< {
|
|
922
|
+
date: ZodString;
|
|
923
|
+
}, $strip>, ZodObject< {
|
|
924
|
+
data: ZodObject< {
|
|
925
|
+
date: ZodString;
|
|
926
|
+
targets: ZodNullable<ZodObject< {
|
|
927
|
+
calories: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
928
|
+
protein: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
929
|
+
carbs: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
930
|
+
fat: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
931
|
+
}, $strip>>;
|
|
932
|
+
totals: ZodObject< {
|
|
933
|
+
calories: ZodNumber;
|
|
934
|
+
protein: ZodNumber;
|
|
935
|
+
carbs: ZodNumber;
|
|
936
|
+
fat: ZodNumber;
|
|
937
|
+
}, $strip>;
|
|
938
|
+
entries: ZodArray<ZodObject< {
|
|
939
|
+
id: ZodString;
|
|
940
|
+
loggedFor: ZodString;
|
|
941
|
+
name: ZodString;
|
|
942
|
+
mealCategory: ZodNullable<ZodEnum< {
|
|
943
|
+
breakfast: "breakfast";
|
|
944
|
+
lunch: "lunch";
|
|
945
|
+
dinner: "dinner";
|
|
946
|
+
snack: "snack";
|
|
947
|
+
}>>;
|
|
948
|
+
recipeId: ZodNullable<ZodString>;
|
|
949
|
+
calories: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
950
|
+
protein: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
951
|
+
carbs: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
952
|
+
fat: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
953
|
+
createdAt: ZodDate;
|
|
954
|
+
}, $strip>>;
|
|
955
|
+
}, $strip>;
|
|
956
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
957
|
+
logFood: DecoratedProcedure<MergedInitialContext< {
|
|
958
|
+
headers: Headers;
|
|
959
|
+
} & Record<never, never>, {
|
|
960
|
+
headers: Headers;
|
|
961
|
+
} & Record<never, never>, {
|
|
962
|
+
headers: Headers;
|
|
963
|
+
}>, MergedCurrentContext< {
|
|
964
|
+
headers: Headers;
|
|
965
|
+
}, ApiKeyContext>, ZodObject< {
|
|
966
|
+
loggedFor: ZodString;
|
|
967
|
+
name: ZodString;
|
|
968
|
+
mealCategory: ZodOptional<ZodEnum< {
|
|
969
|
+
breakfast: "breakfast";
|
|
970
|
+
lunch: "lunch";
|
|
971
|
+
dinner: "dinner";
|
|
972
|
+
snack: "snack";
|
|
973
|
+
}>>;
|
|
974
|
+
recipeId: ZodOptional<ZodString>;
|
|
975
|
+
calories: ZodOptional<ZodNullable<ZodNumber>>;
|
|
976
|
+
protein: ZodOptional<ZodNullable<ZodNumber>>;
|
|
977
|
+
carbs: ZodOptional<ZodNullable<ZodNumber>>;
|
|
978
|
+
fat: ZodOptional<ZodNullable<ZodNumber>>;
|
|
979
|
+
}, $strip>, ZodObject< {
|
|
980
|
+
data: ZodObject< {
|
|
981
|
+
id: ZodString;
|
|
982
|
+
loggedFor: ZodString;
|
|
983
|
+
name: ZodString;
|
|
984
|
+
mealCategory: ZodNullable<ZodEnum< {
|
|
985
|
+
breakfast: "breakfast";
|
|
986
|
+
lunch: "lunch";
|
|
987
|
+
dinner: "dinner";
|
|
988
|
+
snack: "snack";
|
|
989
|
+
}>>;
|
|
990
|
+
recipeId: ZodNullable<ZodString>;
|
|
991
|
+
calories: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
992
|
+
protein: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
993
|
+
carbs: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
994
|
+
fat: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
995
|
+
createdAt: ZodDate;
|
|
996
|
+
}, $strip>;
|
|
997
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
998
|
+
updateFood: DecoratedProcedure<MergedInitialContext< {
|
|
999
|
+
headers: Headers;
|
|
1000
|
+
} & Record<never, never>, {
|
|
1001
|
+
headers: Headers;
|
|
1002
|
+
} & Record<never, never>, {
|
|
1003
|
+
headers: Headers;
|
|
1004
|
+
}>, MergedCurrentContext< {
|
|
1005
|
+
headers: Headers;
|
|
1006
|
+
}, ApiKeyContext>, ZodObject< {
|
|
1007
|
+
name: ZodOptional<ZodString>;
|
|
1008
|
+
mealCategory: ZodOptional<ZodNullable<ZodEnum< {
|
|
1009
|
+
breakfast: "breakfast";
|
|
1010
|
+
lunch: "lunch";
|
|
1011
|
+
dinner: "dinner";
|
|
1012
|
+
snack: "snack";
|
|
1013
|
+
}>>>;
|
|
1014
|
+
calories: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1015
|
+
protein: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1016
|
+
carbs: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1017
|
+
fat: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1018
|
+
id: ZodString;
|
|
1019
|
+
}, $strip>, ZodObject< {
|
|
1020
|
+
data: ZodObject< {
|
|
1021
|
+
id: ZodString;
|
|
1022
|
+
loggedFor: ZodString;
|
|
1023
|
+
name: ZodString;
|
|
1024
|
+
mealCategory: ZodNullable<ZodEnum< {
|
|
1025
|
+
breakfast: "breakfast";
|
|
1026
|
+
lunch: "lunch";
|
|
1027
|
+
dinner: "dinner";
|
|
1028
|
+
snack: "snack";
|
|
1029
|
+
}>>;
|
|
1030
|
+
recipeId: ZodNullable<ZodString>;
|
|
1031
|
+
calories: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1032
|
+
protein: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1033
|
+
carbs: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1034
|
+
fat: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1035
|
+
createdAt: ZodDate;
|
|
1036
|
+
}, $strip>;
|
|
1037
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1038
|
+
deleteFood: DecoratedProcedure<MergedInitialContext< {
|
|
1039
|
+
headers: Headers;
|
|
1040
|
+
} & Record<never, never>, {
|
|
1041
|
+
headers: Headers;
|
|
1042
|
+
} & Record<never, never>, {
|
|
1043
|
+
headers: Headers;
|
|
1044
|
+
}>, MergedCurrentContext< {
|
|
1045
|
+
headers: Headers;
|
|
1046
|
+
}, ApiKeyContext>, ZodObject< {
|
|
1047
|
+
id: ZodString;
|
|
1048
|
+
}, $strip>, ZodObject< {
|
|
1049
|
+
data: ZodObject< {
|
|
1050
|
+
id: ZodString;
|
|
1051
|
+
deleted: ZodLiteral<true>;
|
|
1052
|
+
}, $strip>;
|
|
1053
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1054
|
+
setTargets: DecoratedProcedure<MergedInitialContext< {
|
|
1055
|
+
headers: Headers;
|
|
1056
|
+
} & Record<never, never>, {
|
|
1057
|
+
headers: Headers;
|
|
1058
|
+
} & Record<never, never>, {
|
|
1059
|
+
headers: Headers;
|
|
1060
|
+
}>, MergedCurrentContext< {
|
|
1061
|
+
headers: Headers;
|
|
1062
|
+
}, ApiKeyContext>, ZodObject< {
|
|
1063
|
+
calories: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1064
|
+
protein: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1065
|
+
carbs: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1066
|
+
fat: ZodOptional<ZodNullable<ZodNumber>>;
|
|
1067
|
+
}, $strip>, ZodObject< {
|
|
1068
|
+
data: ZodNullable<ZodObject< {
|
|
1069
|
+
calories: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1070
|
+
protein: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1071
|
+
carbs: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1072
|
+
fat: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1073
|
+
}, $strip>>;
|
|
1074
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1075
|
+
};
|
|
1076
|
+
profile: {
|
|
1077
|
+
get: DecoratedProcedure<MergedInitialContext< {
|
|
1078
|
+
headers: Headers;
|
|
1079
|
+
} & Record<never, never>, {
|
|
1080
|
+
headers: Headers;
|
|
1081
|
+
} & Record<never, never>, {
|
|
1082
|
+
headers: Headers;
|
|
1083
|
+
}>, MergedCurrentContext< {
|
|
1084
|
+
headers: Headers;
|
|
1085
|
+
}, ApiKeyContext>, Schema<unknown, unknown>, ZodObject< {
|
|
1086
|
+
data: ZodObject< {
|
|
1087
|
+
id: ZodString;
|
|
1088
|
+
name: ZodString;
|
|
1089
|
+
email: ZodString;
|
|
1090
|
+
avatarUrl: ZodNullable<ZodString>;
|
|
1091
|
+
weightUnit: ZodEnum< {
|
|
1092
|
+
kg: "kg";
|
|
1093
|
+
lb: "lb";
|
|
1094
|
+
}>;
|
|
1095
|
+
timezone: ZodNullable<ZodString>;
|
|
1096
|
+
fitnessGoal: ZodNullable<ZodEnum< {
|
|
1097
|
+
lose_fat: "lose_fat";
|
|
1098
|
+
build_muscle: "build_muscle";
|
|
1099
|
+
get_strong: "get_strong";
|
|
1100
|
+
stay_consistent: "stay_consistent";
|
|
1101
|
+
}>>;
|
|
1102
|
+
macroTargets: ZodNullable<ZodObject< {
|
|
1103
|
+
calories: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1104
|
+
protein: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1105
|
+
carbs: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1106
|
+
fat: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1107
|
+
}, $strip>>;
|
|
1108
|
+
}, $strip>;
|
|
1109
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1110
|
+
update: DecoratedProcedure<MergedInitialContext< {
|
|
1111
|
+
headers: Headers;
|
|
1112
|
+
} & Record<never, never>, {
|
|
1113
|
+
headers: Headers;
|
|
1114
|
+
} & Record<never, never>, {
|
|
1115
|
+
headers: Headers;
|
|
1116
|
+
}>, MergedCurrentContext< {
|
|
1117
|
+
headers: Headers;
|
|
1118
|
+
}, ApiKeyContext>, ZodObject< {
|
|
1119
|
+
name: ZodOptional<ZodString>;
|
|
1120
|
+
avatarUrl: ZodOptional<ZodNullable<ZodString>>;
|
|
1121
|
+
timezone: ZodOptional<ZodNullable<ZodString>>;
|
|
1122
|
+
weightUnit: ZodOptional<ZodEnum< {
|
|
1123
|
+
kg: "kg";
|
|
1124
|
+
lb: "lb";
|
|
1125
|
+
}>>;
|
|
1126
|
+
fitnessGoal: ZodOptional<ZodNullable<ZodEnum< {
|
|
1127
|
+
lose_fat: "lose_fat";
|
|
1128
|
+
build_muscle: "build_muscle";
|
|
1129
|
+
get_strong: "get_strong";
|
|
1130
|
+
stay_consistent: "stay_consistent";
|
|
1131
|
+
}>>>;
|
|
1132
|
+
}, $strip>, ZodObject< {
|
|
1133
|
+
data: ZodObject< {
|
|
1134
|
+
id: ZodString;
|
|
1135
|
+
name: ZodString;
|
|
1136
|
+
email: ZodString;
|
|
1137
|
+
avatarUrl: ZodNullable<ZodString>;
|
|
1138
|
+
weightUnit: ZodEnum< {
|
|
1139
|
+
kg: "kg";
|
|
1140
|
+
lb: "lb";
|
|
1141
|
+
}>;
|
|
1142
|
+
timezone: ZodNullable<ZodString>;
|
|
1143
|
+
fitnessGoal: ZodNullable<ZodEnum< {
|
|
1144
|
+
lose_fat: "lose_fat";
|
|
1145
|
+
build_muscle: "build_muscle";
|
|
1146
|
+
get_strong: "get_strong";
|
|
1147
|
+
stay_consistent: "stay_consistent";
|
|
1148
|
+
}>>;
|
|
1149
|
+
macroTargets: ZodNullable<ZodObject< {
|
|
1150
|
+
calories: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1151
|
+
protein: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1152
|
+
carbs: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1153
|
+
fat: ZodNullable<ZodCoercedNumber<unknown>>;
|
|
1154
|
+
}, $strip>>;
|
|
1155
|
+
}, $strip>;
|
|
1156
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1157
|
+
};
|
|
834
1158
|
article: {
|
|
835
1159
|
list: DecoratedProcedure<MergedInitialContext< {
|
|
836
1160
|
headers: Headers;
|
|
@@ -916,6 +1240,7 @@ declare const publicRouter: {
|
|
|
916
1240
|
dinner: "dinner";
|
|
917
1241
|
snack: "snack";
|
|
918
1242
|
}>>;
|
|
1243
|
+
q: ZodOptional<ZodString>;
|
|
919
1244
|
}, $strip>, ZodObject< {
|
|
920
1245
|
data: ZodArray<ZodObject< {
|
|
921
1246
|
id: ZodString;
|
|
@@ -1495,12 +1820,14 @@ declare const publicRouter: {
|
|
|
1495
1820
|
}, ApiKeyContext>, ZodObject< {
|
|
1496
1821
|
programId: ZodOptional<ZodString>;
|
|
1497
1822
|
sessionId: ZodOptional<ZodString>;
|
|
1823
|
+
workoutId: ZodOptional<ZodString>;
|
|
1498
1824
|
completed: ZodOptional<ZodBoolean>;
|
|
1499
1825
|
}, $strip>, ZodObject< {
|
|
1500
1826
|
data: ZodArray<ZodObject< {
|
|
1501
1827
|
id: ZodString;
|
|
1502
|
-
enrollmentId: ZodString
|
|
1503
|
-
sessionId: ZodString
|
|
1828
|
+
enrollmentId: ZodNullable<ZodString>;
|
|
1829
|
+
sessionId: ZodNullable<ZodString>;
|
|
1830
|
+
workoutId: ZodNullable<ZodString>;
|
|
1504
1831
|
startedAt: ZodString;
|
|
1505
1832
|
completedAt: ZodNullable<ZodString>;
|
|
1506
1833
|
overallRpe: ZodNullable<ZodNumber>;
|
|
@@ -1525,13 +1852,15 @@ declare const publicRouter: {
|
|
|
1525
1852
|
}>, MergedCurrentContext< {
|
|
1526
1853
|
headers: Headers;
|
|
1527
1854
|
}, ApiKeyContext>, ZodObject< {
|
|
1528
|
-
sessionId: ZodString
|
|
1529
|
-
enrollmentId: ZodString
|
|
1855
|
+
sessionId: ZodOptional<ZodString>;
|
|
1856
|
+
enrollmentId: ZodOptional<ZodString>;
|
|
1857
|
+
workoutId: ZodOptional<ZodString>;
|
|
1530
1858
|
}, $strip>, Schema< {
|
|
1531
1859
|
data: {
|
|
1532
1860
|
id: string;
|
|
1533
|
-
enrollmentId: string;
|
|
1534
|
-
sessionId: string;
|
|
1861
|
+
enrollmentId: string | null;
|
|
1862
|
+
sessionId: string | null;
|
|
1863
|
+
workoutId: string | null;
|
|
1535
1864
|
startedAt: string;
|
|
1536
1865
|
completedAt: string | null;
|
|
1537
1866
|
overallRpe: number | null;
|
|
@@ -1541,8 +1870,9 @@ declare const publicRouter: {
|
|
|
1541
1870
|
}, {
|
|
1542
1871
|
data: {
|
|
1543
1872
|
id: string;
|
|
1544
|
-
enrollmentId: string;
|
|
1545
|
-
sessionId: string;
|
|
1873
|
+
enrollmentId: string | null;
|
|
1874
|
+
sessionId: string | null;
|
|
1875
|
+
workoutId: string | null;
|
|
1546
1876
|
startedAt: string;
|
|
1547
1877
|
completedAt: string | null;
|
|
1548
1878
|
overallRpe: number | null;
|
|
@@ -1566,8 +1896,9 @@ declare const publicRouter: {
|
|
|
1566
1896
|
}, $strip>, Schema< {
|
|
1567
1897
|
data: {
|
|
1568
1898
|
id: string;
|
|
1569
|
-
enrollmentId: string;
|
|
1570
|
-
sessionId: string;
|
|
1899
|
+
enrollmentId: string | null;
|
|
1900
|
+
sessionId: string | null;
|
|
1901
|
+
workoutId: string | null;
|
|
1571
1902
|
startedAt: string;
|
|
1572
1903
|
completedAt: string | null;
|
|
1573
1904
|
overallRpe: number | null;
|
|
@@ -1585,8 +1916,9 @@ declare const publicRouter: {
|
|
|
1585
1916
|
}, {
|
|
1586
1917
|
data: {
|
|
1587
1918
|
id: string;
|
|
1588
|
-
enrollmentId: string;
|
|
1589
|
-
sessionId: string;
|
|
1919
|
+
enrollmentId: string | null;
|
|
1920
|
+
sessionId: string | null;
|
|
1921
|
+
workoutId: string | null;
|
|
1590
1922
|
startedAt: string;
|
|
1591
1923
|
completedAt: string | null;
|
|
1592
1924
|
overallRpe: number | null;
|
|
@@ -1761,6 +2093,29 @@ declare const publicRouter: {
|
|
|
1761
2093
|
computedAt: ZodString;
|
|
1762
2094
|
}, $strip>;
|
|
1763
2095
|
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
2096
|
+
listPrHistory: DecoratedProcedure<MergedInitialContext< {
|
|
2097
|
+
headers: Headers;
|
|
2098
|
+
} & Record<never, never>, {
|
|
2099
|
+
headers: Headers;
|
|
2100
|
+
} & Record<never, never>, {
|
|
2101
|
+
headers: Headers;
|
|
2102
|
+
}>, MergedCurrentContext< {
|
|
2103
|
+
headers: Headers;
|
|
2104
|
+
}, ApiKeyContext>, ZodObject< {
|
|
2105
|
+
exerciseId: ZodOptional<ZodString>;
|
|
2106
|
+
limit: ZodDefault<ZodCoercedNumber<unknown>>;
|
|
2107
|
+
}, $strip>, ZodObject< {
|
|
2108
|
+
data: ZodArray<ZodObject< {
|
|
2109
|
+
id: ZodString;
|
|
2110
|
+
exerciseId: ZodString;
|
|
2111
|
+
exerciseName: ZodString;
|
|
2112
|
+
sessionLogId: ZodString;
|
|
2113
|
+
weightKg: ZodString;
|
|
2114
|
+
reps: ZodNumber;
|
|
2115
|
+
estimated1Rm: ZodString;
|
|
2116
|
+
achievedAt: ZodString;
|
|
2117
|
+
}, $strip>>;
|
|
2118
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1764
2119
|
};
|
|
1765
2120
|
bodyMetric: {
|
|
1766
2121
|
list: DecoratedProcedure<MergedInitialContext< {
|
|
@@ -1888,6 +2243,21 @@ declare const publicRouter: {
|
|
|
1888
2243
|
}, $strip>>;
|
|
1889
2244
|
}, $strip>;
|
|
1890
2245
|
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
2246
|
+
getStreak: DecoratedProcedure<MergedInitialContext< {
|
|
2247
|
+
headers: Headers;
|
|
2248
|
+
} & Record<never, never>, {
|
|
2249
|
+
headers: Headers;
|
|
2250
|
+
} & Record<never, never>, {
|
|
2251
|
+
headers: Headers;
|
|
2252
|
+
}>, MergedCurrentContext< {
|
|
2253
|
+
headers: Headers;
|
|
2254
|
+
}, ApiKeyContext>, ZodObject< {}, $strip>, ZodObject< {
|
|
2255
|
+
data: ZodObject< {
|
|
2256
|
+
currentStreakDays: ZodNumber;
|
|
2257
|
+
longestStreakDays: ZodNumber;
|
|
2258
|
+
lastWorkoutAt: ZodNullable<ZodString>;
|
|
2259
|
+
}, $strip>;
|
|
2260
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1891
2261
|
};
|
|
1892
2262
|
media: {
|
|
1893
2263
|
get: DecoratedProcedure<MergedInitialContext< {
|
|
@@ -1960,11 +2330,25 @@ declare const publicRouter: {
|
|
|
1960
2330
|
data: ZodObject< {
|
|
1961
2331
|
currency: ZodString;
|
|
1962
2332
|
plans: ZodArray<ZodObject< {
|
|
2333
|
+
id: ZodString;
|
|
1963
2334
|
name: ZodString;
|
|
1964
2335
|
monthlyPriceCents: ZodNumber;
|
|
2336
|
+
annualPriceCents: ZodNullable<ZodNumber>;
|
|
2337
|
+
hasAnnualStripe: ZodBoolean;
|
|
2338
|
+
trialDays: ZodNullable<ZodNumber>;
|
|
1965
2339
|
description: ZodString;
|
|
1966
2340
|
sortOrder: ZodNumber;
|
|
1967
2341
|
hasStripe: ZodBoolean;
|
|
2342
|
+
entitlements: ZodArray<ZodObject< {
|
|
2343
|
+
code: ZodEnum< {
|
|
2344
|
+
premium_workouts: "premium_workouts";
|
|
2345
|
+
premium_programs: "premium_programs";
|
|
2346
|
+
premium_nutrition: "premium_nutrition";
|
|
2347
|
+
premium_recipes: "premium_recipes";
|
|
2348
|
+
premium_articles: "premium_articles";
|
|
2349
|
+
}>;
|
|
2350
|
+
label: ZodString;
|
|
2351
|
+
}, $strip>>;
|
|
1968
2352
|
}, $strip>>;
|
|
1969
2353
|
}, $strip>;
|
|
1970
2354
|
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
@@ -1985,6 +2369,8 @@ declare const publicRouter: {
|
|
|
1985
2369
|
premium: "premium";
|
|
1986
2370
|
basic: "basic";
|
|
1987
2371
|
}>;
|
|
2372
|
+
planId: ZodNullable<ZodString>;
|
|
2373
|
+
planName: ZodNullable<ZodString>;
|
|
1988
2374
|
status: ZodEnum< {
|
|
1989
2375
|
active: "active";
|
|
1990
2376
|
cancelled: "cancelled";
|
|
@@ -1993,6 +2379,48 @@ declare const publicRouter: {
|
|
|
1993
2379
|
startedAt: ZodNullable<ZodDate>;
|
|
1994
2380
|
expiresAt: ZodNullable<ZodDate>;
|
|
1995
2381
|
}, $strip>>;
|
|
2382
|
+
entitlements: ZodUnion<readonly [ZodLiteral<"all">, ZodArray<ZodEnum< {
|
|
2383
|
+
premium_workouts: "premium_workouts";
|
|
2384
|
+
premium_programs: "premium_programs";
|
|
2385
|
+
premium_nutrition: "premium_nutrition";
|
|
2386
|
+
premium_recipes: "premium_recipes";
|
|
2387
|
+
premium_articles: "premium_articles";
|
|
2388
|
+
}>>]>;
|
|
2389
|
+
}, $strip>;
|
|
2390
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
2391
|
+
createCheckout: DecoratedProcedure<MergedInitialContext< {
|
|
2392
|
+
headers: Headers;
|
|
2393
|
+
} & Record<never, never>, {
|
|
2394
|
+
headers: Headers;
|
|
2395
|
+
} & Record<never, never>, {
|
|
2396
|
+
headers: Headers;
|
|
2397
|
+
}>, MergedCurrentContext< {
|
|
2398
|
+
headers: Headers;
|
|
2399
|
+
}, ApiKeyContext>, ZodObject< {
|
|
2400
|
+
planId: ZodString;
|
|
2401
|
+
interval: ZodDefault<ZodEnum< {
|
|
2402
|
+
monthly: "monthly";
|
|
2403
|
+
annual: "annual";
|
|
2404
|
+
}>>;
|
|
2405
|
+
returnUrl: ZodOptional<ZodString>;
|
|
2406
|
+
}, $strip>, ZodObject< {
|
|
2407
|
+
data: ZodObject< {
|
|
2408
|
+
url: ZodString;
|
|
2409
|
+
}, $strip>;
|
|
2410
|
+
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
2411
|
+
createPortal: DecoratedProcedure<MergedInitialContext< {
|
|
2412
|
+
headers: Headers;
|
|
2413
|
+
} & Record<never, never>, {
|
|
2414
|
+
headers: Headers;
|
|
2415
|
+
} & Record<never, never>, {
|
|
2416
|
+
headers: Headers;
|
|
2417
|
+
}>, MergedCurrentContext< {
|
|
2418
|
+
headers: Headers;
|
|
2419
|
+
}, ApiKeyContext>, ZodObject< {
|
|
2420
|
+
returnUrl: ZodOptional<ZodString>;
|
|
2421
|
+
}, $strip>, ZodObject< {
|
|
2422
|
+
data: ZodObject< {
|
|
2423
|
+
url: ZodString;
|
|
1996
2424
|
}, $strip>;
|
|
1997
2425
|
}, $strip>, Record<never, never>, Record<never, never>>;
|
|
1998
2426
|
};
|
package/dist/index.js
CHANGED
|
@@ -246,7 +246,9 @@ function createDataNamespaces(transport) {
|
|
|
246
246
|
progress: wrapSlice(c.progress),
|
|
247
247
|
media: wrapSlice(c.media),
|
|
248
248
|
appConfig: wrapSlice(c.appConfig),
|
|
249
|
-
subscription: wrapSlice(c.subscription)
|
|
249
|
+
subscription: wrapSlice(c.subscription),
|
|
250
|
+
profile: wrapSlice(c.profile),
|
|
251
|
+
nutritionLog: wrapSlice(c.nutritionLog)
|
|
250
252
|
};
|
|
251
253
|
}
|
|
252
254
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/error.ts","../src/events.ts","../src/auth.ts","../src/data.ts","../src/storage.ts","../src/transport.ts","../src/index.ts"],"names":["cached"],"mappings":"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","file":"index.js","sourcesContent":["import { ORPCError } from \"@orpc/client\";\nimport type { FytkitError } from \"./types\";\n\ninterface MaybeIssuesData {\n issues?: readonly unknown[];\n}\ninterface MaybeRetryAfterData {\n retryAfterMs?: number;\n}\n\nfunction pickIssues(data: unknown): readonly unknown[] | null {\n if (!data || typeof data !== \"object\") return null;\n const issues = (data as MaybeIssuesData).issues;\n return Array.isArray(issues) ? issues : null;\n}\n\nfunction pickRetryAfter(data: unknown): number {\n if (!data || typeof data !== \"object\") return 0;\n const raw = (data as MaybeRetryAfterData).retryAfterMs;\n return typeof raw === \"number\" && raw >= 0 ? raw : 0;\n}\n\n/**\n * Map any error thrown by `@orpc/client` (or the underlying fetch) into the\n * SDK's `FytkitError` discriminated union. The SDK never re-throws raw orpc\n * or network errors at the public surface.\n */\nexport function normalizeError(err: unknown): FytkitError {\n // Network failures from fetch surface as TypeError.\n if (err instanceof TypeError) return { kind: \"network\" };\n\n if (err instanceof ORPCError) {\n const code = err.code;\n const status = err.status;\n const data: unknown = err.data;\n const message = err.message;\n\n switch (code) {\n case \"UNAUTHORIZED\":\n // Carry the server's reason (e.g. \"Invalid credentials\" on a failed\n // sign-in) so the consumer can show it instead of a generic\n // 'session expired' copy. The synthetic no-session case in auth.ts\n // is built directly and stays message-less.\n return { kind: \"auth_required\", message };\n case \"FORBIDDEN\":\n return { kind: \"forbidden\", reason: message || \"Forbidden\" };\n case \"CONFLICT\":\n return { kind: \"conflict\", message: message || \"Conflict\" };\n case \"NOT_FOUND\":\n return { kind: \"not_found\" };\n case \"TOO_MANY_REQUESTS\":\n return { kind: \"rate_limited\", retryAfter: pickRetryAfter(data) };\n case \"BAD_REQUEST\":\n case \"UNPROCESSABLE_CONTENT\": {\n const issues = pickIssues(data);\n if (issues) return { kind: \"validation\", issues };\n // No structured issues — still carry the server's explanation so it\n // isn't dropped into a bare status code.\n return { kind: \"server\", status, message };\n }\n default:\n return { kind: \"server\", status, message };\n }\n }\n\n return { kind: \"server\", status: 0 };\n}\n","export interface EventBus<T> {\n readonly on: (listener: (value: T) => void) => () => void;\n readonly emit: (value: T) => void;\n}\n\nexport function createEventBus<T>(): EventBus<T> {\n const listeners = new Set<(value: T) => void>();\n return {\n on: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n emit: (value) => {\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (err) {\n // A buggy listener must not break siblings or the calling flow.\n console.error(\"[fytkit-sdk] event listener threw\", err);\n }\n }\n },\n };\n}\n","import { normalizeError } from \"./error\";\nimport { createEventBus } from \"./events\";\nimport type { Transport } from \"./transport\";\nimport type { AuthState, FytkitError, Session, SignInResult, TokenStorage, TwoFactorToken } from \"./types\";\n\nexport interface AuthNamespaceOptions {\n readonly transport: Transport;\n readonly storage: TokenStorage;\n /** Called after the SDK signs out for any reason (manual, refresh failure). */\n readonly onSignedOut?: () => void;\n}\n\nexport interface AuthNamespace {\n readonly signUp: (input: { email: string; password: string; name: string }) => Promise<Session>;\n readonly signIn: (input: { email: string; password: string }) => Promise<SignInResult>;\n readonly signOut: () => Promise<void>;\n readonly getSession: () => Session | null;\n readonly onAuthStateChange: (listener: (state: AuthState) => void) => () => void;\n readonly requestPasswordReset: (input: { email: string }) => Promise<void>;\n readonly confirmPasswordReset: (input: { token: string; password: string }) => Promise<void>;\n readonly confirmEmail: (input: { token: string }) => Promise<void>;\n /** Internal: force a refresh now. Wired by transport's 401 retry path. */\n readonly _refresh: () => Promise<Session>;\n /** Internal: clear cached session + emit signed_out. */\n readonly _signOutLocal: () => void;\n}\n\n/**\n * Schedule a proactive refresh this many ms before `expiresAt`. The\n * server-side access-token TTL is ~15 min so a 60-second lead time gives\n * us enough headroom to refresh transparently without burning sessions\n * needlessly while keeping the user signed-in across long-running tabs.\n */\nconst PROACTIVE_REFRESH_LEAD_MS = 60_000;\n\n/**\n * The auth namespace owns the cached session. It is the single writer to\n * `storage`; everything else reads via `getSession`. Calls that mutate\n * the session also emit on the event bus and (re)schedule the proactive\n * refresh timer against the new expiry.\n */\nexport function createAuthNamespace(opts: AuthNamespaceOptions): AuthNamespace {\n const bus = createEventBus<AuthState>();\n let cached: Session | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n // Forward declaration so scheduleRefresh can call the same _refresh body\n // the public surface exposes. Assigned at the bottom of the factory.\n let refreshFn: () => Promise<Session> = () => {\n throw new Error(\"refreshFn called before initialization\");\n };\n\n function clearTimer(): void {\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n }\n\n // `setTimeout` clamps any delay > 2^31-1 ms (~24.8 days) to 1 ms and\n // prints a Node deprecation warning. Sessions with an exotic far-future\n // expiry (test fixtures, mis-configured server) would otherwise fire the\n // timer instantly; cap the delay to the safe upper bound so the timer\n // simply re-arms on its next firing.\n const MAX_TIMEOUT_MS = 2_147_483_647;\n\n function scheduleRefresh(session: Session): void {\n clearTimer();\n const expiresMs = new Date(session.expiresAt).getTime();\n if (Number.isNaN(expiresMs)) return; // bad date — bail; reactive 401 path will handle it\n const rawDelay = expiresMs - Date.now() - PROACTIVE_REFRESH_LEAD_MS;\n const delay = Math.min(MAX_TIMEOUT_MS, Math.max(0, rawDelay));\n timer = setTimeout(() => {\n timer = null;\n void refreshFn().catch(() => {\n // refreshFn already handles sign-out on failure.\n });\n }, delay);\n }\n\n function applySession(session: Session, event: \"signed_in\" | \"session_refreshed\"): Session {\n cached = session;\n void opts.storage.set(session);\n bus.emit({ type: event, session });\n scheduleRefresh(session);\n return session;\n }\n\n function clearSession(emit = true): void {\n cached = null;\n clearTimer();\n void opts.storage.remove();\n if (emit) bus.emit({ type: \"signed_out\" });\n opts.onSignedOut?.();\n }\n\n async function call<T>(thunk: () => Promise<T>): Promise<T> {\n try {\n return await thunk();\n } catch (err) {\n throw normalizeError(err);\n }\n }\n\n // Best-effort hydrate at construction. If the storage already holds a\n // session (warm reload, second tab), restore it and arm the timer.\n void Promise.resolve(opts.storage.get()).then((s) => {\n if (s) {\n cached = s;\n scheduleRefresh(s);\n }\n });\n\n const signUp: AuthNamespace[\"signUp\"] = async (input) => {\n const result = await call(() => opts.transport.client.auth.signUp(input));\n const { user, session } = result.data;\n return applySession(\n { accessToken: session.accessToken, expiresAt: session.expiresAt, user },\n \"signed_in\",\n );\n };\n\n const signIn: AuthNamespace[\"signIn\"] = async (input) => {\n const result = await call(() => opts.transport.client.auth.signIn(input));\n if (result.data.kind === \"two_factor_required\") {\n // Mint the branded token exactly once at the network boundary.\n const token = result.data.twoFactorToken as TwoFactorToken;\n return {\n kind: \"two_factor_required\",\n challenge: { token, availableMethods: result.data.availableMethods },\n };\n }\n if (result.data.kind === \"signed_in\") {\n const { user, session } = result.data;\n const cached = applySession(\n { accessToken: session.accessToken, expiresAt: session.expiresAt, user },\n \"signed_in\",\n );\n return { kind: \"signed_in\", session: cached };\n }\n // Exhaustiveness guard — a future server-side variant must not silently fall through.\n const _exhaustive: never = result.data;\n throw _exhaustive;\n };\n\n const signOut: AuthNamespace[\"signOut\"] = async () => {\n const current = cached;\n if (!current) return;\n try {\n await opts.transport.client.auth.signOut({ token: current.accessToken });\n } catch (err) {\n // Even if the server rejects (e.g. token already revoked), clear\n // the local cache so the user is signed out client-side.\n void err;\n }\n clearSession();\n };\n\n const getSession: AuthNamespace[\"getSession\"] = () => cached;\n const onAuthStateChange: AuthNamespace[\"onAuthStateChange\"] = (listener) => bus.on(listener);\n\n const requestPasswordReset: AuthNamespace[\"requestPasswordReset\"] = async (input) => {\n await call(() => opts.transport.client.auth.requestPasswordReset(input));\n };\n const confirmPasswordReset: AuthNamespace[\"confirmPasswordReset\"] = async (input) => {\n await call(() => opts.transport.client.auth.confirmPasswordReset(input));\n };\n const confirmEmail: AuthNamespace[\"confirmEmail\"] = async (input) => {\n await call(() => opts.transport.client.auth.confirmEmail(input));\n };\n\n const _refresh: AuthNamespace[\"_refresh\"] = async () => {\n // Re-read storage as a fallback so a session written after\n // construction (e.g. on tab restore or in tests) is honoured.\n let current = cached;\n if (!current) {\n const fromStorage = await Promise.resolve(opts.storage.get());\n if (fromStorage) {\n cached = fromStorage;\n current = fromStorage;\n }\n }\n if (!current) {\n const err: FytkitError = { kind: \"auth_required\" };\n throw err;\n }\n try {\n const result = await opts.transport.client.auth.refresh({ token: current.accessToken });\n const { user, session } = result.data;\n return applySession(\n { accessToken: session.accessToken, expiresAt: session.expiresAt, user },\n \"session_refreshed\",\n );\n } catch (err) {\n clearSession();\n throw normalizeError(err);\n }\n };\n\n const _signOutLocal: AuthNamespace[\"_signOutLocal\"] = () => clearSession();\n\n refreshFn = _refresh;\n\n return {\n signUp,\n signIn,\n signOut,\n getSession,\n onAuthStateChange,\n requestPasswordReset,\n confirmPasswordReset,\n confirmEmail,\n _refresh,\n _signOutLocal,\n };\n}\n","import { normalizeError } from \"./error\";\nimport type { Transport } from \"./transport\";\n\n/**\n * Wrap every method on a public-router slice so thrown ORPCErrors become\n * normalised FytkitErrors at the SDK boundary.\n *\n * The slice we receive is an `@orpc/client` Proxy whose own keys are not\n * enumerable — every property lookup is intercepted lazily. We mirror that\n * shape by returning a Proxy of our own that wraps each function on first\n * access and caches the result. This way the SDK never needs to know the\n * method names ahead of time, and the typed shape from the server router\n * flows through unchanged.\n */\nfunction wrapSlice<T extends object>(slice: T): T {\n const cache = new Map<string | symbol, unknown>();\n return new Proxy(slice, {\n get(target, prop, receiver) {\n if (cache.has(prop)) return cache.get(prop);\n const value = Reflect.get(target, prop, receiver);\n if (typeof value !== \"function\") {\n // Allow nested namespaces to flow through unchanged (the orpc\n // proxy returns another proxy here, not a plain object).\n return value;\n }\n const wrapped = async (...args: unknown[]) => {\n try {\n return await (value as (...a: unknown[]) => Promise<unknown>)(...args);\n } catch (err) {\n throw normalizeError(err);\n }\n };\n cache.set(prop, wrapped);\n return wrapped;\n },\n }) as T;\n}\n\nexport interface DataNamespaces {\n readonly workouts: Transport[\"client\"][\"workout\"];\n readonly programs: Transport[\"client\"][\"program\"];\n readonly recipes: Transport[\"client\"][\"recipe\"];\n readonly nutrition: Transport[\"client\"][\"nutrition\"];\n readonly articles: Transport[\"client\"][\"article\"];\n readonly enrollments: Transport[\"client\"][\"enrollment\"];\n readonly sessionLogs: Transport[\"client\"][\"sessionLog\"];\n readonly progression: Transport[\"client\"][\"progression\"];\n readonly bodyMetrics: Transport[\"client\"][\"bodyMetric\"];\n readonly progress: Transport[\"client\"][\"progress\"];\n readonly media: Transport[\"client\"][\"media\"];\n readonly appConfig: Transport[\"client\"][\"appConfig\"];\n readonly subscription: Transport[\"client\"][\"subscription\"];\n}\n\nexport function createDataNamespaces(transport: Transport): DataNamespaces {\n const c = transport.client;\n return {\n workouts: wrapSlice(c.workout),\n programs: wrapSlice(c.program),\n recipes: wrapSlice(c.recipe),\n nutrition: wrapSlice(c.nutrition),\n articles: wrapSlice(c.article),\n enrollments: wrapSlice(c.enrollment),\n sessionLogs: wrapSlice(c.sessionLog),\n progression: wrapSlice(c.progression),\n bodyMetrics: wrapSlice(c.bodyMetric),\n progress: wrapSlice(c.progress),\n media: wrapSlice(c.media),\n appConfig: wrapSlice(c.appConfig),\n subscription: wrapSlice(c.subscription),\n };\n}\n","import type { Session, TokenStorage } from \"./types\";\n\nconst STORAGE_KEY_PREFIX = \"fytkit:\";\nconst STORAGE_KEY_SUFFIX = \":tokens\";\n\nfunction keyFor(clientId: string): string {\n return `${STORAGE_KEY_PREFIX}${clientId}${STORAGE_KEY_SUFFIX}`;\n}\n\nfunction isValidSession(value: unknown): value is Session {\n if (!value || typeof value !== \"object\") return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.accessToken === \"string\" &&\n typeof v.expiresAt === \"string\" &&\n typeof v.user === \"object\" &&\n v.user !== null &&\n typeof (v.user as { id?: unknown }).id === \"string\" &&\n typeof (v.user as { email?: unknown }).email === \"string\"\n );\n}\n\n/**\n * Default web storage. Reads/writes JSON under `fytkit:{clientId}:tokens`.\n * Silently no-ops when localStorage throws (Safari private mode, SSR).\n */\nexport function createLocalStorageAdapter(clientId: string): TokenStorage {\n const key = keyFor(clientId);\n return {\n get: () => {\n try {\n const raw = globalThis.localStorage?.getItem(key);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n return isValidSession(parsed) ? parsed : null;\n } catch {\n return null;\n }\n },\n set: (session: Session) => {\n try {\n globalThis.localStorage?.setItem(key, JSON.stringify(session));\n } catch {\n // Quota / private-mode / SSR — swallow and let the caller treat the\n // session as in-memory-only for this tab.\n }\n },\n remove: () => {\n try {\n globalThis.localStorage?.removeItem(key);\n } catch {\n // see set() rationale\n }\n },\n };\n}\n\n/** In-memory storage. Useful for tests and SSR. */\nexport function createMemoryStorageAdapter(): TokenStorage {\n let current: Session | null = null;\n return {\n get: () => current,\n set: (session: Session) => {\n current = session;\n },\n remove: () => {\n current = null;\n },\n };\n}\n","import type { PublicApi } from \"@fytkit/types\";\nimport { createORPCClient } from \"@orpc/client\";\nimport { RPCLink } from \"@orpc/client/fetch\";\nimport type { Session } from \"./types\";\n\nexport interface CreateTransportOptions {\n readonly baseUrl: string;\n readonly clientId: string;\n readonly getSession: () => Session | null;\n readonly fetch?: typeof fetch;\n}\n\nexport interface Transport {\n readonly client: PublicApi;\n /** Internal: hook for attachRefreshInterceptor to install a fetch wrapper. */\n readonly _setFetchInterceptor: (interceptor: FetchInterceptor) => void;\n}\n\ntype FetchInterceptor = (\n request: Request,\n next: (req: Request) => Promise<Response>,\n) => Promise<Response>;\n\nexport function createTransport(options: CreateTransportOptions): Transport {\n let interceptor: FetchInterceptor | null = null;\n const baseFetch: typeof fetch = options.fetch ?? fetch.bind(globalThis);\n\n // The fetch handed to RPCLink resolves the interceptor lazily so callers\n // can install one after construction (see attachRefreshInterceptor).\n const wrappedFetch: typeof fetch = (input, init) => {\n const request = input instanceof Request ? input : new Request(input, init);\n const next = (req: Request) => baseFetch(req);\n if (!interceptor) return next(request);\n return interceptor(request, next);\n };\n\n const link = new RPCLink({\n url: () => `${options.baseUrl}/rpc`,\n headers: () => {\n const session = options.getSession();\n const headers: Record<string, string> = {\n \"X-Fytkit-Client-Id\": options.clientId,\n };\n if (session) {\n headers.Authorization = `Bearer ${session.accessToken}`;\n }\n return headers;\n },\n fetch: wrappedFetch,\n });\n\n const client: PublicApi = createORPCClient(link);\n return {\n client,\n _setFetchInterceptor: (i) => {\n interceptor = i;\n },\n };\n}\n\n/** Internal marker header — set on the refresh call so we never recurse. */\nconst REFRESH_HEADER = \"X-Fytkit-Refresh\";\n\n/**\n * Detect whether a request targets the refresh procedure. The RPCLink\n * routes per-procedure calls under a URL whose pathname ends with the\n * procedure path (joined as `/segment/segment`), so we look for the\n * `auth/refresh` suffix. We use endsWith so trailing query strings or\n * link-level prefixes do not break detection.\n */\nfunction isRefreshRequest(request: Request): boolean {\n if (request.headers.get(REFRESH_HEADER) === \"1\") return true;\n try {\n const path = new URL(request.url).pathname;\n return path.endsWith(\"/auth/refresh\");\n } catch {\n return false;\n }\n}\n\nexport interface AttachRefreshInterceptorOptions {\n readonly transport: Transport;\n readonly auth: {\n readonly _refresh: () => Promise<Session>;\n readonly _signOutLocal: () => void;\n readonly getSession: () => Session | null;\n };\n}\n\n/**\n * Install a fetch interceptor that, on a 401 response, calls auth._refresh\n * once and retries the original request. Concurrent 401s de-duplicate\n * onto a single in-flight refresh promise. A 401 from refresh itself or\n * from the retry triggers a local sign-out and propagates the original\n * 401 to the caller (after which orpc throws ORPCError(\"UNAUTHORIZED\")).\n */\nexport function attachRefreshInterceptor(opts: AttachRefreshInterceptorOptions): void {\n let inflight: Promise<Session> | null = null;\n\n const refreshOnce = (): Promise<Session> => {\n if (!inflight) {\n inflight = opts.auth._refresh().finally(() => {\n inflight = null;\n });\n }\n return inflight;\n };\n\n opts.transport._setFetchInterceptor(async (request, next) => {\n // Refresh calls must never trigger a recursive refresh.\n if (isRefreshRequest(request)) {\n return next(request);\n }\n\n // Capture the request body now, before we pass `request` to `next` —\n // once fetch consumes a Request body it can no longer be cloned.\n const buffered = await request.clone().arrayBuffer();\n\n const firstResponse = await next(request);\n if (firstResponse.status !== 401) return firstResponse;\n\n try {\n await refreshOnce();\n } catch {\n // _refresh already called clearSession + emitted signed_out.\n return firstResponse;\n }\n\n // Rebuild headers so the new Authorization header replaces the stale\n // one — the RPCLink only re-evaluates its own `headers()` once per call,\n // so we patch the bearer ourselves here.\n const replayedHeaders = new Headers(request.headers);\n const session = opts.auth.getSession();\n if (session) {\n replayedHeaders.set(\"Authorization\", `Bearer ${session.accessToken}`);\n } else {\n replayedHeaders.delete(\"Authorization\");\n }\n const replayed = new Request(request.url, {\n method: request.method,\n headers: replayedHeaders,\n body: buffered.byteLength > 0 ? buffered : undefined,\n credentials: request.credentials,\n mode: request.mode,\n cache: request.cache,\n redirect: request.redirect,\n referrer: request.referrer,\n integrity: request.integrity,\n });\n\n const retried = await next(replayed);\n if (retried.status === 401) {\n // Refresh succeeded server-side but the server still rejects — the\n // session is dead. Sign out locally and let orpc surface the 401.\n opts.auth._signOutLocal();\n }\n return retried;\n });\n}\n","import { createAuthNamespace } from \"./auth\";\nimport { createDataNamespaces } from \"./data\";\nimport { createLocalStorageAdapter, createMemoryStorageAdapter } from \"./storage\";\nimport { attachRefreshInterceptor, createTransport } from \"./transport\";\nimport type { FytkitClient, FytkitClientOptions } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://api.fytkit.com\";\n\nexport function createFytkitClient(options: FytkitClientOptions): FytkitClient {\n if (!options || typeof options.clientId !== \"string\" || options.clientId.length === 0) {\n throw new Error(\"createFytkitClient: `clientId` is required\");\n }\n\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const storage = options.storage ?? createLocalStorageAdapter(options.clientId);\n\n // `auth` is declared after `transport` because `createAuthNamespace`\n // needs the transport to make its RPC calls. The transport in turn needs\n // a `getSession` that reads the auth cache — we resolve the cycle with a\n // late-bound reference: the closure below reads `auth` lazily, which is\n // safe because no request can fire before construction finishes.\n let auth: ReturnType<typeof createAuthNamespace> | null = null;\n\n const transport = createTransport({\n baseUrl,\n clientId: options.clientId,\n getSession: () => auth?.getSession() ?? null,\n fetch: options.fetch,\n });\n\n const authInstance = createAuthNamespace({ transport, storage });\n auth = authInstance;\n attachRefreshInterceptor({ transport, auth: authInstance });\n\n const data = createDataNamespaces(transport);\n\n return {\n auth: {\n signUp: authInstance.signUp,\n signIn: authInstance.signIn,\n signOut: authInstance.signOut,\n getSession: authInstance.getSession,\n onAuthStateChange: authInstance.onAuthStateChange,\n requestPasswordReset: authInstance.requestPasswordReset,\n confirmPasswordReset: authInstance.confirmPasswordReset,\n confirmEmail: authInstance.confirmEmail,\n },\n ...data,\n };\n}\n\n// Public re-exports.\nexport { createLocalStorageAdapter, createMemoryStorageAdapter };\nexport type {\n AuthState,\n FytkitClient,\n FytkitClientOptions,\n FytkitError,\n Session,\n SignInResult,\n TokenStorage,\n TwoFactorChallenge,\n TwoFactorMethod,\n TwoFactorToken,\n} from \"./types\";\n// `PublicApi` is the inferred router type that backs every namespace\n// on `FytkitClient` (e.g. `client.workouts` is `PublicApi[\"workout\"]`).\n// Re-exported so consumers can write generics over the router shape —\n// previously this surfaced as an `ae-forgotten-export` warning on\n// `FytkitClient` in the api-extractor report. The api-extractor will\n// still warn about `PublicRouter`/`publicRouter` being unexported —\n// that is intentional, those are implementation-detail names from the\n// generated snapshot that should not be part of the consumer surface.\nexport type { PublicApi } from \"@fytkit/types\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/error.ts","../src/events.ts","../src/auth.ts","../src/data.ts","../src/storage.ts","../src/transport.ts","../src/index.ts"],"names":["cached"],"mappings":"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","file":"index.js","sourcesContent":["import { ORPCError } from \"@orpc/client\";\nimport type { FytkitError } from \"./types\";\n\ninterface MaybeIssuesData {\n issues?: readonly unknown[];\n}\ninterface MaybeRetryAfterData {\n retryAfterMs?: number;\n}\n\nfunction pickIssues(data: unknown): readonly unknown[] | null {\n if (!data || typeof data !== \"object\") return null;\n const issues = (data as MaybeIssuesData).issues;\n return Array.isArray(issues) ? issues : null;\n}\n\nfunction pickRetryAfter(data: unknown): number {\n if (!data || typeof data !== \"object\") return 0;\n const raw = (data as MaybeRetryAfterData).retryAfterMs;\n return typeof raw === \"number\" && raw >= 0 ? raw : 0;\n}\n\n/**\n * Map any error thrown by `@orpc/client` (or the underlying fetch) into the\n * SDK's `FytkitError` discriminated union. The SDK never re-throws raw orpc\n * or network errors at the public surface.\n */\nexport function normalizeError(err: unknown): FytkitError {\n // Network failures from fetch surface as TypeError.\n if (err instanceof TypeError) return { kind: \"network\" };\n\n if (err instanceof ORPCError) {\n const code = err.code;\n const status = err.status;\n const data: unknown = err.data;\n const message = err.message;\n\n switch (code) {\n case \"UNAUTHORIZED\":\n // Carry the server's reason (e.g. \"Invalid credentials\" on a failed\n // sign-in) so the consumer can show it instead of a generic\n // 'session expired' copy. The synthetic no-session case in auth.ts\n // is built directly and stays message-less.\n return { kind: \"auth_required\", message };\n case \"FORBIDDEN\":\n return { kind: \"forbidden\", reason: message || \"Forbidden\" };\n case \"CONFLICT\":\n return { kind: \"conflict\", message: message || \"Conflict\" };\n case \"NOT_FOUND\":\n return { kind: \"not_found\" };\n case \"TOO_MANY_REQUESTS\":\n return { kind: \"rate_limited\", retryAfter: pickRetryAfter(data) };\n case \"BAD_REQUEST\":\n case \"UNPROCESSABLE_CONTENT\": {\n const issues = pickIssues(data);\n if (issues) return { kind: \"validation\", issues };\n // No structured issues — still carry the server's explanation so it\n // isn't dropped into a bare status code.\n return { kind: \"server\", status, message };\n }\n default:\n return { kind: \"server\", status, message };\n }\n }\n\n return { kind: \"server\", status: 0 };\n}\n","export interface EventBus<T> {\n readonly on: (listener: (value: T) => void) => () => void;\n readonly emit: (value: T) => void;\n}\n\nexport function createEventBus<T>(): EventBus<T> {\n const listeners = new Set<(value: T) => void>();\n return {\n on: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n emit: (value) => {\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (err) {\n // A buggy listener must not break siblings or the calling flow.\n console.error(\"[fytkit-sdk] event listener threw\", err);\n }\n }\n },\n };\n}\n","import { normalizeError } from \"./error\";\nimport { createEventBus } from \"./events\";\nimport type { Transport } from \"./transport\";\nimport type { AuthState, FytkitError, Session, SignInResult, TokenStorage, TwoFactorToken } from \"./types\";\n\nexport interface AuthNamespaceOptions {\n readonly transport: Transport;\n readonly storage: TokenStorage;\n /** Called after the SDK signs out for any reason (manual, refresh failure). */\n readonly onSignedOut?: () => void;\n}\n\nexport interface AuthNamespace {\n readonly signUp: (input: { email: string; password: string; name: string }) => Promise<Session>;\n readonly signIn: (input: { email: string; password: string }) => Promise<SignInResult>;\n readonly signOut: () => Promise<void>;\n readonly getSession: () => Session | null;\n readonly onAuthStateChange: (listener: (state: AuthState) => void) => () => void;\n readonly requestPasswordReset: (input: { email: string }) => Promise<void>;\n readonly confirmPasswordReset: (input: { token: string; password: string }) => Promise<void>;\n readonly confirmEmail: (input: { token: string }) => Promise<void>;\n /** Internal: force a refresh now. Wired by transport's 401 retry path. */\n readonly _refresh: () => Promise<Session>;\n /** Internal: clear cached session + emit signed_out. */\n readonly _signOutLocal: () => void;\n}\n\n/**\n * Schedule a proactive refresh this many ms before `expiresAt`. The\n * server-side access-token TTL is ~15 min so a 60-second lead time gives\n * us enough headroom to refresh transparently without burning sessions\n * needlessly while keeping the user signed-in across long-running tabs.\n */\nconst PROACTIVE_REFRESH_LEAD_MS = 60_000;\n\n/**\n * The auth namespace owns the cached session. It is the single writer to\n * `storage`; everything else reads via `getSession`. Calls that mutate\n * the session also emit on the event bus and (re)schedule the proactive\n * refresh timer against the new expiry.\n */\nexport function createAuthNamespace(opts: AuthNamespaceOptions): AuthNamespace {\n const bus = createEventBus<AuthState>();\n let cached: Session | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n // Forward declaration so scheduleRefresh can call the same _refresh body\n // the public surface exposes. Assigned at the bottom of the factory.\n let refreshFn: () => Promise<Session> = () => {\n throw new Error(\"refreshFn called before initialization\");\n };\n\n function clearTimer(): void {\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n }\n\n // `setTimeout` clamps any delay > 2^31-1 ms (~24.8 days) to 1 ms and\n // prints a Node deprecation warning. Sessions with an exotic far-future\n // expiry (test fixtures, mis-configured server) would otherwise fire the\n // timer instantly; cap the delay to the safe upper bound so the timer\n // simply re-arms on its next firing.\n const MAX_TIMEOUT_MS = 2_147_483_647;\n\n function scheduleRefresh(session: Session): void {\n clearTimer();\n const expiresMs = new Date(session.expiresAt).getTime();\n if (Number.isNaN(expiresMs)) return; // bad date — bail; reactive 401 path will handle it\n const rawDelay = expiresMs - Date.now() - PROACTIVE_REFRESH_LEAD_MS;\n const delay = Math.min(MAX_TIMEOUT_MS, Math.max(0, rawDelay));\n timer = setTimeout(() => {\n timer = null;\n void refreshFn().catch(() => {\n // refreshFn already handles sign-out on failure.\n });\n }, delay);\n }\n\n function applySession(session: Session, event: \"signed_in\" | \"session_refreshed\"): Session {\n cached = session;\n void opts.storage.set(session);\n bus.emit({ type: event, session });\n scheduleRefresh(session);\n return session;\n }\n\n function clearSession(emit = true): void {\n cached = null;\n clearTimer();\n void opts.storage.remove();\n if (emit) bus.emit({ type: \"signed_out\" });\n opts.onSignedOut?.();\n }\n\n async function call<T>(thunk: () => Promise<T>): Promise<T> {\n try {\n return await thunk();\n } catch (err) {\n throw normalizeError(err);\n }\n }\n\n // Best-effort hydrate at construction. If the storage already holds a\n // session (warm reload, second tab), restore it and arm the timer.\n void Promise.resolve(opts.storage.get()).then((s) => {\n if (s) {\n cached = s;\n scheduleRefresh(s);\n }\n });\n\n const signUp: AuthNamespace[\"signUp\"] = async (input) => {\n const result = await call(() => opts.transport.client.auth.signUp(input));\n const { user, session } = result.data;\n return applySession(\n { accessToken: session.accessToken, expiresAt: session.expiresAt, user },\n \"signed_in\",\n );\n };\n\n const signIn: AuthNamespace[\"signIn\"] = async (input) => {\n const result = await call(() => opts.transport.client.auth.signIn(input));\n if (result.data.kind === \"two_factor_required\") {\n // Mint the branded token exactly once at the network boundary.\n const token = result.data.twoFactorToken as TwoFactorToken;\n return {\n kind: \"two_factor_required\",\n challenge: { token, availableMethods: result.data.availableMethods },\n };\n }\n if (result.data.kind === \"signed_in\") {\n const { user, session } = result.data;\n const cached = applySession(\n { accessToken: session.accessToken, expiresAt: session.expiresAt, user },\n \"signed_in\",\n );\n return { kind: \"signed_in\", session: cached };\n }\n // Exhaustiveness guard — a future server-side variant must not silently fall through.\n const _exhaustive: never = result.data;\n throw _exhaustive;\n };\n\n const signOut: AuthNamespace[\"signOut\"] = async () => {\n const current = cached;\n if (!current) return;\n try {\n await opts.transport.client.auth.signOut({ token: current.accessToken });\n } catch (err) {\n // Even if the server rejects (e.g. token already revoked), clear\n // the local cache so the user is signed out client-side.\n void err;\n }\n clearSession();\n };\n\n const getSession: AuthNamespace[\"getSession\"] = () => cached;\n const onAuthStateChange: AuthNamespace[\"onAuthStateChange\"] = (listener) => bus.on(listener);\n\n const requestPasswordReset: AuthNamespace[\"requestPasswordReset\"] = async (input) => {\n await call(() => opts.transport.client.auth.requestPasswordReset(input));\n };\n const confirmPasswordReset: AuthNamespace[\"confirmPasswordReset\"] = async (input) => {\n await call(() => opts.transport.client.auth.confirmPasswordReset(input));\n };\n const confirmEmail: AuthNamespace[\"confirmEmail\"] = async (input) => {\n await call(() => opts.transport.client.auth.confirmEmail(input));\n };\n\n const _refresh: AuthNamespace[\"_refresh\"] = async () => {\n // Re-read storage as a fallback so a session written after\n // construction (e.g. on tab restore or in tests) is honoured.\n let current = cached;\n if (!current) {\n const fromStorage = await Promise.resolve(opts.storage.get());\n if (fromStorage) {\n cached = fromStorage;\n current = fromStorage;\n }\n }\n if (!current) {\n const err: FytkitError = { kind: \"auth_required\" };\n throw err;\n }\n try {\n const result = await opts.transport.client.auth.refresh({ token: current.accessToken });\n const { user, session } = result.data;\n return applySession(\n { accessToken: session.accessToken, expiresAt: session.expiresAt, user },\n \"session_refreshed\",\n );\n } catch (err) {\n clearSession();\n throw normalizeError(err);\n }\n };\n\n const _signOutLocal: AuthNamespace[\"_signOutLocal\"] = () => clearSession();\n\n refreshFn = _refresh;\n\n return {\n signUp,\n signIn,\n signOut,\n getSession,\n onAuthStateChange,\n requestPasswordReset,\n confirmPasswordReset,\n confirmEmail,\n _refresh,\n _signOutLocal,\n };\n}\n","import { normalizeError } from \"./error\";\nimport type { Transport } from \"./transport\";\n\n/**\n * Wrap every method on a public-router slice so thrown ORPCErrors become\n * normalised FytkitErrors at the SDK boundary.\n *\n * The slice we receive is an `@orpc/client` Proxy whose own keys are not\n * enumerable — every property lookup is intercepted lazily. We mirror that\n * shape by returning a Proxy of our own that wraps each function on first\n * access and caches the result. This way the SDK never needs to know the\n * method names ahead of time, and the typed shape from the server router\n * flows through unchanged.\n */\nfunction wrapSlice<T extends object>(slice: T): T {\n const cache = new Map<string | symbol, unknown>();\n return new Proxy(slice, {\n get(target, prop, receiver) {\n if (cache.has(prop)) return cache.get(prop);\n const value = Reflect.get(target, prop, receiver);\n if (typeof value !== \"function\") {\n // Allow nested namespaces to flow through unchanged (the orpc\n // proxy returns another proxy here, not a plain object).\n return value;\n }\n const wrapped = async (...args: unknown[]) => {\n try {\n return await (value as (...a: unknown[]) => Promise<unknown>)(...args);\n } catch (err) {\n throw normalizeError(err);\n }\n };\n cache.set(prop, wrapped);\n return wrapped;\n },\n }) as T;\n}\n\nexport interface DataNamespaces {\n readonly workouts: Transport[\"client\"][\"workout\"];\n readonly programs: Transport[\"client\"][\"program\"];\n readonly recipes: Transport[\"client\"][\"recipe\"];\n readonly nutrition: Transport[\"client\"][\"nutrition\"];\n readonly articles: Transport[\"client\"][\"article\"];\n readonly enrollments: Transport[\"client\"][\"enrollment\"];\n readonly sessionLogs: Transport[\"client\"][\"sessionLog\"];\n readonly progression: Transport[\"client\"][\"progression\"];\n readonly bodyMetrics: Transport[\"client\"][\"bodyMetric\"];\n readonly progress: Transport[\"client\"][\"progress\"];\n readonly media: Transport[\"client\"][\"media\"];\n readonly appConfig: Transport[\"client\"][\"appConfig\"];\n readonly subscription: Transport[\"client\"][\"subscription\"];\n readonly profile: Transport[\"client\"][\"profile\"];\n readonly nutritionLog: Transport[\"client\"][\"nutritionLog\"];\n}\n\nexport function createDataNamespaces(transport: Transport): DataNamespaces {\n const c = transport.client;\n return {\n workouts: wrapSlice(c.workout),\n programs: wrapSlice(c.program),\n recipes: wrapSlice(c.recipe),\n nutrition: wrapSlice(c.nutrition),\n articles: wrapSlice(c.article),\n enrollments: wrapSlice(c.enrollment),\n sessionLogs: wrapSlice(c.sessionLog),\n progression: wrapSlice(c.progression),\n bodyMetrics: wrapSlice(c.bodyMetric),\n progress: wrapSlice(c.progress),\n media: wrapSlice(c.media),\n appConfig: wrapSlice(c.appConfig),\n subscription: wrapSlice(c.subscription),\n profile: wrapSlice(c.profile),\n nutritionLog: wrapSlice(c.nutritionLog),\n };\n}\n","import type { Session, TokenStorage } from \"./types\";\n\nconst STORAGE_KEY_PREFIX = \"fytkit:\";\nconst STORAGE_KEY_SUFFIX = \":tokens\";\n\nfunction keyFor(clientId: string): string {\n return `${STORAGE_KEY_PREFIX}${clientId}${STORAGE_KEY_SUFFIX}`;\n}\n\nfunction isValidSession(value: unknown): value is Session {\n if (!value || typeof value !== \"object\") return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.accessToken === \"string\" &&\n typeof v.expiresAt === \"string\" &&\n typeof v.user === \"object\" &&\n v.user !== null &&\n typeof (v.user as { id?: unknown }).id === \"string\" &&\n typeof (v.user as { email?: unknown }).email === \"string\"\n );\n}\n\n/**\n * Default web storage. Reads/writes JSON under `fytkit:{clientId}:tokens`.\n * Silently no-ops when localStorage throws (Safari private mode, SSR).\n */\nexport function createLocalStorageAdapter(clientId: string): TokenStorage {\n const key = keyFor(clientId);\n return {\n get: () => {\n try {\n const raw = globalThis.localStorage?.getItem(key);\n if (!raw) return null;\n const parsed: unknown = JSON.parse(raw);\n return isValidSession(parsed) ? parsed : null;\n } catch {\n return null;\n }\n },\n set: (session: Session) => {\n try {\n globalThis.localStorage?.setItem(key, JSON.stringify(session));\n } catch {\n // Quota / private-mode / SSR — swallow and let the caller treat the\n // session as in-memory-only for this tab.\n }\n },\n remove: () => {\n try {\n globalThis.localStorage?.removeItem(key);\n } catch {\n // see set() rationale\n }\n },\n };\n}\n\n/** In-memory storage. Useful for tests and SSR. */\nexport function createMemoryStorageAdapter(): TokenStorage {\n let current: Session | null = null;\n return {\n get: () => current,\n set: (session: Session) => {\n current = session;\n },\n remove: () => {\n current = null;\n },\n };\n}\n","import type { PublicApi } from \"@fytkit/types\";\nimport { createORPCClient } from \"@orpc/client\";\nimport { RPCLink } from \"@orpc/client/fetch\";\nimport type { Session } from \"./types\";\n\nexport interface CreateTransportOptions {\n readonly baseUrl: string;\n readonly clientId: string;\n readonly getSession: () => Session | null;\n readonly fetch?: typeof fetch;\n}\n\nexport interface Transport {\n readonly client: PublicApi;\n /** Internal: hook for attachRefreshInterceptor to install a fetch wrapper. */\n readonly _setFetchInterceptor: (interceptor: FetchInterceptor) => void;\n}\n\ntype FetchInterceptor = (\n request: Request,\n next: (req: Request) => Promise<Response>,\n) => Promise<Response>;\n\nexport function createTransport(options: CreateTransportOptions): Transport {\n let interceptor: FetchInterceptor | null = null;\n const baseFetch: typeof fetch = options.fetch ?? fetch.bind(globalThis);\n\n // The fetch handed to RPCLink resolves the interceptor lazily so callers\n // can install one after construction (see attachRefreshInterceptor).\n const wrappedFetch: typeof fetch = (input, init) => {\n const request = input instanceof Request ? input : new Request(input, init);\n const next = (req: Request) => baseFetch(req);\n if (!interceptor) return next(request);\n return interceptor(request, next);\n };\n\n const link = new RPCLink({\n url: () => `${options.baseUrl}/rpc`,\n headers: () => {\n const session = options.getSession();\n const headers: Record<string, string> = {\n \"X-Fytkit-Client-Id\": options.clientId,\n };\n if (session) {\n headers.Authorization = `Bearer ${session.accessToken}`;\n }\n return headers;\n },\n fetch: wrappedFetch,\n });\n\n const client: PublicApi = createORPCClient(link);\n return {\n client,\n _setFetchInterceptor: (i) => {\n interceptor = i;\n },\n };\n}\n\n/** Internal marker header — set on the refresh call so we never recurse. */\nconst REFRESH_HEADER = \"X-Fytkit-Refresh\";\n\n/**\n * Detect whether a request targets the refresh procedure. The RPCLink\n * routes per-procedure calls under a URL whose pathname ends with the\n * procedure path (joined as `/segment/segment`), so we look for the\n * `auth/refresh` suffix. We use endsWith so trailing query strings or\n * link-level prefixes do not break detection.\n */\nfunction isRefreshRequest(request: Request): boolean {\n if (request.headers.get(REFRESH_HEADER) === \"1\") return true;\n try {\n const path = new URL(request.url).pathname;\n return path.endsWith(\"/auth/refresh\");\n } catch {\n return false;\n }\n}\n\nexport interface AttachRefreshInterceptorOptions {\n readonly transport: Transport;\n readonly auth: {\n readonly _refresh: () => Promise<Session>;\n readonly _signOutLocal: () => void;\n readonly getSession: () => Session | null;\n };\n}\n\n/**\n * Install a fetch interceptor that, on a 401 response, calls auth._refresh\n * once and retries the original request. Concurrent 401s de-duplicate\n * onto a single in-flight refresh promise. A 401 from refresh itself or\n * from the retry triggers a local sign-out and propagates the original\n * 401 to the caller (after which orpc throws ORPCError(\"UNAUTHORIZED\")).\n */\nexport function attachRefreshInterceptor(opts: AttachRefreshInterceptorOptions): void {\n let inflight: Promise<Session> | null = null;\n\n const refreshOnce = (): Promise<Session> => {\n if (!inflight) {\n inflight = opts.auth._refresh().finally(() => {\n inflight = null;\n });\n }\n return inflight;\n };\n\n opts.transport._setFetchInterceptor(async (request, next) => {\n // Refresh calls must never trigger a recursive refresh.\n if (isRefreshRequest(request)) {\n return next(request);\n }\n\n // Capture the request body now, before we pass `request` to `next` —\n // once fetch consumes a Request body it can no longer be cloned.\n const buffered = await request.clone().arrayBuffer();\n\n const firstResponse = await next(request);\n if (firstResponse.status !== 401) return firstResponse;\n\n try {\n await refreshOnce();\n } catch {\n // _refresh already called clearSession + emitted signed_out.\n return firstResponse;\n }\n\n // Rebuild headers so the new Authorization header replaces the stale\n // one — the RPCLink only re-evaluates its own `headers()` once per call,\n // so we patch the bearer ourselves here.\n const replayedHeaders = new Headers(request.headers);\n const session = opts.auth.getSession();\n if (session) {\n replayedHeaders.set(\"Authorization\", `Bearer ${session.accessToken}`);\n } else {\n replayedHeaders.delete(\"Authorization\");\n }\n const replayed = new Request(request.url, {\n method: request.method,\n headers: replayedHeaders,\n body: buffered.byteLength > 0 ? buffered : undefined,\n credentials: request.credentials,\n mode: request.mode,\n cache: request.cache,\n redirect: request.redirect,\n referrer: request.referrer,\n integrity: request.integrity,\n });\n\n const retried = await next(replayed);\n if (retried.status === 401) {\n // Refresh succeeded server-side but the server still rejects — the\n // session is dead. Sign out locally and let orpc surface the 401.\n opts.auth._signOutLocal();\n }\n return retried;\n });\n}\n","import { createAuthNamespace } from \"./auth\";\nimport { createDataNamespaces } from \"./data\";\nimport { createLocalStorageAdapter, createMemoryStorageAdapter } from \"./storage\";\nimport { attachRefreshInterceptor, createTransport } from \"./transport\";\nimport type { FytkitClient, FytkitClientOptions } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://api.fytkit.com\";\n\nexport function createFytkitClient(options: FytkitClientOptions): FytkitClient {\n if (!options || typeof options.clientId !== \"string\" || options.clientId.length === 0) {\n throw new Error(\"createFytkitClient: `clientId` is required\");\n }\n\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const storage = options.storage ?? createLocalStorageAdapter(options.clientId);\n\n // `auth` is declared after `transport` because `createAuthNamespace`\n // needs the transport to make its RPC calls. The transport in turn needs\n // a `getSession` that reads the auth cache — we resolve the cycle with a\n // late-bound reference: the closure below reads `auth` lazily, which is\n // safe because no request can fire before construction finishes.\n let auth: ReturnType<typeof createAuthNamespace> | null = null;\n\n const transport = createTransport({\n baseUrl,\n clientId: options.clientId,\n getSession: () => auth?.getSession() ?? null,\n fetch: options.fetch,\n });\n\n const authInstance = createAuthNamespace({ transport, storage });\n auth = authInstance;\n attachRefreshInterceptor({ transport, auth: authInstance });\n\n const data = createDataNamespaces(transport);\n\n return {\n auth: {\n signUp: authInstance.signUp,\n signIn: authInstance.signIn,\n signOut: authInstance.signOut,\n getSession: authInstance.getSession,\n onAuthStateChange: authInstance.onAuthStateChange,\n requestPasswordReset: authInstance.requestPasswordReset,\n confirmPasswordReset: authInstance.confirmPasswordReset,\n confirmEmail: authInstance.confirmEmail,\n },\n ...data,\n };\n}\n\n// Public re-exports.\nexport { createLocalStorageAdapter, createMemoryStorageAdapter };\nexport type {\n AuthState,\n FytkitClient,\n FytkitClientOptions,\n FytkitError,\n Session,\n SignInResult,\n TokenStorage,\n TwoFactorChallenge,\n TwoFactorMethod,\n TwoFactorToken,\n} from \"./types\";\n// `PublicApi` is the inferred router type that backs every namespace\n// on `FytkitClient` (e.g. `client.workouts` is `PublicApi[\"workout\"]`).\n// Re-exported so consumers can write generics over the router shape —\n// previously this surfaced as an `ae-forgotten-export` warning on\n// `FytkitClient` in the api-extractor report. The api-extractor will\n// still warn about `PublicRouter`/`publicRouter` being unexported —\n// that is intentional, those are implementation-detail names from the\n// generated snapshot that should not be part of the consumer surface.\nexport type { PublicApi } from \"@fytkit/types\";\n"]}
|