@learncard/types 5.17.6 → 5.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vc.d.ts CHANGED
@@ -151,7 +151,7 @@ export declare const CredentialSubjectValidator: z.ZodObject<{
151
151
  export type CredentialSubject = z.infer<typeof CredentialSubjectValidator>;
152
152
  export declare const CredentialStatusValidator: z.ZodObject<{
153
153
  type: z.ZodString;
154
- id: z.ZodString;
154
+ id: z.ZodOptional<z.ZodString>;
155
155
  }, z.core.$catchall<z.ZodAny>>;
156
156
  export type CredentialStatus = z.infer<typeof CredentialStatusValidator>;
157
157
  export declare const CredentialSchemaValidator: z.ZodObject<{
@@ -290,10 +290,10 @@ export declare const UnsignedVCValidator: z.ZodObject<{
290
290
  expirationDate: z.ZodOptional<z.ZodString>;
291
291
  credentialStatus: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
292
292
  type: z.ZodString;
293
- id: z.ZodString;
293
+ id: z.ZodOptional<z.ZodString>;
294
294
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
295
295
  type: z.ZodString;
296
- id: z.ZodString;
296
+ id: z.ZodOptional<z.ZodString>;
297
297
  }, z.core.$catchall<z.ZodAny>>>]>>;
298
298
  name: z.ZodOptional<z.ZodString>;
299
299
  description: z.ZodOptional<z.ZodString>;
@@ -301,10 +301,10 @@ export declare const UnsignedVCValidator: z.ZodObject<{
301
301
  validUntil: z.ZodOptional<z.ZodString>;
302
302
  status: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
303
303
  type: z.ZodString;
304
- id: z.ZodString;
304
+ id: z.ZodOptional<z.ZodString>;
305
305
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
306
306
  type: z.ZodString;
307
- id: z.ZodString;
307
+ id: z.ZodOptional<z.ZodString>;
308
308
  }, z.core.$catchall<z.ZodAny>>>]>>;
309
309
  termsOfUse: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
310
310
  type: z.ZodString;
@@ -451,10 +451,10 @@ export declare const VCValidator: z.ZodObject<{
451
451
  expirationDate: z.ZodOptional<z.ZodString>;
452
452
  credentialStatus: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
453
453
  type: z.ZodString;
454
- id: z.ZodString;
454
+ id: z.ZodOptional<z.ZodString>;
455
455
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
456
456
  type: z.ZodString;
457
- id: z.ZodString;
457
+ id: z.ZodOptional<z.ZodString>;
458
458
  }, z.core.$catchall<z.ZodAny>>>]>>;
459
459
  name: z.ZodOptional<z.ZodString>;
460
460
  description: z.ZodOptional<z.ZodString>;
@@ -462,10 +462,10 @@ export declare const VCValidator: z.ZodObject<{
462
462
  validUntil: z.ZodOptional<z.ZodString>;
463
463
  status: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
464
464
  type: z.ZodString;
465
- id: z.ZodString;
465
+ id: z.ZodOptional<z.ZodString>;
466
466
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
467
467
  type: z.ZodString;
468
- id: z.ZodString;
468
+ id: z.ZodOptional<z.ZodString>;
469
469
  }, z.core.$catchall<z.ZodAny>>>]>>;
470
470
  termsOfUse: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
471
471
  type: z.ZodString;
@@ -624,10 +624,10 @@ export declare const UnsignedVPValidator: z.ZodObject<{
624
624
  expirationDate: z.ZodOptional<z.ZodString>;
625
625
  credentialStatus: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
626
626
  type: z.ZodString;
627
- id: z.ZodString;
627
+ id: z.ZodOptional<z.ZodString>;
628
628
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
629
629
  type: z.ZodString;
630
- id: z.ZodString;
630
+ id: z.ZodOptional<z.ZodString>;
631
631
  }, z.core.$catchall<z.ZodAny>>>]>>;
632
632
  name: z.ZodOptional<z.ZodString>;
633
633
  description: z.ZodOptional<z.ZodString>;
@@ -635,10 +635,10 @@ export declare const UnsignedVPValidator: z.ZodObject<{
635
635
  validUntil: z.ZodOptional<z.ZodString>;
636
636
  status: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
637
637
  type: z.ZodString;
638
- id: z.ZodString;
638
+ id: z.ZodOptional<z.ZodString>;
639
639
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
640
640
  type: z.ZodString;
641
- id: z.ZodString;
641
+ id: z.ZodOptional<z.ZodString>;
642
642
  }, z.core.$catchall<z.ZodAny>>>]>>;
643
643
  termsOfUse: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
644
644
  type: z.ZodString;
@@ -791,10 +791,10 @@ export declare const UnsignedVPValidator: z.ZodObject<{
791
791
  expirationDate: z.ZodOptional<z.ZodString>;
792
792
  credentialStatus: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
793
793
  type: z.ZodString;
794
- id: z.ZodString;
794
+ id: z.ZodOptional<z.ZodString>;
795
795
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
796
796
  type: z.ZodString;
797
- id: z.ZodString;
797
+ id: z.ZodOptional<z.ZodString>;
798
798
  }, z.core.$catchall<z.ZodAny>>>]>>;
799
799
  name: z.ZodOptional<z.ZodString>;
800
800
  description: z.ZodOptional<z.ZodString>;
@@ -802,10 +802,10 @@ export declare const UnsignedVPValidator: z.ZodObject<{
802
802
  validUntil: z.ZodOptional<z.ZodString>;
803
803
  status: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
804
804
  type: z.ZodString;
805
- id: z.ZodString;
805
+ id: z.ZodOptional<z.ZodString>;
806
806
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
807
807
  type: z.ZodString;
808
- id: z.ZodString;
808
+ id: z.ZodOptional<z.ZodString>;
809
809
  }, z.core.$catchall<z.ZodAny>>>]>>;
810
810
  termsOfUse: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
811
811
  type: z.ZodString;
@@ -966,10 +966,10 @@ export declare const VPValidator: z.ZodObject<{
966
966
  expirationDate: z.ZodOptional<z.ZodString>;
967
967
  credentialStatus: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
968
968
  type: z.ZodString;
969
- id: z.ZodString;
969
+ id: z.ZodOptional<z.ZodString>;
970
970
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
971
971
  type: z.ZodString;
972
- id: z.ZodString;
972
+ id: z.ZodOptional<z.ZodString>;
973
973
  }, z.core.$catchall<z.ZodAny>>>]>>;
974
974
  name: z.ZodOptional<z.ZodString>;
975
975
  description: z.ZodOptional<z.ZodString>;
@@ -977,10 +977,10 @@ export declare const VPValidator: z.ZodObject<{
977
977
  validUntil: z.ZodOptional<z.ZodString>;
978
978
  status: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
979
979
  type: z.ZodString;
980
- id: z.ZodString;
980
+ id: z.ZodOptional<z.ZodString>;
981
981
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
982
982
  type: z.ZodString;
983
- id: z.ZodString;
983
+ id: z.ZodOptional<z.ZodString>;
984
984
  }, z.core.$catchall<z.ZodAny>>>]>>;
985
985
  termsOfUse: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
986
986
  type: z.ZodString;
@@ -1133,10 +1133,10 @@ export declare const VPValidator: z.ZodObject<{
1133
1133
  expirationDate: z.ZodOptional<z.ZodString>;
1134
1134
  credentialStatus: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
1135
1135
  type: z.ZodString;
1136
- id: z.ZodString;
1136
+ id: z.ZodOptional<z.ZodString>;
1137
1137
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
1138
1138
  type: z.ZodString;
1139
- id: z.ZodString;
1139
+ id: z.ZodOptional<z.ZodString>;
1140
1140
  }, z.core.$catchall<z.ZodAny>>>]>>;
1141
1141
  name: z.ZodOptional<z.ZodString>;
1142
1142
  description: z.ZodOptional<z.ZodString>;
@@ -1144,10 +1144,10 @@ export declare const VPValidator: z.ZodObject<{
1144
1144
  validUntil: z.ZodOptional<z.ZodString>;
1145
1145
  status: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
1146
1146
  type: z.ZodString;
1147
- id: z.ZodString;
1147
+ id: z.ZodOptional<z.ZodString>;
1148
1148
  }, z.core.$catchall<z.ZodAny>>, z.ZodArray<z.ZodObject<{
1149
1149
  type: z.ZodString;
1150
- id: z.ZodString;
1150
+ id: z.ZodOptional<z.ZodString>;
1151
1151
  }, z.core.$catchall<z.ZodAny>>>]>>;
1152
1152
  termsOfUse: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
1153
1153
  type: z.ZodString;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learncard/types",
3
- "version": "5.17.6",
3
+ "version": "5.18.1",
4
4
  "description": "Shared types for learn card",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -10,7 +10,7 @@ export const BitstringStatusListEntryValidator = z.object({
10
10
  id: z.string().optional(),
11
11
  type: z.literal('BitstringStatusListEntry'),
12
12
  statusPurpose: BitstringStatusPurposeValidator,
13
- statusListIndex: z.string(),
13
+ statusListIndex: z.string().or(z.number().int().nonnegative()),
14
14
  statusListCredential: z.string(),
15
15
  });
16
16
  export type BitstringStatusListEntry = z.infer<typeof BitstringStatusListEntryValidator>;
@@ -0,0 +1,216 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * In-App Messages — schema for the LaunchDarkly JSON flag that drives
5
+ * conditional, targeted user prompts across LearnCard apps.
6
+ *
7
+ * The flag value is a versioned list of messages. Each message carries its own
8
+ * targeting predicate tree that is evaluated ON DEVICE, because the client
9
+ * knows things LaunchDarkly's own targeting rules cannot reliably see — the
10
+ * Capacitor platform, the native binary version, and (crucially) the live
11
+ * Capgo/OTA bundle version. Keeping targeting in the JSON also makes the whole
12
+ * system unit-testable without a live LaunchDarkly connection.
13
+ *
14
+ * Consumed by `useInAppMessages()` in `learn-card-base`.
15
+ */
16
+
17
+ /** Runtime platform, as reported by `Capacitor.getPlatform()`. */
18
+ export const inAppMessagePlatformValidator = z.enum(['ios', 'android', 'web']);
19
+ export type InAppMessagePlatform = z.infer<typeof inAppMessagePlatformValidator>;
20
+
21
+ /**
22
+ * Which version number a `version` predicate compares against:
23
+ * - `native` — the installed native binary version (`App.getInfo().version`)
24
+ * - `web` — the web build's package.json version (`__APP_VERSION__`)
25
+ * - `capgo` — the live Capgo/OTA bundle version (`CapacitorUpdater.current()`)
26
+ */
27
+ export const inAppMessageVersionSourceValidator = z.enum(['native', 'web', 'capgo']);
28
+ export type InAppMessageVersionSource = z.infer<typeof inAppMessageVersionSourceValidator>;
29
+
30
+ /** Semantic-version comparison operator (less-than, ..., greater-than). */
31
+ export const inAppMessageVersionOpValidator = z.enum(['lt', 'lte', 'eq', 'gte', 'gt']);
32
+ export type InAppMessageVersionOp = z.infer<typeof inAppMessageVersionOpValidator>;
33
+
34
+ /** Match when the runtime platform is one of the listed platforms. */
35
+ export const platformPredicateValidator = z
36
+ .object({ platform: z.array(inAppMessagePlatformValidator).nonempty() })
37
+ .strict();
38
+
39
+ /** Match when the current user's profile role is one of the listed roles. */
40
+ export const rolePredicateValidator = z.object({ role: z.array(z.string()).nonempty() }).strict();
41
+
42
+ /** Match when a chosen version source satisfies a semver comparison. */
43
+ export const versionPredicateValidator = z
44
+ .object({
45
+ version: z
46
+ .object({
47
+ source: inAppMessageVersionSourceValidator,
48
+ op: inAppMessageVersionOpValidator,
49
+ value: z.string(),
50
+ })
51
+ .strict(),
52
+ })
53
+ .strict();
54
+
55
+ export type InAppMessagePredicate =
56
+ | z.infer<typeof platformPredicateValidator>
57
+ | z.infer<typeof rolePredicateValidator>
58
+ | z.infer<typeof versionPredicateValidator>
59
+ | { all: InAppMessagePredicate[] }
60
+ | { any: InAppMessagePredicate[] }
61
+ | { not: InAppMessagePredicate };
62
+
63
+ export const inAppMessagePredicateValidator: z.ZodType<InAppMessagePredicate> = z.lazy(() =>
64
+ z.union([
65
+ platformPredicateValidator,
66
+ rolePredicateValidator,
67
+ versionPredicateValidator,
68
+ z.object({ all: z.array(inAppMessagePredicateValidator) }).strict(),
69
+ z.object({ any: z.array(inAppMessagePredicateValidator) }).strict(),
70
+ z.object({ not: inAppMessagePredicateValidator }).strict(),
71
+ ])
72
+ );
73
+
74
+ /** Visual weight of an action button — maps to the app's button styles. */
75
+ export const inAppMessageActionStyleValidator = z
76
+ .enum(['primary', 'secondary', 'positive', 'dismiss'])
77
+ .default('secondary');
78
+ export type InAppMessageActionStyle = z.infer<typeof inAppMessageActionStyleValidator>;
79
+
80
+ // Action validators use .passthrough() (old clients tolerate new fields on
81
+ // actions), while predicate validators are .strict() so a typo in targeting
82
+ // fails closed at parse time instead of silently matching everyone.
83
+
84
+ /** Navigate to an in-app route (react-router path). */
85
+ export const internalLinkActionValidator = z
86
+ .object({ type: z.literal('internalLink'), path: z.string() })
87
+ .passthrough();
88
+
89
+ /** Open an external URL (native: Capacitor Browser; web: new tab). */
90
+ export const externalLinkActionValidator = z
91
+ .object({ type: z.literal('externalLink'), url: z.string() })
92
+ .passthrough();
93
+
94
+ /**
95
+ * Open this app's store page, resolved per-platform at runtime:
96
+ * iOS → App Store, Android → Google Play, web → configured fallback URL.
97
+ * Optional overrides win over tenant-config-derived links.
98
+ */
99
+ export const appStoreActionValidator = z
100
+ .object({
101
+ type: z.literal('appStore'),
102
+ iosUrl: z.string().optional(),
103
+ androidUrl: z.string().optional(),
104
+ webUrl: z.string().optional(),
105
+ })
106
+ .passthrough();
107
+
108
+ /** Trigger a Capgo OTA bundle check + download (with progress) + reload. */
109
+ export type AppStoreAction = z.infer<typeof appStoreActionValidator>;
110
+
111
+ export const capgoUpdateActionValidator = z
112
+ .object({ type: z.literal('capgoUpdate') })
113
+ .passthrough();
114
+
115
+ /** Dismiss/close the message without any side effect. */
116
+ export const dismissActionValidator = z.object({ type: z.literal('dismiss') }).passthrough();
117
+
118
+ export const inAppMessageActionTargetValidator = z.union([
119
+ internalLinkActionValidator,
120
+ externalLinkActionValidator,
121
+ appStoreActionValidator,
122
+ capgoUpdateActionValidator,
123
+ dismissActionValidator,
124
+ ]);
125
+ export type InAppMessageActionTarget = z.infer<typeof inAppMessageActionTargetValidator>;
126
+
127
+ export const inAppMessageActionValidator = z
128
+ .object({
129
+ label: z.string(),
130
+ style: inAppMessageActionStyleValidator,
131
+ action: inAppMessageActionTargetValidator,
132
+ /** When true, the message closes after this action runs (default true). */
133
+ closeOnComplete: z.boolean().default(true),
134
+ })
135
+ .passthrough();
136
+ export type InAppMessageAction = z.infer<typeof inAppMessageActionValidator>;
137
+
138
+ export const inAppMessageMediaValidator = z
139
+ .object({
140
+ type: z.enum(['youtube', 'image', 'gif']),
141
+ url: z.string(),
142
+ /** Aspect ratio hint, e.g. "16:9" or "1:1". Defaults to 16:9. */
143
+ aspect: z.string().default('16:9'),
144
+ /** Alt text for images/gifs (accessibility). */
145
+ alt: z.string().optional(),
146
+ })
147
+ .passthrough();
148
+ export type InAppMessageMedia = z.infer<typeof inAppMessageMediaValidator>;
149
+
150
+ /**
151
+ * How often a message may re-appear after being seen/dismissed:
152
+ * - `once` — show a single time, ever (persisted forever)
153
+ * - `session` — at most once per app session (in-memory)
154
+ * - `always` — every eligible render (no suppression)
155
+ * - `{ everyDays: n }` — again only after n days have elapsed
156
+ */
157
+ export const inAppMessageFrequencyValidator = z
158
+ .union([
159
+ z.literal('once'),
160
+ z.literal('session'),
161
+ z.literal('always'),
162
+ z.object({ everyDays: z.number().positive() }).strict(),
163
+ ])
164
+ .default('once');
165
+ export type InAppMessageFrequency = z.infer<typeof inAppMessageFrequencyValidator>;
166
+
167
+ export const inAppMessagePresentationValidator = z
168
+ .enum(['modal', 'banner', 'toast'])
169
+ .default('modal');
170
+ export type InAppMessagePresentation = z.infer<typeof inAppMessagePresentationValidator>;
171
+
172
+ export const inAppMessageValidator = z
173
+ .object({
174
+ /** Stable identifier — used to persist dismissal / frequency state. */
175
+ id: z.string(),
176
+ /** Higher priority wins when multiple messages match. Default 0. */
177
+ priority: z.number().default(0),
178
+ /** When false, the message is required/blocking (no dismiss affordance). */
179
+ dismissible: z.boolean().default(true),
180
+ frequency: inAppMessageFrequencyValidator,
181
+ presentation: inAppMessagePresentationValidator,
182
+ media: inAppMessageMediaValidator.optional(),
183
+ /** Optional emoji hero glyph — rendered only when `media` is not set. */
184
+ emoji: z.string().optional(),
185
+ title: z.string(),
186
+ body: z.string().optional(),
187
+ actions: z.array(inAppMessageActionValidator).default([]),
188
+ /** Targeting predicate tree. Omitted → matches everyone. */
189
+ targeting: inAppMessagePredicateValidator.optional(),
190
+ /** Allow disabling a message without removing it from the flag. */
191
+ enabled: z.boolean().default(true),
192
+ })
193
+ .passthrough();
194
+ export type InAppMessage = z.infer<typeof inAppMessageValidator>;
195
+
196
+ export const inAppMessagesFlagValidator = z
197
+ .object({
198
+ version: z.number().default(1),
199
+ messages: z.array(inAppMessageValidator).default([]),
200
+ })
201
+ .passthrough();
202
+ export type InAppMessagesFlag = z.infer<typeof inAppMessagesFlagValidator>;
203
+
204
+ /** Empty, safe default used when the flag is absent or malformed. */
205
+ export const EMPTY_IN_APP_MESSAGES_FLAG: InAppMessagesFlag = { version: 1, messages: [] };
206
+
207
+ /**
208
+ * Parse an unknown flag value into a validated `InAppMessagesFlag`.
209
+ * Returns the empty flag (never throws) so a malformed flag can never crash
210
+ * the host app.
211
+ */
212
+ export const parseInAppMessagesFlag = (raw: unknown): InAppMessagesFlag => {
213
+ const result = inAppMessagesFlagValidator.safeParse(raw);
214
+
215
+ return result.success ? result.data : EMPTY_IN_APP_MESSAGES_FLAG;
216
+ };
package/src/index.ts CHANGED
@@ -15,3 +15,4 @@ export * from './helpers';
15
15
  export * from './queries';
16
16
  export * from './auth';
17
17
  export * from './bitstring-status-list';
18
+ export * from './inAppMessages';
package/src/lcn.ts CHANGED
@@ -80,6 +80,12 @@ export const LCNProfileValidator = z.object({
80
80
  .optional()
81
81
  .describe('Date of birth of the profile: e.g. "1990-01-01".'),
82
82
  country: z.string().optional().describe('Country for the profile.'),
83
+ locale: z
84
+ .string()
85
+ .optional()
86
+ .describe(
87
+ "BCP-47 language tag (e.g. 'es', 'fr', 'ar') — the user's preferred language for server-sent notifications and emails."
88
+ ),
83
89
  approved: z.boolean().optional().describe('Approval status for the profile.'),
84
90
  });
85
91
  export type LCNProfile = z.infer<typeof LCNProfileValidator>;
@@ -918,6 +924,9 @@ export const LCNNotificationTypeEnumValidator = z.enum([
918
924
  'GUARDIAN_APPROVED',
919
925
  'GUARDIAN_REJECTED',
920
926
  'APP_NOTIFICATION',
927
+ 'CREDENTIAL_REVOKED',
928
+ 'CREDENTIAL_SUSPENDED',
929
+ 'CREDENTIAL_UNSUSPENDED',
921
930
  ]);
922
931
 
923
932
  export type LCNNotificationTypeEnum = z.infer<typeof LCNNotificationTypeEnumValidator>;
package/src/learncard.ts CHANGED
@@ -44,8 +44,17 @@ export const StatusCheckEntryValidator = z.object({
44
44
  export type StatusCheckEntry = z.infer<typeof StatusCheckEntryValidator>;
45
45
 
46
46
  export const VerificationCheckValidator = z.object({
47
+ /**
48
+ * Checks that completed successfully. This does not imply that warnings can be ignored.
49
+ */
47
50
  checks: z.string().array(),
51
+ /**
52
+ * Security-relevant conditions that did not prevent the requested cryptographic checks from
53
+ * completing. In particular, a non-DID issuer warning means the signature is valid but the
54
+ * named URL issuer's authorization of that signing key was not established.
55
+ */
48
56
  warnings: z.string().array(),
57
+ /** Verification failures that prevented one or more requested checks from succeeding. */
49
58
  errors: z.string().array(),
50
59
  /**
51
60
  * Per-entry results for the `credentialStatus` check, populated
package/src/vc.ts CHANGED
@@ -102,7 +102,7 @@ export const CredentialSubjectValidator = z.object({ id: z.string().optional() }
102
102
  export type CredentialSubject = z.infer<typeof CredentialSubjectValidator>;
103
103
 
104
104
  export const CredentialStatusValidator = z
105
- .object({ type: z.string(), id: z.string() })
105
+ .object({ type: z.string(), id: z.string().optional() })
106
106
  .catchall(z.any());
107
107
  export type CredentialStatus = z.infer<typeof CredentialStatusValidator>;
108
108