@learncard/types 5.17.3 → 5.17.5
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/README.md +5 -5
- package/dist/bitstring-status-list.d.ts +1 -1
- package/dist/bitstring-status-list.d.ts.map +1 -1
- package/dist/clr.d.ts +1 -1
- package/dist/clr.d.ts.map +1 -1
- package/dist/credential-format.d.ts +1 -1
- package/dist/credential-format.d.ts.map +1 -1
- package/dist/crypto.d.ts +1 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/did.d.ts +1 -1
- package/dist/did.d.ts.map +1 -1
- package/dist/lcn.d.ts +137 -134
- package/dist/lcn.d.ts.map +1 -1
- package/dist/learncard.d.ts +1 -1
- package/dist/learncard.d.ts.map +1 -1
- package/dist/learncloud.d.ts +1 -1
- package/dist/learncloud.d.ts.map +1 -1
- package/dist/mongo.d.ts +1 -1
- package/dist/mongo.d.ts.map +1 -1
- package/dist/obv3.d.ts +1 -1
- package/dist/obv3.d.ts.map +1 -1
- package/dist/queries.d.ts +4 -4
- package/dist/queries.d.ts.map +1 -1
- package/dist/types.cjs.development.cjs +4307 -2430
- package/dist/types.cjs.development.cjs.map +4 -4
- package/dist/types.cjs.production.min.cjs +56 -14
- package/dist/types.cjs.production.min.cjs.map +4 -4
- package/dist/types.esm.js +19 -22
- package/dist/types.esm.js.map +2 -2
- package/dist/vc.d.ts +1 -1
- package/dist/vc.d.ts.map +1 -1
- package/package.json +64 -59
- package/src/auth.ts +460 -0
- package/src/bitstring-status-list.ts +44 -0
- package/src/clr.ts +68 -0
- package/src/credential-format.ts +154 -0
- package/src/crypto.ts +41 -0
- package/src/did.ts +47 -0
- package/src/helpers.ts +10 -0
- package/src/index.ts +17 -0
- package/src/lcn.ts +2181 -0
- package/src/learncard.ts +123 -0
- package/src/learncloud.ts +26 -0
- package/src/mongo.ts +14 -0
- package/src/obv3.ts +252 -0
- package/src/queries.ts +56 -0
- package/src/registries.ts +9 -0
- package/src/vc.ts +221 -0
- package/src/wasm.ts +1 -0
package/src/lcn.ts
ADDED
|
@@ -0,0 +1,2181 @@
|
|
|
1
|
+
import type {} from 'zod-openapi';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
3
|
+
|
|
4
|
+
import { PaginationResponseValidator } from './mongo';
|
|
5
|
+
import { StringQuery } from './queries';
|
|
6
|
+
import { UnsignedVCValidator, VCValidator, VPValidator } from './vc';
|
|
7
|
+
|
|
8
|
+
export const LCNProfileDisplayValidator = z.object({
|
|
9
|
+
backgroundColor: z.string().optional(),
|
|
10
|
+
backgroundImage: z.string().optional(),
|
|
11
|
+
fadeBackgroundImage: z.boolean().optional(),
|
|
12
|
+
repeatBackgroundImage: z.boolean().optional(),
|
|
13
|
+
fontColor: z.string().optional(),
|
|
14
|
+
accentColor: z.string().optional(),
|
|
15
|
+
accentFontColor: z.string().optional(),
|
|
16
|
+
idBackgroundImage: z.string().optional(),
|
|
17
|
+
fadeIdBackgroundImage: z.boolean().optional(),
|
|
18
|
+
idBackgroundColor: z.string().optional(),
|
|
19
|
+
repeatIdBackgroundImage: z.boolean().optional(),
|
|
20
|
+
});
|
|
21
|
+
export type LCNProfileDisplay = z.infer<typeof LCNProfileDisplayValidator>;
|
|
22
|
+
|
|
23
|
+
export const ProfileVisibilityEnum = z.enum(['public', 'connections_only', 'private']);
|
|
24
|
+
export type ProfileVisibility = z.infer<typeof ProfileVisibilityEnum>;
|
|
25
|
+
|
|
26
|
+
export const AllowConnectionRequestsEnum = z.enum(['anyone', 'invite_only']);
|
|
27
|
+
export type AllowConnectionRequests = z.infer<typeof AllowConnectionRequestsEnum>;
|
|
28
|
+
|
|
29
|
+
export const LCNProfileValidator = z.object({
|
|
30
|
+
profileId: z.string().min(3).max(40).describe('Unique, URL-safe identifier for the profile.'),
|
|
31
|
+
displayName: z.string().default('').describe('Human-readable display name for the profile.'),
|
|
32
|
+
shortBio: z.string().default('').describe('Short bio for the profile.'),
|
|
33
|
+
bio: z.string().default('').describe('Longer bio for the profile.'),
|
|
34
|
+
did: z.string().describe('Decentralized Identifier for the profile. (auto-assigned)'),
|
|
35
|
+
isPrivate: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Whether the profile is private or not and shows up in search results.'),
|
|
39
|
+
profileVisibility: ProfileVisibilityEnum.default('public')
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Profile visibility: 'public', 'connections_only', or 'private'."),
|
|
42
|
+
showEmail: z
|
|
43
|
+
.boolean()
|
|
44
|
+
.default(false)
|
|
45
|
+
.optional()
|
|
46
|
+
.describe('Whether to show email to connections.'),
|
|
47
|
+
allowConnectionRequests: AllowConnectionRequestsEnum.default('anyone')
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("Who can send connection requests: 'anyone' or 'invite_only'."),
|
|
50
|
+
email: z.string().optional().describe('Contact email address for the profile. (deprecated)'),
|
|
51
|
+
image: z.string().optional().describe('Profile image URL for the profile.'),
|
|
52
|
+
heroImage: z.string().optional().describe('Hero image URL for the profile.'),
|
|
53
|
+
websiteLink: z.string().optional().describe('Website link for the profile.'),
|
|
54
|
+
isServiceProfile: z
|
|
55
|
+
.boolean()
|
|
56
|
+
.default(false)
|
|
57
|
+
.optional()
|
|
58
|
+
.describe('Whether the profile is a service profile or not.'),
|
|
59
|
+
type: z.string().optional().describe('Profile type: e.g. "person", "organization", "service".'),
|
|
60
|
+
notificationsWebhook: z
|
|
61
|
+
.string()
|
|
62
|
+
.url()
|
|
63
|
+
.startsWith('http')
|
|
64
|
+
.optional()
|
|
65
|
+
.describe('URL to send notifications to.'),
|
|
66
|
+
display: LCNProfileDisplayValidator.optional().describe('Display settings for the profile.'),
|
|
67
|
+
highlightedCredentials: z
|
|
68
|
+
.array(z.string())
|
|
69
|
+
.max(5)
|
|
70
|
+
.optional()
|
|
71
|
+
.describe('Up to 5 unique boost URIs to highlight on the profile.'),
|
|
72
|
+
role: z
|
|
73
|
+
.string()
|
|
74
|
+
.default('')
|
|
75
|
+
.optional()
|
|
76
|
+
.describe('Role of the profile: e.g. "teacher", "student".'),
|
|
77
|
+
dob: z
|
|
78
|
+
.string()
|
|
79
|
+
.default('')
|
|
80
|
+
.optional()
|
|
81
|
+
.describe('Date of birth of the profile: e.g. "1990-01-01".'),
|
|
82
|
+
country: z.string().optional().describe('Country for the profile.'),
|
|
83
|
+
approved: z.boolean().optional().describe('Approval status for the profile.'),
|
|
84
|
+
});
|
|
85
|
+
export type LCNProfile = z.infer<typeof LCNProfileValidator>;
|
|
86
|
+
|
|
87
|
+
export const LCNPublicProfileValidator = LCNProfileValidator.pick({
|
|
88
|
+
profileId: true,
|
|
89
|
+
displayName: true,
|
|
90
|
+
shortBio: true,
|
|
91
|
+
image: true,
|
|
92
|
+
heroImage: true,
|
|
93
|
+
type: true,
|
|
94
|
+
isServiceProfile: true,
|
|
95
|
+
display: true,
|
|
96
|
+
});
|
|
97
|
+
export type LCNPublicProfile = z.infer<typeof LCNPublicProfileValidator>;
|
|
98
|
+
|
|
99
|
+
export const LCNAuthedProfileValidator = LCNPublicProfileValidator.extend({
|
|
100
|
+
bio: LCNProfileValidator.shape.bio,
|
|
101
|
+
websiteLink: LCNProfileValidator.shape.websiteLink,
|
|
102
|
+
role: LCNProfileValidator.shape.role,
|
|
103
|
+
highlightedCredentials: LCNProfileValidator.shape.highlightedCredentials,
|
|
104
|
+
did: LCNProfileValidator.shape.did,
|
|
105
|
+
});
|
|
106
|
+
export type LCNAuthedProfile = z.infer<typeof LCNAuthedProfileValidator>;
|
|
107
|
+
|
|
108
|
+
export const LCNConnectionProfileValidator = LCNAuthedProfileValidator.extend({
|
|
109
|
+
email: LCNProfileValidator.shape.email,
|
|
110
|
+
});
|
|
111
|
+
export type LCNConnectionProfile = z.infer<typeof LCNConnectionProfileValidator>;
|
|
112
|
+
|
|
113
|
+
export const LCNVisibleProfileValidator = z.union([
|
|
114
|
+
LCNConnectionProfileValidator.strict(),
|
|
115
|
+
LCNAuthedProfileValidator.strict(),
|
|
116
|
+
LCNPublicProfileValidator.strict(),
|
|
117
|
+
LCNProfileValidator,
|
|
118
|
+
]);
|
|
119
|
+
export type LCNVisibleProfile = z.infer<typeof LCNVisibleProfileValidator>;
|
|
120
|
+
|
|
121
|
+
export const LCNProfileQueryValidator = z
|
|
122
|
+
.object({
|
|
123
|
+
profileId: StringQuery,
|
|
124
|
+
displayName: StringQuery,
|
|
125
|
+
shortBio: StringQuery,
|
|
126
|
+
bio: StringQuery,
|
|
127
|
+
email: StringQuery,
|
|
128
|
+
websiteLink: StringQuery,
|
|
129
|
+
isServiceProfile: z.boolean(),
|
|
130
|
+
type: StringQuery,
|
|
131
|
+
})
|
|
132
|
+
.partial();
|
|
133
|
+
export type LCNProfileQuery = z.infer<typeof LCNProfileQueryValidator>;
|
|
134
|
+
|
|
135
|
+
export const PaginatedLCNProfilesValidator = PaginationResponseValidator.extend({
|
|
136
|
+
records: LCNProfileValidator.array(),
|
|
137
|
+
});
|
|
138
|
+
export type PaginatedLCNProfiles = z.infer<typeof PaginatedLCNProfilesValidator>;
|
|
139
|
+
|
|
140
|
+
export const PaginatedVisibleLCNProfilesValidator = PaginationResponseValidator.extend({
|
|
141
|
+
records: LCNVisibleProfileValidator.array(),
|
|
142
|
+
});
|
|
143
|
+
export type PaginatedVisibleLCNProfiles = z.infer<typeof PaginatedVisibleLCNProfilesValidator>;
|
|
144
|
+
|
|
145
|
+
export const LCNProfileConnectionStatusEnum = z.enum([
|
|
146
|
+
'CONNECTED',
|
|
147
|
+
'PENDING_REQUEST_SENT',
|
|
148
|
+
'PENDING_REQUEST_RECEIVED',
|
|
149
|
+
'NOT_CONNECTED',
|
|
150
|
+
]);
|
|
151
|
+
export type LCNProfileConnectionStatusEnum = z.infer<typeof LCNProfileConnectionStatusEnum>;
|
|
152
|
+
|
|
153
|
+
export const LCNProfileManagerValidator = z.object({
|
|
154
|
+
id: z.string(),
|
|
155
|
+
created: z.string(),
|
|
156
|
+
displayName: z.string().default('').optional(),
|
|
157
|
+
shortBio: z.string().default('').optional(),
|
|
158
|
+
bio: z.string().default('').optional(),
|
|
159
|
+
email: z.string().optional(),
|
|
160
|
+
image: z.string().optional(),
|
|
161
|
+
heroImage: z.string().optional(),
|
|
162
|
+
});
|
|
163
|
+
export type LCNProfileManager = z.infer<typeof LCNProfileManagerValidator>;
|
|
164
|
+
|
|
165
|
+
export const PaginatedLCNProfileManagersValidator = PaginationResponseValidator.extend({
|
|
166
|
+
records: LCNProfileManagerValidator.extend({ did: z.string() }).array(),
|
|
167
|
+
});
|
|
168
|
+
export type PaginatedLCNProfileManagers = z.infer<typeof PaginatedLCNProfileManagersValidator>;
|
|
169
|
+
|
|
170
|
+
export const LCNProfileManagerQueryValidator = z
|
|
171
|
+
.object({
|
|
172
|
+
id: StringQuery,
|
|
173
|
+
displayName: StringQuery,
|
|
174
|
+
shortBio: StringQuery,
|
|
175
|
+
bio: StringQuery,
|
|
176
|
+
email: StringQuery,
|
|
177
|
+
})
|
|
178
|
+
.partial();
|
|
179
|
+
export type LCNProfileManagerQuery = z.infer<typeof LCNProfileManagerQueryValidator>;
|
|
180
|
+
|
|
181
|
+
export const PaginatedLCNProfilesAndManagersValidator = PaginationResponseValidator.extend({
|
|
182
|
+
records: z
|
|
183
|
+
.object({
|
|
184
|
+
profile: LCNProfileValidator,
|
|
185
|
+
manager: LCNProfileManagerValidator.extend({ did: z.string() }).optional(),
|
|
186
|
+
})
|
|
187
|
+
.array(),
|
|
188
|
+
});
|
|
189
|
+
export type PaginatedLCNProfilesAndManagers = z.infer<
|
|
190
|
+
typeof PaginatedLCNProfilesAndManagersValidator
|
|
191
|
+
>;
|
|
192
|
+
|
|
193
|
+
export const SentCredentialInfoValidator = z.object({
|
|
194
|
+
uri: z.string(),
|
|
195
|
+
to: z.string(),
|
|
196
|
+
from: z.string(),
|
|
197
|
+
sent: z.iso.datetime(),
|
|
198
|
+
received: z.iso.datetime().optional(),
|
|
199
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
200
|
+
});
|
|
201
|
+
export type SentCredentialInfo = z.infer<typeof SentCredentialInfoValidator>;
|
|
202
|
+
|
|
203
|
+
export const BoostPermissionsValidator = z.object({
|
|
204
|
+
role: z.string(),
|
|
205
|
+
canView: z.boolean().default(true),
|
|
206
|
+
canEdit: z.boolean(),
|
|
207
|
+
canIssue: z.boolean(),
|
|
208
|
+
canRevoke: z.boolean(),
|
|
209
|
+
canManagePermissions: z.boolean(),
|
|
210
|
+
canIssueChildren: z.string(),
|
|
211
|
+
canCreateChildren: z.string(),
|
|
212
|
+
canEditChildren: z.string(),
|
|
213
|
+
canRevokeChildren: z.string(),
|
|
214
|
+
canManageChildrenPermissions: z.string(),
|
|
215
|
+
canManageChildrenProfiles: z.boolean().optional(),
|
|
216
|
+
canViewAnalytics: z.boolean(),
|
|
217
|
+
});
|
|
218
|
+
export type BoostPermissions = z.infer<typeof BoostPermissionsValidator>;
|
|
219
|
+
|
|
220
|
+
export const BoostPermissionsQueryValidator = z
|
|
221
|
+
.object({
|
|
222
|
+
role: StringQuery,
|
|
223
|
+
canView: z.boolean(),
|
|
224
|
+
canEdit: z.boolean(),
|
|
225
|
+
canIssue: z.boolean(),
|
|
226
|
+
canRevoke: z.boolean(),
|
|
227
|
+
canManagePermissions: z.boolean(),
|
|
228
|
+
canIssueChildren: StringQuery,
|
|
229
|
+
canCreateChildren: StringQuery,
|
|
230
|
+
canEditChildren: StringQuery,
|
|
231
|
+
canRevokeChildren: StringQuery,
|
|
232
|
+
canManageChildrenPermissions: StringQuery,
|
|
233
|
+
canManageChildrenProfiles: z.boolean(),
|
|
234
|
+
canViewAnalytics: z.boolean(),
|
|
235
|
+
})
|
|
236
|
+
.partial();
|
|
237
|
+
export type BoostPermissionsQuery = z.infer<typeof BoostPermissionsQueryValidator>;
|
|
238
|
+
|
|
239
|
+
export const ClaimHookTypeValidator = z.enum(['GRANT_PERMISSIONS', 'ADD_ADMIN', 'AUTO_CONNECT']);
|
|
240
|
+
export type ClaimHookType = z.infer<typeof ClaimHookTypeValidator>;
|
|
241
|
+
|
|
242
|
+
export const ClaimHookValidator = z.discriminatedUnion('type', [
|
|
243
|
+
z.object({
|
|
244
|
+
type: z.literal(ClaimHookTypeValidator.enum.GRANT_PERMISSIONS),
|
|
245
|
+
data: z.object({
|
|
246
|
+
claimUri: z.string(),
|
|
247
|
+
targetUri: z.string(),
|
|
248
|
+
permissions: BoostPermissionsValidator.partial(),
|
|
249
|
+
}),
|
|
250
|
+
}),
|
|
251
|
+
z.object({
|
|
252
|
+
type: z.literal(ClaimHookTypeValidator.enum.ADD_ADMIN),
|
|
253
|
+
data: z.object({ claimUri: z.string(), targetUri: z.string() }),
|
|
254
|
+
}),
|
|
255
|
+
z.object({
|
|
256
|
+
type: z.literal(ClaimHookTypeValidator.enum.AUTO_CONNECT),
|
|
257
|
+
data: z.object({ claimUri: z.string(), targetUri: z.string() }),
|
|
258
|
+
}),
|
|
259
|
+
]);
|
|
260
|
+
export type ClaimHook = z.infer<typeof ClaimHookValidator>;
|
|
261
|
+
|
|
262
|
+
export const ClaimHookQueryValidator = z.object({
|
|
263
|
+
type: StringQuery,
|
|
264
|
+
data: z
|
|
265
|
+
.object({
|
|
266
|
+
claimUri: StringQuery,
|
|
267
|
+
targetUri: StringQuery,
|
|
268
|
+
permissions: BoostPermissionsQueryValidator.partial(),
|
|
269
|
+
})
|
|
270
|
+
.partial(),
|
|
271
|
+
});
|
|
272
|
+
export type ClaimHookQuery = z.infer<typeof ClaimHookQueryValidator>;
|
|
273
|
+
|
|
274
|
+
export const FullClaimHookValidator = z
|
|
275
|
+
.object({ id: z.string(), createdAt: z.string(), updatedAt: z.string() })
|
|
276
|
+
.and(ClaimHookValidator);
|
|
277
|
+
export type FullClaimHook = z.infer<typeof FullClaimHookValidator>;
|
|
278
|
+
|
|
279
|
+
export const PaginatedClaimHooksValidator = PaginationResponseValidator.extend({
|
|
280
|
+
records: FullClaimHookValidator.array(),
|
|
281
|
+
});
|
|
282
|
+
export type PaginatedClaimHooksType = z.infer<typeof PaginatedClaimHooksValidator>;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Status states for Boosts that control what actions can be performed.
|
|
286
|
+
*
|
|
287
|
+
* - **DRAFT**: Work in progress. Can edit all fields, but cannot send or generate claim links.
|
|
288
|
+
* - **PROVISIONAL**: Active but iterating. Can both edit all fields AND send/issue credentials. Ideal for testing in production or soft launches.
|
|
289
|
+
* - **LIVE**: Official/finalized. Can only edit meta and defaultPermissions. Core properties are locked for consistency.
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* // Create a provisional boost for testing
|
|
294
|
+
* const boostUri = await learnCard.invoke.createBoost(credential, {
|
|
295
|
+
* status: 'PROVISIONAL',
|
|
296
|
+
* });
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
export const LCNBoostStatus = z.enum(['DRAFT', 'PROVISIONAL', 'LIVE']);
|
|
300
|
+
export type LCNBoostStatusEnum = z.infer<typeof LCNBoostStatus>;
|
|
301
|
+
|
|
302
|
+
export const BoostValidator = z.object({
|
|
303
|
+
uri: z.string(),
|
|
304
|
+
name: z.string().optional(),
|
|
305
|
+
type: z.string().optional(),
|
|
306
|
+
category: z.string().optional(),
|
|
307
|
+
status: LCNBoostStatus.optional(),
|
|
308
|
+
autoConnectRecipients: z.boolean().optional(),
|
|
309
|
+
meta: z.record(z.string(), z.any()).optional(),
|
|
310
|
+
claimPermissions: BoostPermissionsValidator.optional(),
|
|
311
|
+
defaultPermissions: BoostPermissionsValidator.optional(),
|
|
312
|
+
allowAnyoneToCreateChildren: z.boolean().optional(),
|
|
313
|
+
});
|
|
314
|
+
export type Boost = z.infer<typeof BoostValidator>;
|
|
315
|
+
|
|
316
|
+
const BaseBoostQueryValidator = z
|
|
317
|
+
.object({
|
|
318
|
+
uri: StringQuery,
|
|
319
|
+
name: StringQuery,
|
|
320
|
+
type: StringQuery,
|
|
321
|
+
category: StringQuery,
|
|
322
|
+
meta: z.record(z.string(), StringQuery),
|
|
323
|
+
status: LCNBoostStatus.or(z.object({ $in: LCNBoostStatus.array() })),
|
|
324
|
+
autoConnectRecipients: z.boolean(),
|
|
325
|
+
})
|
|
326
|
+
.partial();
|
|
327
|
+
|
|
328
|
+
export const BoostQueryValidator = z.union([
|
|
329
|
+
z.object({
|
|
330
|
+
$or: BaseBoostQueryValidator.array(),
|
|
331
|
+
}),
|
|
332
|
+
BaseBoostQueryValidator,
|
|
333
|
+
]);
|
|
334
|
+
export type BoostQuery = z.infer<typeof BoostQueryValidator>;
|
|
335
|
+
|
|
336
|
+
export const PaginatedBoostsValidator = PaginationResponseValidator.extend({
|
|
337
|
+
records: BoostValidator.array(),
|
|
338
|
+
});
|
|
339
|
+
export type PaginatedBoostsType = z.infer<typeof PaginatedBoostsValidator>;
|
|
340
|
+
|
|
341
|
+
export const BoostRecipientValidator = z.object({
|
|
342
|
+
to: LCNVisibleProfileValidator,
|
|
343
|
+
from: z.string(),
|
|
344
|
+
received: z.string().optional(),
|
|
345
|
+
uri: z.string().optional(),
|
|
346
|
+
status: z.enum(['active', 'revoked', 'suspended']).optional(),
|
|
347
|
+
});
|
|
348
|
+
export type BoostRecipientInfo = z.infer<typeof BoostRecipientValidator>;
|
|
349
|
+
|
|
350
|
+
export const PaginatedBoostRecipientsValidator = PaginationResponseValidator.extend({
|
|
351
|
+
records: BoostRecipientValidator.array(),
|
|
352
|
+
});
|
|
353
|
+
export type PaginatedBoostRecipientsType = z.infer<typeof PaginatedBoostRecipientsValidator>;
|
|
354
|
+
|
|
355
|
+
export const BoostRecipientWithChildrenValidator = z.object({
|
|
356
|
+
to: LCNVisibleProfileValidator,
|
|
357
|
+
from: z.string(),
|
|
358
|
+
received: z.string().optional(),
|
|
359
|
+
boostUris: z.array(z.string()),
|
|
360
|
+
credentialUris: z.array(z.string()).optional(),
|
|
361
|
+
status: z.enum(['active', 'revoked', 'suspended']).optional(),
|
|
362
|
+
});
|
|
363
|
+
export type BoostRecipientWithChildrenInfo = z.infer<typeof BoostRecipientWithChildrenValidator>;
|
|
364
|
+
|
|
365
|
+
export const PaginatedBoostRecipientsWithChildrenValidator = PaginationResponseValidator.extend({
|
|
366
|
+
records: BoostRecipientWithChildrenValidator.array(),
|
|
367
|
+
});
|
|
368
|
+
export type PaginatedBoostRecipientsWithChildrenType = z.infer<
|
|
369
|
+
typeof PaginatedBoostRecipientsWithChildrenValidator
|
|
370
|
+
>;
|
|
371
|
+
|
|
372
|
+
export const LCNBoostClaimLinkSigningAuthorityValidator = z.object({
|
|
373
|
+
endpoint: z.string(),
|
|
374
|
+
name: z.string(),
|
|
375
|
+
did: z.string().optional(),
|
|
376
|
+
});
|
|
377
|
+
export type LCNBoostClaimLinkSigningAuthorityType = z.infer<
|
|
378
|
+
typeof LCNBoostClaimLinkSigningAuthorityValidator
|
|
379
|
+
>;
|
|
380
|
+
|
|
381
|
+
export const LCNBoostClaimLinkOptionsValidator = z.object({
|
|
382
|
+
ttlSeconds: z.number().optional(),
|
|
383
|
+
totalUses: z.number().optional(),
|
|
384
|
+
});
|
|
385
|
+
export type LCNBoostClaimLinkOptionsType = z.infer<typeof LCNBoostClaimLinkOptionsValidator>;
|
|
386
|
+
|
|
387
|
+
export const LCNSigningAuthorityValidator = z.object({
|
|
388
|
+
endpoint: z.string(),
|
|
389
|
+
});
|
|
390
|
+
export type LCNSigningAuthorityType = z.infer<typeof LCNSigningAuthorityValidator>;
|
|
391
|
+
|
|
392
|
+
export const LCNSigningAuthorityForUserValidator = z.object({
|
|
393
|
+
signingAuthority: LCNSigningAuthorityValidator,
|
|
394
|
+
relationship: z.object({
|
|
395
|
+
name: z
|
|
396
|
+
.string()
|
|
397
|
+
.max(15)
|
|
398
|
+
.regex(/^[a-z0-9-]+$/, {
|
|
399
|
+
message:
|
|
400
|
+
'The input string must contain only lowercase letters, numbers, and hyphens.',
|
|
401
|
+
}),
|
|
402
|
+
did: z.string(),
|
|
403
|
+
isPrimary: z.boolean().optional(),
|
|
404
|
+
}),
|
|
405
|
+
});
|
|
406
|
+
export type LCNSigningAuthorityForUserType = z.infer<typeof LCNSigningAuthorityForUserValidator>;
|
|
407
|
+
|
|
408
|
+
export const AutoBoostConfigValidator = z.object({
|
|
409
|
+
boostUri: z.string(),
|
|
410
|
+
signingAuthority: z.object({
|
|
411
|
+
endpoint: z.string(),
|
|
412
|
+
name: z.string(),
|
|
413
|
+
}),
|
|
414
|
+
});
|
|
415
|
+
export type AutoBoostConfig = z.infer<typeof AutoBoostConfigValidator>;
|
|
416
|
+
|
|
417
|
+
const SendBoostTemplateValidator = BoostValidator.partial()
|
|
418
|
+
.omit({ uri: true, claimPermissions: true })
|
|
419
|
+
.extend({
|
|
420
|
+
credential: VCValidator.or(UnsignedVCValidator),
|
|
421
|
+
claimPermissions: BoostPermissionsValidator.partial().optional(),
|
|
422
|
+
skills: z
|
|
423
|
+
.array(
|
|
424
|
+
z.object({
|
|
425
|
+
frameworkId: z.string(),
|
|
426
|
+
id: z.string(),
|
|
427
|
+
proficiencyLevel: z.number().optional(),
|
|
428
|
+
})
|
|
429
|
+
)
|
|
430
|
+
.min(1)
|
|
431
|
+
.optional(),
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
// Branding options for email/SMS delivery (used when recipient is email/phone)
|
|
435
|
+
export const SendBrandingOptionsValidator = z.object({
|
|
436
|
+
issuerName: z.string().optional().describe('Name of the issuing organization'),
|
|
437
|
+
issuerLogoUrl: z.string().url().optional().describe('Logo URL of the issuing organization'),
|
|
438
|
+
credentialName: z.string().optional().describe('Display name for the credential'),
|
|
439
|
+
recipientName: z.string().optional().describe('Name of the recipient for personalization'),
|
|
440
|
+
});
|
|
441
|
+
export type SendBrandingOptions = z.infer<typeof SendBrandingOptionsValidator>;
|
|
442
|
+
|
|
443
|
+
export const GuardianStatusValidator = z.enum([
|
|
444
|
+
'AWAITING_GUARDIAN',
|
|
445
|
+
'GUARDIAN_APPROVED',
|
|
446
|
+
'GUARDIAN_REJECTED',
|
|
447
|
+
]);
|
|
448
|
+
export type GuardianStatus = z.infer<typeof GuardianStatusValidator>;
|
|
449
|
+
|
|
450
|
+
// Options for send method (applies when recipient is email/phone, routes to Universal Inbox)
|
|
451
|
+
export const SendOptionsValidator = z.object({
|
|
452
|
+
webhookUrl: z.string().url().optional().describe('Webhook URL to receive claim notifications'),
|
|
453
|
+
suppressDelivery: z
|
|
454
|
+
.boolean()
|
|
455
|
+
.optional()
|
|
456
|
+
.describe('If true, returns claimUrl without sending email/SMS'),
|
|
457
|
+
branding: SendBrandingOptionsValidator.optional().describe('Branding for email/SMS delivery'),
|
|
458
|
+
guardianEmail: z
|
|
459
|
+
.string()
|
|
460
|
+
.email()
|
|
461
|
+
.optional()
|
|
462
|
+
.describe('Guardian email that must approve before student can claim'),
|
|
463
|
+
});
|
|
464
|
+
export type SendOptions = z.infer<typeof SendOptionsValidator>;
|
|
465
|
+
|
|
466
|
+
// Route-level validator (TRPC requires ZodObject, not discriminatedUnion)
|
|
467
|
+
export const SendBoostInputValidator = z
|
|
468
|
+
.object({
|
|
469
|
+
type: z.literal('boost'),
|
|
470
|
+
recipient: z.string().describe('Profile ID, DID, email, or phone number (auto-detected)'),
|
|
471
|
+
contractUri: z.string().optional(),
|
|
472
|
+
templateUri: z.string().optional(),
|
|
473
|
+
template: SendBoostTemplateValidator.optional(),
|
|
474
|
+
signedCredential: VCValidator.optional(),
|
|
475
|
+
options: SendOptionsValidator.optional().describe(
|
|
476
|
+
'Options for email/phone recipients (Universal Inbox)'
|
|
477
|
+
),
|
|
478
|
+
templateData: z.record(z.string(), z.unknown()).optional(),
|
|
479
|
+
integrationId: z.string().optional().describe('Integration ID for activity tracking'),
|
|
480
|
+
})
|
|
481
|
+
.refine(data => data.templateUri || data.template || data.signedCredential, {
|
|
482
|
+
message: 'Either templateUri, template, or signedCredential must be provided.',
|
|
483
|
+
path: ['templateUri'],
|
|
484
|
+
})
|
|
485
|
+
.refine(
|
|
486
|
+
data => {
|
|
487
|
+
if (data.options?.guardianEmail) {
|
|
488
|
+
return data.options.guardianEmail.toLowerCase() !== data.recipient.toLowerCase();
|
|
489
|
+
}
|
|
490
|
+
return true;
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
message: 'guardianEmail must differ from recipient (self-approval not allowed)',
|
|
494
|
+
path: ['options', 'guardianEmail'],
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
export type SendBoostInput = z.infer<typeof SendBoostInputValidator>;
|
|
498
|
+
|
|
499
|
+
// Inbox-specific response fields (only present when sent via email/phone)
|
|
500
|
+
export const SendInboxResponseValidator = z.object({
|
|
501
|
+
issuanceId: z.string(),
|
|
502
|
+
status: z.enum(['PENDING', 'ISSUED', 'EXPIRED', 'DELIVERED', 'CLAIMED']),
|
|
503
|
+
claimUrl: z.string().url().optional().describe('Present when suppressDelivery=true'),
|
|
504
|
+
guardianStatus: GuardianStatusValidator.optional().describe(
|
|
505
|
+
'Present when guardianEmail was specified'
|
|
506
|
+
),
|
|
507
|
+
});
|
|
508
|
+
export type SendInboxResponse = z.infer<typeof SendInboxResponseValidator>;
|
|
509
|
+
|
|
510
|
+
export const SendBoostResponseValidator = z.object({
|
|
511
|
+
type: z.literal('boost'),
|
|
512
|
+
credentialUri: z.string(),
|
|
513
|
+
uri: z.string(),
|
|
514
|
+
activityId: z.string().describe('Links to the activity lifecycle for this issuance'),
|
|
515
|
+
inbox: SendInboxResponseValidator.optional().describe(
|
|
516
|
+
'Present when sent via email/phone (Universal Inbox)'
|
|
517
|
+
),
|
|
518
|
+
});
|
|
519
|
+
export type SendBoostResponse = z.infer<typeof SendBoostResponseValidator>;
|
|
520
|
+
|
|
521
|
+
// Plugin-level discriminated union (for extensibility)
|
|
522
|
+
export const SendInputValidator = z.discriminatedUnion('type', [SendBoostInputValidator]);
|
|
523
|
+
export type SendInput = z.infer<typeof SendInputValidator>;
|
|
524
|
+
|
|
525
|
+
export const SendResponseValidator = z.discriminatedUnion('type', [SendBoostResponseValidator]);
|
|
526
|
+
export type SendResponse = z.infer<typeof SendResponseValidator>;
|
|
527
|
+
|
|
528
|
+
export const ConsentFlowTermsStatusValidator = z.enum(['live', 'stale', 'withdrawn']);
|
|
529
|
+
export type ConsentFlowTermsStatus = z.infer<typeof ConsentFlowTermsStatusValidator>;
|
|
530
|
+
|
|
531
|
+
export const ConsentFlowContractValidator = z.object({
|
|
532
|
+
read: z
|
|
533
|
+
.object({
|
|
534
|
+
anonymize: z.boolean().optional(),
|
|
535
|
+
credentials: z
|
|
536
|
+
.object({
|
|
537
|
+
categories: z
|
|
538
|
+
.record(
|
|
539
|
+
z.string(),
|
|
540
|
+
z.object({
|
|
541
|
+
required: z.boolean(),
|
|
542
|
+
defaultEnabled: z.boolean().optional(),
|
|
543
|
+
})
|
|
544
|
+
)
|
|
545
|
+
.default({}),
|
|
546
|
+
})
|
|
547
|
+
.prefault({ categories: {} }),
|
|
548
|
+
personal: z
|
|
549
|
+
.record(
|
|
550
|
+
z.string(),
|
|
551
|
+
z.object({ required: z.boolean(), defaultEnabled: z.boolean().optional() })
|
|
552
|
+
)
|
|
553
|
+
.default({}),
|
|
554
|
+
})
|
|
555
|
+
.prefault({ credentials: { categories: {} }, personal: {} }),
|
|
556
|
+
write: z
|
|
557
|
+
.object({
|
|
558
|
+
credentials: z
|
|
559
|
+
.object({
|
|
560
|
+
categories: z
|
|
561
|
+
.record(
|
|
562
|
+
z.string(),
|
|
563
|
+
z.object({
|
|
564
|
+
required: z.boolean(),
|
|
565
|
+
defaultEnabled: z.boolean().optional(),
|
|
566
|
+
})
|
|
567
|
+
)
|
|
568
|
+
.default({}),
|
|
569
|
+
})
|
|
570
|
+
.prefault({ categories: {} }),
|
|
571
|
+
personal: z
|
|
572
|
+
.record(
|
|
573
|
+
z.string(),
|
|
574
|
+
z.object({ required: z.boolean(), defaultEnabled: z.boolean().optional() })
|
|
575
|
+
)
|
|
576
|
+
.default({}),
|
|
577
|
+
})
|
|
578
|
+
.prefault({ credentials: { categories: {} }, personal: {} }),
|
|
579
|
+
});
|
|
580
|
+
export type ConsentFlowContract = z.infer<typeof ConsentFlowContractValidator>;
|
|
581
|
+
export type ConsentFlowContractInput = z.input<typeof ConsentFlowContractValidator>;
|
|
582
|
+
|
|
583
|
+
export const ConsentFlowContractDetailsValidator = z.object({
|
|
584
|
+
contract: ConsentFlowContractValidator,
|
|
585
|
+
owner: LCNProfileValidator,
|
|
586
|
+
name: z.string(),
|
|
587
|
+
subtitle: z.string().optional(),
|
|
588
|
+
description: z.string().optional(),
|
|
589
|
+
reasonForAccessing: z.string().optional(),
|
|
590
|
+
image: z.string().optional(),
|
|
591
|
+
uri: z.string(),
|
|
592
|
+
needsGuardianConsent: z.boolean().optional(),
|
|
593
|
+
redirectUrl: z.string().optional(),
|
|
594
|
+
frontDoorBoostUri: z.string().optional(),
|
|
595
|
+
createdAt: z.string(),
|
|
596
|
+
updatedAt: z.string(),
|
|
597
|
+
expiresAt: z.string().optional(),
|
|
598
|
+
autoBoosts: z.string().array().optional(),
|
|
599
|
+
writers: z.array(LCNProfileValidator).optional(),
|
|
600
|
+
});
|
|
601
|
+
export type ConsentFlowContractDetails = z.infer<typeof ConsentFlowContractDetailsValidator>;
|
|
602
|
+
export type ConsentFlowContractDetailsInput = z.input<typeof ConsentFlowContractDetailsValidator>;
|
|
603
|
+
|
|
604
|
+
export const ConsentFlowContractRequestStatusValidator = z
|
|
605
|
+
.enum(['pending', 'accepted', 'denied'])
|
|
606
|
+
.nullable();
|
|
607
|
+
export type ConsentFlowContractRequestStatus = z.infer<
|
|
608
|
+
typeof ConsentFlowContractRequestStatusValidator
|
|
609
|
+
>;
|
|
610
|
+
|
|
611
|
+
export const ConsentFlowContractRequestReadStatusValidator = z.enum(['unseen', 'seen']).nullable();
|
|
612
|
+
export type ConsentFlowContractRequestReadStatus = z.infer<
|
|
613
|
+
typeof ConsentFlowContractRequestReadStatusValidator
|
|
614
|
+
>;
|
|
615
|
+
|
|
616
|
+
export const ConsentFlowContractRequestForProfileValidator = z.object({
|
|
617
|
+
profile: LCNProfileValidator,
|
|
618
|
+
status: ConsentFlowContractRequestStatusValidator,
|
|
619
|
+
readStatus: ConsentFlowContractRequestReadStatusValidator.optional(),
|
|
620
|
+
});
|
|
621
|
+
export type ConsentFlowContractRequestForProfile = z.infer<
|
|
622
|
+
typeof ConsentFlowContractRequestForProfileValidator
|
|
623
|
+
>;
|
|
624
|
+
|
|
625
|
+
export const ConsentFlowContractRequestForProfileListValidator = z.array(
|
|
626
|
+
ConsentFlowContractRequestForProfileValidator
|
|
627
|
+
);
|
|
628
|
+
export type ConsentFlowContractRequestForProfileList = z.infer<
|
|
629
|
+
typeof ConsentFlowContractRequestForProfileListValidator
|
|
630
|
+
>;
|
|
631
|
+
|
|
632
|
+
export const PaginatedConsentFlowContractsValidator = PaginationResponseValidator.extend({
|
|
633
|
+
records: ConsentFlowContractDetailsValidator.omit({ owner: true }).array(),
|
|
634
|
+
});
|
|
635
|
+
export type PaginatedConsentFlowContracts = z.infer<typeof PaginatedConsentFlowContractsValidator>;
|
|
636
|
+
|
|
637
|
+
export const ConsentFlowContractDataValidator = z.object({
|
|
638
|
+
credentials: z.object({ categories: z.record(z.string(), z.string().array()).default({}) }),
|
|
639
|
+
personal: z.record(z.string(), z.string()).default({}),
|
|
640
|
+
date: z.string(),
|
|
641
|
+
});
|
|
642
|
+
export type ConsentFlowContractData = z.infer<typeof ConsentFlowContractDataValidator>;
|
|
643
|
+
|
|
644
|
+
export const PaginatedConsentFlowDataValidator = PaginationResponseValidator.extend({
|
|
645
|
+
records: ConsentFlowContractDataValidator.array(),
|
|
646
|
+
});
|
|
647
|
+
export type PaginatedConsentFlowData = z.infer<typeof PaginatedConsentFlowDataValidator>;
|
|
648
|
+
|
|
649
|
+
export const ConsentFlowContractDataForDidValidator = z.object({
|
|
650
|
+
credentials: z.object({ category: z.string(), uri: z.string() }).array(),
|
|
651
|
+
personal: z.record(z.string(), z.string()).default({}),
|
|
652
|
+
date: z.string(),
|
|
653
|
+
contractUri: z.string(),
|
|
654
|
+
});
|
|
655
|
+
export type ConsentFlowContractDataForDid = z.infer<typeof ConsentFlowContractDataForDidValidator>;
|
|
656
|
+
|
|
657
|
+
export const PaginatedConsentFlowDataForDidValidator = PaginationResponseValidator.extend({
|
|
658
|
+
records: ConsentFlowContractDataForDidValidator.array(),
|
|
659
|
+
});
|
|
660
|
+
export type PaginatedConsentFlowDataForDid = z.infer<
|
|
661
|
+
typeof PaginatedConsentFlowDataForDidValidator
|
|
662
|
+
>;
|
|
663
|
+
|
|
664
|
+
export const ConsentFlowTermValidator = z.object({
|
|
665
|
+
sharing: z.boolean().optional(),
|
|
666
|
+
shared: z.string().array().optional(),
|
|
667
|
+
shareAll: z.boolean().optional(),
|
|
668
|
+
shareUntil: z.string().optional(),
|
|
669
|
+
});
|
|
670
|
+
export type ConsentFlowTerm = z.infer<typeof ConsentFlowTermValidator>;
|
|
671
|
+
|
|
672
|
+
export const ConsentFlowTermsValidator = z.object({
|
|
673
|
+
read: z
|
|
674
|
+
.object({
|
|
675
|
+
anonymize: z.boolean().optional(),
|
|
676
|
+
credentials: z
|
|
677
|
+
.object({
|
|
678
|
+
shareAll: z.boolean().optional(),
|
|
679
|
+
sharing: z.boolean().optional(),
|
|
680
|
+
categories: z.record(z.string(), ConsentFlowTermValidator).default({}),
|
|
681
|
+
})
|
|
682
|
+
.prefault({ categories: {} }),
|
|
683
|
+
personal: z.record(z.string(), z.string()).default({}),
|
|
684
|
+
})
|
|
685
|
+
.prefault({ credentials: { categories: {} }, personal: {} }),
|
|
686
|
+
write: z
|
|
687
|
+
.object({
|
|
688
|
+
credentials: z
|
|
689
|
+
.object({ categories: z.record(z.string(), z.boolean()).default({}) })
|
|
690
|
+
.prefault({ categories: {} }),
|
|
691
|
+
personal: z.record(z.string(), z.boolean()).default({}),
|
|
692
|
+
})
|
|
693
|
+
.prefault({ credentials: { categories: {} }, personal: {} }),
|
|
694
|
+
deniedWriters: z.array(z.string()).optional(),
|
|
695
|
+
});
|
|
696
|
+
export type ConsentFlowTerms = z.infer<typeof ConsentFlowTermsValidator>;
|
|
697
|
+
export type ConsentFlowTermsInput = z.input<typeof ConsentFlowTermsValidator>;
|
|
698
|
+
export const PaginatedConsentFlowTermsValidator = PaginationResponseValidator.extend({
|
|
699
|
+
records: z
|
|
700
|
+
.object({
|
|
701
|
+
expiresAt: z.string().optional(),
|
|
702
|
+
oneTime: z.boolean().optional(),
|
|
703
|
+
terms: ConsentFlowTermsValidator,
|
|
704
|
+
contract: ConsentFlowContractDetailsValidator,
|
|
705
|
+
uri: z.string(),
|
|
706
|
+
consenter: LCNProfileValidator,
|
|
707
|
+
status: ConsentFlowTermsStatusValidator,
|
|
708
|
+
})
|
|
709
|
+
.array(),
|
|
710
|
+
});
|
|
711
|
+
export type PaginatedConsentFlowTerms = z.infer<typeof PaginatedConsentFlowTermsValidator>;
|
|
712
|
+
|
|
713
|
+
export const ConsentFlowContractQueryValidator = z.object({
|
|
714
|
+
read: z
|
|
715
|
+
.object({
|
|
716
|
+
anonymize: z.boolean().optional(),
|
|
717
|
+
credentials: z
|
|
718
|
+
.object({
|
|
719
|
+
categories: z
|
|
720
|
+
.record(z.string(), z.object({ required: z.boolean().optional() }))
|
|
721
|
+
.optional(),
|
|
722
|
+
})
|
|
723
|
+
.optional(),
|
|
724
|
+
personal: z
|
|
725
|
+
.record(z.string(), z.object({ required: z.boolean().optional() }))
|
|
726
|
+
.optional(),
|
|
727
|
+
})
|
|
728
|
+
.optional(),
|
|
729
|
+
write: z
|
|
730
|
+
.object({
|
|
731
|
+
credentials: z
|
|
732
|
+
.object({
|
|
733
|
+
categories: z
|
|
734
|
+
.record(z.string(), z.object({ required: z.boolean().optional() }))
|
|
735
|
+
.optional(),
|
|
736
|
+
})
|
|
737
|
+
.optional(),
|
|
738
|
+
personal: z
|
|
739
|
+
.record(z.string(), z.object({ required: z.boolean().optional() }))
|
|
740
|
+
.optional(),
|
|
741
|
+
})
|
|
742
|
+
.optional(),
|
|
743
|
+
});
|
|
744
|
+
export type ConsentFlowContractQuery = z.infer<typeof ConsentFlowContractQueryValidator>;
|
|
745
|
+
export type ConsentFlowContractQueryInput = z.input<typeof ConsentFlowContractQueryValidator>;
|
|
746
|
+
|
|
747
|
+
export const ConsentFlowDataQueryValidator = z.object({
|
|
748
|
+
anonymize: z.boolean().optional(),
|
|
749
|
+
credentials: z.object({ categories: z.record(z.string(), z.boolean()).optional() }).optional(),
|
|
750
|
+
personal: z.record(z.string(), z.boolean()).optional(),
|
|
751
|
+
});
|
|
752
|
+
export type ConsentFlowDataQuery = z.infer<typeof ConsentFlowDataQueryValidator>;
|
|
753
|
+
export type ConsentFlowDataQueryInput = z.input<typeof ConsentFlowDataQueryValidator>;
|
|
754
|
+
|
|
755
|
+
export const ConsentFlowDataForDidQueryValidator = z.object({
|
|
756
|
+
credentials: z.object({ categories: z.record(z.string(), z.boolean()).optional() }).optional(),
|
|
757
|
+
personal: z.record(z.string(), z.boolean()).optional(),
|
|
758
|
+
id: StringQuery.optional(),
|
|
759
|
+
});
|
|
760
|
+
export type ConsentFlowDataForDidQuery = z.infer<typeof ConsentFlowDataForDidQueryValidator>;
|
|
761
|
+
export type ConsentFlowDataForDidQueryInput = z.input<typeof ConsentFlowDataForDidQueryValidator>;
|
|
762
|
+
|
|
763
|
+
export const ConsentFlowTermsQueryValidator = z.object({
|
|
764
|
+
read: z
|
|
765
|
+
.object({
|
|
766
|
+
anonymize: z.boolean().optional(),
|
|
767
|
+
credentials: z
|
|
768
|
+
.object({
|
|
769
|
+
shareAll: z.boolean().optional(),
|
|
770
|
+
sharing: z.boolean().optional(),
|
|
771
|
+
categories: z
|
|
772
|
+
.record(z.string(), ConsentFlowTermValidator.optional())
|
|
773
|
+
.optional(),
|
|
774
|
+
})
|
|
775
|
+
.optional(),
|
|
776
|
+
personal: z.record(z.string(), z.string()).optional(),
|
|
777
|
+
})
|
|
778
|
+
.optional(),
|
|
779
|
+
write: z
|
|
780
|
+
.object({
|
|
781
|
+
credentials: z
|
|
782
|
+
.object({ categories: z.record(z.string(), z.boolean()).optional() })
|
|
783
|
+
.optional(),
|
|
784
|
+
personal: z.record(z.string(), z.boolean()).optional(),
|
|
785
|
+
})
|
|
786
|
+
.optional(),
|
|
787
|
+
});
|
|
788
|
+
export type ConsentFlowTermsQuery = z.infer<typeof ConsentFlowTermsQueryValidator>;
|
|
789
|
+
export type ConsentFlowTermsQueryInput = z.input<typeof ConsentFlowTermsQueryValidator>;
|
|
790
|
+
|
|
791
|
+
export const ConsentFlowTransactionActionValidator = z.enum([
|
|
792
|
+
'consent',
|
|
793
|
+
'update',
|
|
794
|
+
'sync',
|
|
795
|
+
'withdraw',
|
|
796
|
+
'write',
|
|
797
|
+
]);
|
|
798
|
+
export type ConsentFlowTransactionAction = z.infer<typeof ConsentFlowTransactionActionValidator>;
|
|
799
|
+
|
|
800
|
+
export const ConsentFlowTransactionsQueryValidator = z.object({
|
|
801
|
+
terms: ConsentFlowTermsQueryValidator.optional(),
|
|
802
|
+
action: ConsentFlowTransactionActionValidator.or(
|
|
803
|
+
ConsentFlowTransactionActionValidator.array()
|
|
804
|
+
).optional(),
|
|
805
|
+
date: z
|
|
806
|
+
.object({ $gt: z.string() })
|
|
807
|
+
.or(z.object({ $lt: z.string() }))
|
|
808
|
+
.or(z.object({ $eq: z.string() }))
|
|
809
|
+
.optional(),
|
|
810
|
+
expiresAt: z
|
|
811
|
+
.object({ $gt: z.string() })
|
|
812
|
+
.or(z.object({ $lt: z.string() }))
|
|
813
|
+
.or(z.object({ $eq: z.string() }))
|
|
814
|
+
.optional(),
|
|
815
|
+
oneTime: z.boolean().optional(),
|
|
816
|
+
});
|
|
817
|
+
export type ConsentFlowTransactionsQuery = z.infer<typeof ConsentFlowTransactionsQueryValidator>;
|
|
818
|
+
export type ConsentFlowTransactionsQueryInput = z.input<
|
|
819
|
+
typeof ConsentFlowTransactionsQueryValidator
|
|
820
|
+
>;
|
|
821
|
+
|
|
822
|
+
export const ConsentFlowTransactionValidator = z.object({
|
|
823
|
+
expiresAt: z.string().optional(),
|
|
824
|
+
oneTime: z.boolean().optional(),
|
|
825
|
+
terms: ConsentFlowTermsValidator.optional(),
|
|
826
|
+
id: z.string(),
|
|
827
|
+
action: ConsentFlowTransactionActionValidator,
|
|
828
|
+
date: z.string(),
|
|
829
|
+
uris: z.string().array().optional(),
|
|
830
|
+
});
|
|
831
|
+
export type ConsentFlowTransaction = z.infer<typeof ConsentFlowTransactionValidator>;
|
|
832
|
+
|
|
833
|
+
export const HolderExportConsentRecordValidator = z.object({
|
|
834
|
+
termsUri: z.string(),
|
|
835
|
+
status: ConsentFlowTermsStatusValidator,
|
|
836
|
+
contract: ConsentFlowContractDetailsValidator,
|
|
837
|
+
terms: ConsentFlowTermsValidator,
|
|
838
|
+
transactions: ConsentFlowTransactionValidator.array(),
|
|
839
|
+
});
|
|
840
|
+
export type HolderExportConsentRecord = z.infer<typeof HolderExportConsentRecordValidator>;
|
|
841
|
+
|
|
842
|
+
export const HolderExportMetadataValidator = z.object({
|
|
843
|
+
consentRecords: HolderExportConsentRecordValidator.array(),
|
|
844
|
+
truncated: z.boolean().optional(),
|
|
845
|
+
warnings: z.string().array().optional(),
|
|
846
|
+
limits: z
|
|
847
|
+
.object({
|
|
848
|
+
maxConsentRecords: z.number(),
|
|
849
|
+
maxTransactionsPerConsentRecord: z.number(),
|
|
850
|
+
})
|
|
851
|
+
.optional(),
|
|
852
|
+
});
|
|
853
|
+
export type HolderExportMetadata = z.infer<typeof HolderExportMetadataValidator>;
|
|
854
|
+
|
|
855
|
+
export const PaginatedConsentFlowTransactionsValidator = PaginationResponseValidator.extend({
|
|
856
|
+
records: ConsentFlowTransactionValidator.array(),
|
|
857
|
+
});
|
|
858
|
+
export type PaginatedConsentFlowTransactions = z.infer<
|
|
859
|
+
typeof PaginatedConsentFlowTransactionsValidator
|
|
860
|
+
>;
|
|
861
|
+
|
|
862
|
+
// Skill Frameworks: Query + Paginated types
|
|
863
|
+
const BaseSkillFrameworkQueryValidator = z
|
|
864
|
+
.object({
|
|
865
|
+
id: StringQuery,
|
|
866
|
+
name: StringQuery,
|
|
867
|
+
description: StringQuery,
|
|
868
|
+
sourceURI: StringQuery,
|
|
869
|
+
status: StringQuery,
|
|
870
|
+
})
|
|
871
|
+
.partial();
|
|
872
|
+
|
|
873
|
+
export const SkillFrameworkQueryValidator = z.union([
|
|
874
|
+
z.object({ $or: BaseSkillFrameworkQueryValidator.array() }),
|
|
875
|
+
BaseSkillFrameworkQueryValidator,
|
|
876
|
+
]);
|
|
877
|
+
export type SkillFrameworkQuery = z.infer<typeof SkillFrameworkQueryValidator>;
|
|
878
|
+
|
|
879
|
+
// moved below SkillFrameworkValidator
|
|
880
|
+
|
|
881
|
+
export const ContractCredentialValidator = z.object({
|
|
882
|
+
credentialUri: z.string(),
|
|
883
|
+
termsUri: z.string(),
|
|
884
|
+
contractUri: z.string(),
|
|
885
|
+
boostUri: z.string(),
|
|
886
|
+
category: z.string().optional(),
|
|
887
|
+
date: z.string(),
|
|
888
|
+
});
|
|
889
|
+
export type ContractCredential = z.infer<typeof ContractCredentialValidator>;
|
|
890
|
+
|
|
891
|
+
export const PaginatedContractCredentialsValidator = PaginationResponseValidator.extend({
|
|
892
|
+
records: ContractCredentialValidator.array(),
|
|
893
|
+
});
|
|
894
|
+
export type PaginatedContractCredentials = z.infer<typeof PaginatedContractCredentialsValidator>;
|
|
895
|
+
|
|
896
|
+
export const LCNNotificationTypeEnumValidator = z.enum([
|
|
897
|
+
'CONNECTION_REQUEST',
|
|
898
|
+
'CONNECTION_REQUEST_EXPIRED_INVITE',
|
|
899
|
+
'CONNECTION_ACCEPTED',
|
|
900
|
+
'CREDENTIAL_RECEIVED',
|
|
901
|
+
'CREDENTIAL_ACCEPTED',
|
|
902
|
+
'BOOST_RECEIVED',
|
|
903
|
+
'BOOST_ACCEPTED',
|
|
904
|
+
'PRESENTATION_REQUEST',
|
|
905
|
+
'PRESENTATION_RECEIVED',
|
|
906
|
+
'CONSENT_FLOW_TRANSACTION',
|
|
907
|
+
'ISSUANCE_CLAIMED',
|
|
908
|
+
'ISSUANCE_DELIVERED',
|
|
909
|
+
'ISSUANCE_ERROR',
|
|
910
|
+
'PROFILE_PARENT_APPROVED',
|
|
911
|
+
'APP_LISTING_SUBMITTED',
|
|
912
|
+
'APP_LISTING_APPROVED',
|
|
913
|
+
'APP_LISTING_REJECTED',
|
|
914
|
+
'APP_LISTING_WITHDRAWN',
|
|
915
|
+
'DEVICE_LINK_REQUEST',
|
|
916
|
+
'GUARDIAN_APPROVAL_PENDING',
|
|
917
|
+
'GUARDIAN_APPROVED',
|
|
918
|
+
'GUARDIAN_REJECTED',
|
|
919
|
+
'APP_NOTIFICATION',
|
|
920
|
+
]);
|
|
921
|
+
|
|
922
|
+
export type LCNNotificationTypeEnum = z.infer<typeof LCNNotificationTypeEnumValidator>;
|
|
923
|
+
|
|
924
|
+
export const LCNNotificationMessageValidator = z.object({
|
|
925
|
+
title: z.string().optional(),
|
|
926
|
+
body: z.string().optional(),
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
export type LCNNotificationMessage = z.infer<typeof LCNNotificationMessageValidator>;
|
|
930
|
+
|
|
931
|
+
export const LCNInboxContactMethodValidator = z.object({
|
|
932
|
+
type: z.string(),
|
|
933
|
+
value: z.string(),
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
export type LCNInboxContactMethod = z.infer<typeof LCNInboxContactMethodValidator>;
|
|
937
|
+
|
|
938
|
+
export const LCNInboxStatusEnumValidator = z.enum([
|
|
939
|
+
'PENDING',
|
|
940
|
+
'ISSUED',
|
|
941
|
+
'EXPIRED',
|
|
942
|
+
/* DEPRECATED — use ISSUED */ 'DELIVERED',
|
|
943
|
+
/* DEPRECATED — use ISSUED */ 'CLAIMED',
|
|
944
|
+
]);
|
|
945
|
+
export type LCNInboxStatusEnum = z.infer<typeof LCNInboxStatusEnumValidator>;
|
|
946
|
+
|
|
947
|
+
export const LCNNotificationInboxValidator = z.object({
|
|
948
|
+
issuanceId: z.string(),
|
|
949
|
+
status: LCNInboxStatusEnumValidator,
|
|
950
|
+
recipient: z.object({
|
|
951
|
+
contactMethod: LCNInboxContactMethodValidator.optional(),
|
|
952
|
+
learnCardId: z.string().optional(),
|
|
953
|
+
}),
|
|
954
|
+
timestamp: z.iso.datetime().optional(),
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
export type LCNNotificationInbox = z.infer<typeof LCNNotificationInboxValidator>;
|
|
958
|
+
|
|
959
|
+
export const LCNNotificationDataValidator = z
|
|
960
|
+
.object({
|
|
961
|
+
vcUris: z.array(z.string()).optional(),
|
|
962
|
+
vpUris: z.array(z.string()).optional(),
|
|
963
|
+
transaction: ConsentFlowTransactionValidator.optional(),
|
|
964
|
+
inbox: LCNNotificationInboxValidator.optional(),
|
|
965
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
966
|
+
})
|
|
967
|
+
.loose();
|
|
968
|
+
export type LCNNotificationData = z.infer<typeof LCNNotificationDataValidator>;
|
|
969
|
+
|
|
970
|
+
export const LCNNotificationValidator = z.object({
|
|
971
|
+
type: LCNNotificationTypeEnumValidator,
|
|
972
|
+
to: LCNProfileValidator.partial().and(z.object({ did: z.string() })),
|
|
973
|
+
from: z.union([z.string(), LCNProfileValidator.partial().and(z.object({ did: z.string() }))]),
|
|
974
|
+
message: LCNNotificationMessageValidator.optional(),
|
|
975
|
+
data: LCNNotificationDataValidator.optional(),
|
|
976
|
+
sent: z.iso.datetime().optional(),
|
|
977
|
+
webhookUrl: z.string().optional(),
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
export type LCNNotification = z.infer<typeof LCNNotificationValidator>;
|
|
981
|
+
|
|
982
|
+
export const AUTH_GRANT_AUDIENCE_DOMAIN_PREFIX = 'auth-grant:';
|
|
983
|
+
|
|
984
|
+
export const AuthGrantValidator = z.object({
|
|
985
|
+
id: z.string(),
|
|
986
|
+
name: z.string(),
|
|
987
|
+
description: z.string().optional(),
|
|
988
|
+
challenge: z
|
|
989
|
+
.string()
|
|
990
|
+
.startsWith(AUTH_GRANT_AUDIENCE_DOMAIN_PREFIX)
|
|
991
|
+
.min(10, { message: 'Challenge is too short' })
|
|
992
|
+
.max(100, { message: 'Challenge is too long' }),
|
|
993
|
+
status: z.enum(['revoked', 'active'], {
|
|
994
|
+
error: issue => {
|
|
995
|
+
if (issue.code === 'invalid_value') return 'Status must be either active or revoked';
|
|
996
|
+
return 'Status is required';
|
|
997
|
+
},
|
|
998
|
+
}),
|
|
999
|
+
scope: z.string(),
|
|
1000
|
+
createdAt: z.iso.datetime({ error: 'createdAt must be a valid ISO 8601 datetime string' }),
|
|
1001
|
+
expiresAt: z.iso
|
|
1002
|
+
.datetime({ error: 'expiresAt must be a valid ISO 8601 datetime string' })
|
|
1003
|
+
.nullish()
|
|
1004
|
+
.optional(),
|
|
1005
|
+
});
|
|
1006
|
+
export type AuthGrantType = z.infer<typeof AuthGrantValidator>;
|
|
1007
|
+
|
|
1008
|
+
export const FlatAuthGrantValidator = z.object({ id: z.string() }).catchall(z.any());
|
|
1009
|
+
export type FlatAuthGrantType = z.infer<typeof FlatAuthGrantValidator>;
|
|
1010
|
+
|
|
1011
|
+
export const AuthGrantStatusValidator = z.enum(['active', 'revoked']);
|
|
1012
|
+
|
|
1013
|
+
export type AuthGrantStatus = z.infer<typeof AuthGrantStatusValidator>;
|
|
1014
|
+
|
|
1015
|
+
export const AuthGrantQueryValidator = z
|
|
1016
|
+
.object({
|
|
1017
|
+
id: StringQuery,
|
|
1018
|
+
name: StringQuery,
|
|
1019
|
+
description: StringQuery,
|
|
1020
|
+
status: AuthGrantStatusValidator,
|
|
1021
|
+
})
|
|
1022
|
+
.partial();
|
|
1023
|
+
|
|
1024
|
+
export type AuthGrantQuery = z.infer<typeof AuthGrantQueryValidator>;
|
|
1025
|
+
|
|
1026
|
+
// Contact Methods
|
|
1027
|
+
const contactMethodBase = z.object({
|
|
1028
|
+
id: z.string(),
|
|
1029
|
+
isVerified: z.boolean(),
|
|
1030
|
+
verifiedAt: z.string().optional(),
|
|
1031
|
+
isPrimary: z.boolean(),
|
|
1032
|
+
createdAt: z.string(),
|
|
1033
|
+
});
|
|
1034
|
+
|
|
1035
|
+
export const ContactMethodValidator = z.discriminatedUnion('type', [
|
|
1036
|
+
z
|
|
1037
|
+
.object({
|
|
1038
|
+
type: z.literal('email'),
|
|
1039
|
+
value: z.string().email(),
|
|
1040
|
+
})
|
|
1041
|
+
.merge(contactMethodBase),
|
|
1042
|
+
z
|
|
1043
|
+
.object({
|
|
1044
|
+
type: z.literal('phone'),
|
|
1045
|
+
value: z.string(), // Can be improved with a regex later
|
|
1046
|
+
})
|
|
1047
|
+
.merge(contactMethodBase),
|
|
1048
|
+
]);
|
|
1049
|
+
|
|
1050
|
+
export type ContactMethodType = z.infer<typeof ContactMethodValidator>;
|
|
1051
|
+
|
|
1052
|
+
const createContactMethodBase = z.object({
|
|
1053
|
+
isVerified: z.boolean().optional(),
|
|
1054
|
+
isPrimary: z.boolean().optional(),
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
export const ContactMethodCreateValidator = z.discriminatedUnion('type', [
|
|
1058
|
+
z
|
|
1059
|
+
.object({
|
|
1060
|
+
type: z.literal('email'),
|
|
1061
|
+
value: z.string().email(),
|
|
1062
|
+
})
|
|
1063
|
+
.merge(createContactMethodBase),
|
|
1064
|
+
z
|
|
1065
|
+
.object({
|
|
1066
|
+
type: z.literal('phone'),
|
|
1067
|
+
value: z.string(),
|
|
1068
|
+
})
|
|
1069
|
+
.merge(createContactMethodBase),
|
|
1070
|
+
]);
|
|
1071
|
+
|
|
1072
|
+
export type ContactMethodCreateType = z.infer<typeof ContactMethodCreateValidator>;
|
|
1073
|
+
|
|
1074
|
+
export const ContactMethodQueryValidator = z.discriminatedUnion('type', [
|
|
1075
|
+
z.object({
|
|
1076
|
+
type: z.literal('email'),
|
|
1077
|
+
value: z.string().email(),
|
|
1078
|
+
}),
|
|
1079
|
+
z.object({
|
|
1080
|
+
type: z.literal('phone'),
|
|
1081
|
+
value: z.string(),
|
|
1082
|
+
}),
|
|
1083
|
+
]);
|
|
1084
|
+
|
|
1085
|
+
export type ContactMethodQueryType = z.infer<typeof ContactMethodQueryValidator>;
|
|
1086
|
+
|
|
1087
|
+
export const ContactMethodVerificationRequestValidator = z.object({
|
|
1088
|
+
value: z.string(),
|
|
1089
|
+
type: z.enum(['email', 'phone']),
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
export type ContactMethodVerificationRequestType = z.infer<
|
|
1093
|
+
typeof ContactMethodVerificationRequestValidator
|
|
1094
|
+
>;
|
|
1095
|
+
|
|
1096
|
+
export const ContactMethodVerificationValidator = z.object({
|
|
1097
|
+
token: z.string(),
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
export type ContactMethodVerificationType = z.infer<typeof ContactMethodVerificationValidator>;
|
|
1101
|
+
|
|
1102
|
+
export const SetPrimaryContactMethodValidator = z.object({
|
|
1103
|
+
contactMethodId: z.string(),
|
|
1104
|
+
});
|
|
1105
|
+
|
|
1106
|
+
export type SetPrimaryContactMethodType = z.infer<typeof SetPrimaryContactMethodValidator>;
|
|
1107
|
+
|
|
1108
|
+
// Create Inbox Claim Session for a Contact Method
|
|
1109
|
+
export const CreateContactMethodSessionValidator = z.object({
|
|
1110
|
+
contactMethod: ContactMethodVerificationRequestValidator,
|
|
1111
|
+
otpChallenge: z.string(),
|
|
1112
|
+
});
|
|
1113
|
+
|
|
1114
|
+
export type CreateContactMethodSessionType = z.infer<typeof CreateContactMethodSessionValidator>;
|
|
1115
|
+
|
|
1116
|
+
export const CreateContactMethodSessionResponseValidator = z.object({
|
|
1117
|
+
sessionJwt: z.string(),
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
export type CreateContactMethodSessionResponseType = z.infer<
|
|
1121
|
+
typeof CreateContactMethodSessionResponseValidator
|
|
1122
|
+
>;
|
|
1123
|
+
|
|
1124
|
+
// Inbox Credentials
|
|
1125
|
+
export const InboxCredentialValidator = z.object({
|
|
1126
|
+
id: z.string(),
|
|
1127
|
+
credential: z.string(),
|
|
1128
|
+
isSigned: z.boolean(),
|
|
1129
|
+
currentStatus: LCNInboxStatusEnumValidator,
|
|
1130
|
+
isAccepted: z.boolean().optional(),
|
|
1131
|
+
expiresAt: z.string(),
|
|
1132
|
+
createdAt: z.string(),
|
|
1133
|
+
issuerDid: z.string(),
|
|
1134
|
+
webhookUrl: z.string().optional(),
|
|
1135
|
+
boostUri: z.string().optional(),
|
|
1136
|
+
activityId: z.string().optional(),
|
|
1137
|
+
integrationId: z.string().optional(),
|
|
1138
|
+
signingAuthority: z
|
|
1139
|
+
.object({
|
|
1140
|
+
endpoint: z.string().optional(),
|
|
1141
|
+
name: z.string().optional(),
|
|
1142
|
+
})
|
|
1143
|
+
.optional(),
|
|
1144
|
+
// Guardian gate fields (all optional — absent on pre-existing credentials)
|
|
1145
|
+
guardianEmail: z.string().email().optional(),
|
|
1146
|
+
guardianStatus: GuardianStatusValidator.optional(),
|
|
1147
|
+
guardianApprovedAt: z.string().optional(),
|
|
1148
|
+
guardianApprovedByDid: z.string().optional(),
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1151
|
+
export type InboxCredentialType = z.infer<typeof InboxCredentialValidator>;
|
|
1152
|
+
|
|
1153
|
+
export const PaginatedInboxCredentialsValidator = z.object({
|
|
1154
|
+
hasMore: z.boolean(),
|
|
1155
|
+
records: z.array(InboxCredentialValidator),
|
|
1156
|
+
cursor: z.string().optional(),
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
export type PaginatedInboxCredentialsType = z.infer<typeof PaginatedInboxCredentialsValidator>;
|
|
1160
|
+
|
|
1161
|
+
export const InboxCredentialQueryValidator = z
|
|
1162
|
+
.object({
|
|
1163
|
+
currentStatus: LCNInboxStatusEnumValidator,
|
|
1164
|
+
id: z.string(),
|
|
1165
|
+
isSigned: z.boolean(),
|
|
1166
|
+
isAccepted: z.boolean().optional(),
|
|
1167
|
+
issuerDid: z.string(),
|
|
1168
|
+
boostUri: z.string(),
|
|
1169
|
+
})
|
|
1170
|
+
.partial();
|
|
1171
|
+
|
|
1172
|
+
export type InboxCredentialQuery = z.infer<typeof InboxCredentialQueryValidator>;
|
|
1173
|
+
|
|
1174
|
+
export const IssueInboxSigningAuthorityValidator = z.object({
|
|
1175
|
+
endpoint: z.string().url(),
|
|
1176
|
+
name: z.string(),
|
|
1177
|
+
});
|
|
1178
|
+
|
|
1179
|
+
export type IssueInboxSigningAuthority = z.infer<typeof IssueInboxSigningAuthorityValidator>;
|
|
1180
|
+
|
|
1181
|
+
export const IssueInboxCredentialValidator = z
|
|
1182
|
+
.object({
|
|
1183
|
+
// === CORE DATA (Required) ===
|
|
1184
|
+
// WHAT is being sent and WHO is it for?
|
|
1185
|
+
recipient: ContactMethodQueryValidator.describe('The recipient of the credential'),
|
|
1186
|
+
|
|
1187
|
+
// Either credential OR templateUri must be provided
|
|
1188
|
+
credential: VCValidator.or(VPValidator)
|
|
1189
|
+
.or(UnsignedVCValidator)
|
|
1190
|
+
.optional()
|
|
1191
|
+
.describe(
|
|
1192
|
+
'The credential to issue. If not signed, the users default signing authority will be used, or the specified signing authority in the configuration.'
|
|
1193
|
+
),
|
|
1194
|
+
templateUri: z
|
|
1195
|
+
.string()
|
|
1196
|
+
.optional()
|
|
1197
|
+
.describe(
|
|
1198
|
+
'URI of a boost template to use for issuance. The boost credential will be resolved and used. Mutually exclusive with credential field.'
|
|
1199
|
+
),
|
|
1200
|
+
|
|
1201
|
+
// === OPTIONAL FEATURES ===
|
|
1202
|
+
// Add major, distinct features at the top level.
|
|
1203
|
+
//consentRequest: ConsentRequestValidator.optional(),
|
|
1204
|
+
|
|
1205
|
+
// === PROCESS CONFIGURATION (Optional) ===
|
|
1206
|
+
// HOW should this issuance be handled?
|
|
1207
|
+
configuration: z
|
|
1208
|
+
.object({
|
|
1209
|
+
signingAuthority: IssueInboxSigningAuthorityValidator.optional().describe(
|
|
1210
|
+
'The signing authority to use for the credential. If not provided, the users default signing authority will be used if the credential is not signed.'
|
|
1211
|
+
),
|
|
1212
|
+
webhookUrl: z
|
|
1213
|
+
.string()
|
|
1214
|
+
.url()
|
|
1215
|
+
.optional()
|
|
1216
|
+
.describe('The webhook URL to receive credential issuance events.'),
|
|
1217
|
+
expiresInDays: z
|
|
1218
|
+
.number()
|
|
1219
|
+
.min(1)
|
|
1220
|
+
.max(365)
|
|
1221
|
+
.optional()
|
|
1222
|
+
.describe('The number of days the credential will be valid for.'),
|
|
1223
|
+
templateData: z
|
|
1224
|
+
.record(z.string(), z.unknown())
|
|
1225
|
+
.optional()
|
|
1226
|
+
.describe(
|
|
1227
|
+
'Template data to render into the boost credential template using Mustache syntax. Only used when boostUri is provided.'
|
|
1228
|
+
),
|
|
1229
|
+
// --- For User-Facing Delivery (Email/SMS) ---
|
|
1230
|
+
delivery: z
|
|
1231
|
+
.object({
|
|
1232
|
+
suppress: z
|
|
1233
|
+
.boolean()
|
|
1234
|
+
.optional()
|
|
1235
|
+
.default(false)
|
|
1236
|
+
.describe(
|
|
1237
|
+
'Whether to suppress delivery of the credential to the recipient. If true, the email/sms will not be sent to the recipient. Useful if you would like to manually send claim link to your users.'
|
|
1238
|
+
),
|
|
1239
|
+
template: z
|
|
1240
|
+
.object({
|
|
1241
|
+
id: z
|
|
1242
|
+
.enum(['universal-inbox-claim'])
|
|
1243
|
+
.optional()
|
|
1244
|
+
.describe(
|
|
1245
|
+
'The template ID to use for the credential delivery. If not provided, the default template will be used.'
|
|
1246
|
+
),
|
|
1247
|
+
model: z
|
|
1248
|
+
.object({
|
|
1249
|
+
issuer: z
|
|
1250
|
+
.object({
|
|
1251
|
+
name: z
|
|
1252
|
+
.string()
|
|
1253
|
+
.optional()
|
|
1254
|
+
.describe(
|
|
1255
|
+
'The name of the organization (e.g., "State University").'
|
|
1256
|
+
),
|
|
1257
|
+
logoUrl: z
|
|
1258
|
+
.string()
|
|
1259
|
+
.url()
|
|
1260
|
+
.optional()
|
|
1261
|
+
.describe(
|
|
1262
|
+
"The URL of the organization's logo."
|
|
1263
|
+
),
|
|
1264
|
+
})
|
|
1265
|
+
.optional(),
|
|
1266
|
+
credential: z
|
|
1267
|
+
.object({
|
|
1268
|
+
name: z
|
|
1269
|
+
.string()
|
|
1270
|
+
.optional()
|
|
1271
|
+
.describe(
|
|
1272
|
+
'The name of the credential (e.g., "Bachelor of Science").'
|
|
1273
|
+
),
|
|
1274
|
+
type: z
|
|
1275
|
+
.string()
|
|
1276
|
+
.optional()
|
|
1277
|
+
.describe(
|
|
1278
|
+
'The type of the credential (e.g., "degree", "certificate").'
|
|
1279
|
+
),
|
|
1280
|
+
})
|
|
1281
|
+
.optional(),
|
|
1282
|
+
recipient: z
|
|
1283
|
+
.object({
|
|
1284
|
+
name: z
|
|
1285
|
+
.string()
|
|
1286
|
+
.optional()
|
|
1287
|
+
.describe(
|
|
1288
|
+
'The name of the recipient (e.g., "John Doe").'
|
|
1289
|
+
),
|
|
1290
|
+
})
|
|
1291
|
+
.optional(),
|
|
1292
|
+
})
|
|
1293
|
+
.describe(
|
|
1294
|
+
'The template model to use for the credential delivery. Injects via template variables into email/sms templates. If not provided, the default template will be used.'
|
|
1295
|
+
),
|
|
1296
|
+
})
|
|
1297
|
+
.optional()
|
|
1298
|
+
.describe(
|
|
1299
|
+
'The template to use for the credential delivery. If not provided, the default template will be used.'
|
|
1300
|
+
),
|
|
1301
|
+
})
|
|
1302
|
+
.optional()
|
|
1303
|
+
.describe(
|
|
1304
|
+
'Configuration for the credential delivery i.e. email or SMS. When credentials are sent to a user who has a verified email or phone associated with their account, delivery is skipped, and the credential will be sent using in-app notifications. If not provided, the default configuration will be used.'
|
|
1305
|
+
),
|
|
1306
|
+
})
|
|
1307
|
+
.optional()
|
|
1308
|
+
.describe(
|
|
1309
|
+
'Configuration for the credential issuance. If not provided, the default configuration will be used.'
|
|
1310
|
+
),
|
|
1311
|
+
})
|
|
1312
|
+
.refine(data => data.credential || data.templateUri, {
|
|
1313
|
+
message: 'Either credential or templateUri must be provided.',
|
|
1314
|
+
path: ['credential'],
|
|
1315
|
+
});
|
|
1316
|
+
|
|
1317
|
+
export type IssueInboxCredentialType = z.infer<typeof IssueInboxCredentialValidator>;
|
|
1318
|
+
|
|
1319
|
+
export const IssueInboxCredentialResponseValidator = z.object({
|
|
1320
|
+
issuanceId: z.string(),
|
|
1321
|
+
status: LCNInboxStatusEnumValidator,
|
|
1322
|
+
recipient: ContactMethodQueryValidator,
|
|
1323
|
+
claimUrl: z.string().url().optional(),
|
|
1324
|
+
recipientDid: z.string().optional(),
|
|
1325
|
+
});
|
|
1326
|
+
|
|
1327
|
+
export type IssueInboxCredentialResponseType = z.infer<
|
|
1328
|
+
typeof IssueInboxCredentialResponseValidator
|
|
1329
|
+
>;
|
|
1330
|
+
|
|
1331
|
+
/** A simple name reference that the server resolves to a boost template */
|
|
1332
|
+
export const CredentialNameRefValidator = z.object({ name: z.string() }).passthrough();
|
|
1333
|
+
|
|
1334
|
+
export const ClaimInboxCredentialValidator = z.object({
|
|
1335
|
+
credential: VCValidator.or(VPValidator)
|
|
1336
|
+
.or(UnsignedVCValidator)
|
|
1337
|
+
.or(CredentialNameRefValidator)
|
|
1338
|
+
.describe('The credential to issue, or a { name } reference to resolve a boost template.'),
|
|
1339
|
+
configuration: z
|
|
1340
|
+
.object({
|
|
1341
|
+
publishableKey: z.string(),
|
|
1342
|
+
signingAuthorityName: z.string().optional(),
|
|
1343
|
+
listingId: z.string().optional(),
|
|
1344
|
+
listingSlug: z.string().optional(),
|
|
1345
|
+
})
|
|
1346
|
+
.optional(),
|
|
1347
|
+
});
|
|
1348
|
+
|
|
1349
|
+
export type ClaimInboxCredentialType = z.infer<typeof ClaimInboxCredentialValidator>;
|
|
1350
|
+
|
|
1351
|
+
// Integrations
|
|
1352
|
+
export const LCNDomainOrOriginValidator = z.union([
|
|
1353
|
+
z
|
|
1354
|
+
.string()
|
|
1355
|
+
.regex(
|
|
1356
|
+
/^(?:(?:[a-zA-Z0-9-]{1,63}\.)+[a-zA-Z]{2,63}|localhost|\d{1,3}(?:\.\d{1,3}){3})(?::\d{1,5})?$/,
|
|
1357
|
+
{
|
|
1358
|
+
message:
|
|
1359
|
+
'Must be a valid domain (incl. subdomains), localhost, or IPv4, optionally with port',
|
|
1360
|
+
}
|
|
1361
|
+
),
|
|
1362
|
+
z
|
|
1363
|
+
.string()
|
|
1364
|
+
.regex(
|
|
1365
|
+
/^https?:\/\/(?:(?:[a-zA-Z0-9-]{1,63}\.)+[a-zA-Z]{2,63}|localhost|\d{1,3}(?:\.\d{1,3}){3})(?::\d{1,5})?$/,
|
|
1366
|
+
{ message: 'Must be a valid http(s) origin' }
|
|
1367
|
+
),
|
|
1368
|
+
]);
|
|
1369
|
+
|
|
1370
|
+
export const LCNIntegrationStatusEnum = z.enum(['setup', 'active', 'paused']);
|
|
1371
|
+
export type LCNIntegrationStatus = z.infer<typeof LCNIntegrationStatusEnum>;
|
|
1372
|
+
|
|
1373
|
+
export const LCNIntegrationValidator = z.object({
|
|
1374
|
+
id: z.string(),
|
|
1375
|
+
name: z.string(),
|
|
1376
|
+
description: z.string().optional(),
|
|
1377
|
+
publishableKey: z.string(),
|
|
1378
|
+
whitelistedDomains: z.array(LCNDomainOrOriginValidator).default([]),
|
|
1379
|
+
|
|
1380
|
+
// Setup/onboarding status
|
|
1381
|
+
status: LCNIntegrationStatusEnum.default('setup'),
|
|
1382
|
+
guideType: z.string().optional(),
|
|
1383
|
+
guideState: z.record(z.string(), z.any()).optional(),
|
|
1384
|
+
|
|
1385
|
+
// Timestamps
|
|
1386
|
+
createdAt: z.string().optional(),
|
|
1387
|
+
updatedAt: z.string().optional(),
|
|
1388
|
+
});
|
|
1389
|
+
|
|
1390
|
+
export type LCNIntegration = z.infer<typeof LCNIntegrationValidator>;
|
|
1391
|
+
|
|
1392
|
+
export const LCNIntegrationCreateValidator = z.object({
|
|
1393
|
+
name: z.string(),
|
|
1394
|
+
description: z.string().optional(),
|
|
1395
|
+
whitelistedDomains: z.array(LCNDomainOrOriginValidator).default([]),
|
|
1396
|
+
guideType: z.string().optional(),
|
|
1397
|
+
});
|
|
1398
|
+
|
|
1399
|
+
export type LCNIntegrationCreateType = z.infer<typeof LCNIntegrationCreateValidator>;
|
|
1400
|
+
|
|
1401
|
+
export const LCNIntegrationUpdateValidator = z.object({
|
|
1402
|
+
name: z.string().optional(),
|
|
1403
|
+
description: z.string().optional(),
|
|
1404
|
+
whitelistedDomains: z.array(LCNDomainOrOriginValidator).optional(),
|
|
1405
|
+
rotatePublishableKey: z.boolean().optional(),
|
|
1406
|
+
|
|
1407
|
+
// Setup/onboarding updates
|
|
1408
|
+
status: LCNIntegrationStatusEnum.optional(),
|
|
1409
|
+
guideType: z.string().optional(),
|
|
1410
|
+
guideState: z.record(z.string(), z.any()).optional(),
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
export type LCNIntegrationUpdateType = z.infer<typeof LCNIntegrationUpdateValidator>;
|
|
1414
|
+
|
|
1415
|
+
export const LCNIntegrationQueryValidator = z
|
|
1416
|
+
.object({
|
|
1417
|
+
id: StringQuery,
|
|
1418
|
+
name: StringQuery,
|
|
1419
|
+
description: StringQuery,
|
|
1420
|
+
status: StringQuery,
|
|
1421
|
+
guideType: StringQuery,
|
|
1422
|
+
})
|
|
1423
|
+
.partial();
|
|
1424
|
+
|
|
1425
|
+
export type LCNIntegrationQueryType = z.infer<typeof LCNIntegrationQueryValidator>;
|
|
1426
|
+
|
|
1427
|
+
export const PaginatedLCNIntegrationsValidator = PaginationResponseValidator.extend({
|
|
1428
|
+
records: LCNIntegrationValidator.array(),
|
|
1429
|
+
});
|
|
1430
|
+
|
|
1431
|
+
export type PaginatedLCNIntegrationsType = z.infer<typeof PaginatedLCNIntegrationsValidator>;
|
|
1432
|
+
|
|
1433
|
+
export const ClaimTokenValidator = z.object({
|
|
1434
|
+
token: z.string(),
|
|
1435
|
+
contactMethodId: z.string(),
|
|
1436
|
+
autoVerifyContactMethod: z.boolean().optional().default(false),
|
|
1437
|
+
createdAt: z.string(),
|
|
1438
|
+
expiresAt: z.string(),
|
|
1439
|
+
used: z.boolean(),
|
|
1440
|
+
});
|
|
1441
|
+
|
|
1442
|
+
export type ClaimTokenType = z.infer<typeof ClaimTokenValidator>;
|
|
1443
|
+
|
|
1444
|
+
export const TagValidator = z.object({
|
|
1445
|
+
id: z.string(),
|
|
1446
|
+
name: z.string().min(1),
|
|
1447
|
+
slug: z.string().min(1),
|
|
1448
|
+
createdAt: z.string().optional(),
|
|
1449
|
+
updatedAt: z.string().optional(),
|
|
1450
|
+
});
|
|
1451
|
+
|
|
1452
|
+
export type TagType = z.infer<typeof TagValidator>;
|
|
1453
|
+
|
|
1454
|
+
export const SkillStatusEnum = z.enum(['active', 'archived']);
|
|
1455
|
+
export type SkillStatus = z.infer<typeof SkillStatusEnum>;
|
|
1456
|
+
|
|
1457
|
+
export const SkillValidator = z.object({
|
|
1458
|
+
id: z.string(),
|
|
1459
|
+
statement: z.string(),
|
|
1460
|
+
description: z.string().optional(),
|
|
1461
|
+
code: z.string().optional(),
|
|
1462
|
+
icon: z.string().optional(),
|
|
1463
|
+
type: z.string().default('skill'),
|
|
1464
|
+
status: SkillStatusEnum.default('active'),
|
|
1465
|
+
frameworkId: z.string().optional(),
|
|
1466
|
+
createdAt: z.string().optional(),
|
|
1467
|
+
updatedAt: z.string().optional(),
|
|
1468
|
+
});
|
|
1469
|
+
|
|
1470
|
+
export type SkillType = z.infer<typeof SkillValidator>;
|
|
1471
|
+
|
|
1472
|
+
const BaseSkillQueryValidator = z
|
|
1473
|
+
.object({
|
|
1474
|
+
id: StringQuery,
|
|
1475
|
+
statement: StringQuery,
|
|
1476
|
+
description: StringQuery,
|
|
1477
|
+
code: StringQuery,
|
|
1478
|
+
type: StringQuery,
|
|
1479
|
+
status: SkillStatusEnum.or(z.object({ $in: SkillStatusEnum.array() })),
|
|
1480
|
+
})
|
|
1481
|
+
.partial();
|
|
1482
|
+
|
|
1483
|
+
export const SkillQueryValidator = z.union([
|
|
1484
|
+
z.object({
|
|
1485
|
+
$or: BaseSkillQueryValidator.array(),
|
|
1486
|
+
}),
|
|
1487
|
+
BaseSkillQueryValidator,
|
|
1488
|
+
]);
|
|
1489
|
+
|
|
1490
|
+
export type SkillQuery = z.infer<typeof SkillQueryValidator>;
|
|
1491
|
+
|
|
1492
|
+
export const SkillSemanticSearchInputValidator = z.object({
|
|
1493
|
+
text: z.string().min(1),
|
|
1494
|
+
frameworkId: z.string().optional(),
|
|
1495
|
+
limit: z.number().int().min(1).max(200).default(50),
|
|
1496
|
+
});
|
|
1497
|
+
|
|
1498
|
+
export type SkillSemanticSearchInput = z.infer<typeof SkillSemanticSearchInputValidator>;
|
|
1499
|
+
|
|
1500
|
+
export const SkillSemanticSearchResultItemValidator = SkillValidator.extend({
|
|
1501
|
+
score: z.number(),
|
|
1502
|
+
});
|
|
1503
|
+
|
|
1504
|
+
export type SkillSemanticSearchResultItem = z.infer<typeof SkillSemanticSearchResultItemValidator>;
|
|
1505
|
+
|
|
1506
|
+
export const SkillSemanticSearchResultValidator = z.object({
|
|
1507
|
+
records: SkillSemanticSearchResultItemValidator.array(),
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
export type SkillSemanticSearchResult = z.infer<typeof SkillSemanticSearchResultValidator>;
|
|
1511
|
+
|
|
1512
|
+
export const SkillFrameworkStatusEnum = z.enum(['active', 'archived']);
|
|
1513
|
+
export type SkillFrameworkStatus = z.infer<typeof SkillFrameworkStatusEnum>;
|
|
1514
|
+
|
|
1515
|
+
export const SkillFrameworkValidator = z.object({
|
|
1516
|
+
id: z.string(),
|
|
1517
|
+
name: z.string(),
|
|
1518
|
+
description: z.string().optional(),
|
|
1519
|
+
image: z.string().optional(),
|
|
1520
|
+
sourceURI: z.string().url().optional(),
|
|
1521
|
+
isPublic: z.boolean().default(false),
|
|
1522
|
+
status: SkillFrameworkStatusEnum.default('active'),
|
|
1523
|
+
createdAt: z.string().optional(),
|
|
1524
|
+
updatedAt: z.string().optional(),
|
|
1525
|
+
});
|
|
1526
|
+
|
|
1527
|
+
export type SkillFrameworkType = z.infer<typeof SkillFrameworkValidator>;
|
|
1528
|
+
|
|
1529
|
+
export const PaginatedSkillFrameworksValidator = PaginationResponseValidator.extend({
|
|
1530
|
+
records: SkillFrameworkValidator.array(),
|
|
1531
|
+
});
|
|
1532
|
+
export type PaginatedSkillFrameworksType = z.infer<typeof PaginatedSkillFrameworksValidator>;
|
|
1533
|
+
|
|
1534
|
+
export type SkillTreeNode = SkillType & {
|
|
1535
|
+
children: SkillTreeNode[];
|
|
1536
|
+
hasChildren: boolean;
|
|
1537
|
+
childrenCursor?: string | null;
|
|
1538
|
+
};
|
|
1539
|
+
|
|
1540
|
+
export const SkillTreeNodeValidator: z.ZodType<SkillTreeNode> = SkillValidator.extend({
|
|
1541
|
+
children: z.array(z.lazy(() => SkillTreeNodeValidator)),
|
|
1542
|
+
hasChildren: z.boolean(),
|
|
1543
|
+
childrenCursor: z.string().nullable().optional(),
|
|
1544
|
+
});
|
|
1545
|
+
|
|
1546
|
+
export const PaginatedSkillTreeValidator = z.object({
|
|
1547
|
+
hasMore: z.boolean(),
|
|
1548
|
+
cursor: z.string().nullable(),
|
|
1549
|
+
records: z.array(SkillTreeNodeValidator),
|
|
1550
|
+
});
|
|
1551
|
+
|
|
1552
|
+
export type PaginatedSkillTree = z.infer<typeof PaginatedSkillTreeValidator>;
|
|
1553
|
+
|
|
1554
|
+
export interface SkillTreeInput {
|
|
1555
|
+
id?: string;
|
|
1556
|
+
statement: string;
|
|
1557
|
+
description?: string;
|
|
1558
|
+
code?: string;
|
|
1559
|
+
icon?: string;
|
|
1560
|
+
type?: string;
|
|
1561
|
+
status?: 'active' | 'archived';
|
|
1562
|
+
children?: SkillTreeInput[];
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
export const SkillTreeNodeInputValidator: z.ZodType<SkillTreeInput> = z.lazy(() =>
|
|
1566
|
+
z.object({
|
|
1567
|
+
id: z.string().optional(),
|
|
1568
|
+
statement: z.string(),
|
|
1569
|
+
description: z.string().optional(),
|
|
1570
|
+
code: z.string().optional(),
|
|
1571
|
+
icon: z.string().optional(),
|
|
1572
|
+
type: z.string().optional(),
|
|
1573
|
+
status: SkillStatusEnum.optional(),
|
|
1574
|
+
children: z.array(SkillTreeNodeInputValidator).optional(),
|
|
1575
|
+
})
|
|
1576
|
+
);
|
|
1577
|
+
|
|
1578
|
+
export const LinkProviderFrameworkInputValidator = z.object({
|
|
1579
|
+
frameworkId: z.string(),
|
|
1580
|
+
});
|
|
1581
|
+
|
|
1582
|
+
export type LinkProviderFrameworkInputType = z.infer<typeof LinkProviderFrameworkInputValidator>;
|
|
1583
|
+
|
|
1584
|
+
export const CreateManagedFrameworkInputValidator = z.object({
|
|
1585
|
+
id: z.string().optional(),
|
|
1586
|
+
name: z.string().min(1),
|
|
1587
|
+
description: z.string().optional(),
|
|
1588
|
+
image: z.string().optional(),
|
|
1589
|
+
sourceURI: z.string().url().optional(),
|
|
1590
|
+
isPublic: z.boolean().optional(),
|
|
1591
|
+
status: SkillFrameworkStatusEnum.optional(),
|
|
1592
|
+
skills: z.array(SkillTreeNodeInputValidator).optional(),
|
|
1593
|
+
boostUris: z.array(z.string()).optional(),
|
|
1594
|
+
});
|
|
1595
|
+
|
|
1596
|
+
export type CreateManagedFrameworkInputType = z.infer<typeof CreateManagedFrameworkInputValidator>;
|
|
1597
|
+
|
|
1598
|
+
// Back-compat alias for plugin naming
|
|
1599
|
+
export type CreateManagedSkillFrameworkInput = CreateManagedFrameworkInputType;
|
|
1600
|
+
|
|
1601
|
+
export const UpdateFrameworkInputValidator = z
|
|
1602
|
+
.object({
|
|
1603
|
+
id: z.string(),
|
|
1604
|
+
name: z.string().min(1).optional(),
|
|
1605
|
+
description: z.string().optional(),
|
|
1606
|
+
image: z.string().optional(),
|
|
1607
|
+
sourceURI: z.string().url().optional(),
|
|
1608
|
+
isPublic: z.boolean().optional(),
|
|
1609
|
+
status: SkillFrameworkStatusEnum.optional(),
|
|
1610
|
+
})
|
|
1611
|
+
.refine(
|
|
1612
|
+
data =>
|
|
1613
|
+
data.name !== undefined ||
|
|
1614
|
+
data.description !== undefined ||
|
|
1615
|
+
data.image !== undefined ||
|
|
1616
|
+
data.sourceURI !== undefined ||
|
|
1617
|
+
data.isPublic !== undefined ||
|
|
1618
|
+
data.status !== undefined,
|
|
1619
|
+
{
|
|
1620
|
+
message: 'At least one field must be provided to update',
|
|
1621
|
+
path: ['name'],
|
|
1622
|
+
}
|
|
1623
|
+
);
|
|
1624
|
+
|
|
1625
|
+
export type UpdateFrameworkInputType = z.infer<typeof UpdateFrameworkInputValidator>;
|
|
1626
|
+
|
|
1627
|
+
// Back-compat alias for plugin naming
|
|
1628
|
+
export type UpdateSkillFrameworkInput = UpdateFrameworkInputType;
|
|
1629
|
+
|
|
1630
|
+
export const DeleteFrameworkInputValidator = z.object({ id: z.string() });
|
|
1631
|
+
|
|
1632
|
+
export type DeleteFrameworkInputType = z.infer<typeof DeleteFrameworkInputValidator>;
|
|
1633
|
+
|
|
1634
|
+
// Back-compat alias for plugin naming
|
|
1635
|
+
export type DeleteSkillFrameworkInput = DeleteFrameworkInputType;
|
|
1636
|
+
|
|
1637
|
+
export const CreateManagedFrameworkBatchInputValidator = z.object({
|
|
1638
|
+
frameworks: z
|
|
1639
|
+
.array(
|
|
1640
|
+
CreateManagedFrameworkInputValidator.extend({
|
|
1641
|
+
skills: z.array(SkillTreeNodeInputValidator).optional(),
|
|
1642
|
+
})
|
|
1643
|
+
)
|
|
1644
|
+
.min(1),
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
export type CreateManagedFrameworkBatchInputType = z.infer<
|
|
1648
|
+
typeof CreateManagedFrameworkBatchInputValidator
|
|
1649
|
+
>;
|
|
1650
|
+
|
|
1651
|
+
// Back-compat alias for plugin naming
|
|
1652
|
+
export type CreateManagedSkillFrameworkBatchInput = CreateManagedFrameworkBatchInputType;
|
|
1653
|
+
|
|
1654
|
+
export const SkillFrameworkAdminInputValidator = z.object({
|
|
1655
|
+
frameworkId: z.string(),
|
|
1656
|
+
profileId: z.string(),
|
|
1657
|
+
});
|
|
1658
|
+
|
|
1659
|
+
export type SkillFrameworkAdminInputType = z.infer<typeof SkillFrameworkAdminInputValidator>;
|
|
1660
|
+
|
|
1661
|
+
export const SkillFrameworkIdInputValidator = z.object({ frameworkId: z.string() });
|
|
1662
|
+
|
|
1663
|
+
export type SkillFrameworkIdInputType = z.infer<typeof SkillFrameworkIdInputValidator>;
|
|
1664
|
+
|
|
1665
|
+
export const SkillFrameworkAdminsValidator = LCNProfileValidator.array();
|
|
1666
|
+
|
|
1667
|
+
export type SkillFrameworkAdminsType = z.infer<typeof SkillFrameworkAdminsValidator>;
|
|
1668
|
+
|
|
1669
|
+
export const SyncFrameworkInputValidator = z.object({ id: z.string() });
|
|
1670
|
+
|
|
1671
|
+
export type SyncFrameworkInput = z.infer<typeof SyncFrameworkInputValidator>;
|
|
1672
|
+
|
|
1673
|
+
export const AddTagInputValidator = z.object({
|
|
1674
|
+
slug: z.string().min(1),
|
|
1675
|
+
name: z.string().min(1),
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
export type AddTagInput = z.infer<typeof AddTagInputValidator>;
|
|
1679
|
+
|
|
1680
|
+
export const CreateSkillInputValidator = z.object({
|
|
1681
|
+
frameworkId: z.string(),
|
|
1682
|
+
skill: SkillTreeNodeInputValidator,
|
|
1683
|
+
parentId: z.string().nullable().optional(),
|
|
1684
|
+
});
|
|
1685
|
+
|
|
1686
|
+
export type CreateSkillInput = z.infer<typeof CreateSkillInputValidator>;
|
|
1687
|
+
|
|
1688
|
+
export const UpdateSkillInputValidator = z
|
|
1689
|
+
.object({
|
|
1690
|
+
frameworkId: z.string(),
|
|
1691
|
+
id: z.string(),
|
|
1692
|
+
statement: z.string().optional(),
|
|
1693
|
+
description: z.string().optional(),
|
|
1694
|
+
code: z.string().optional(),
|
|
1695
|
+
icon: z.string().optional(),
|
|
1696
|
+
type: z.string().optional(),
|
|
1697
|
+
status: SkillStatusEnum.optional(),
|
|
1698
|
+
})
|
|
1699
|
+
.refine(
|
|
1700
|
+
data =>
|
|
1701
|
+
data.statement !== undefined ||
|
|
1702
|
+
data.description !== undefined ||
|
|
1703
|
+
data.code !== undefined ||
|
|
1704
|
+
data.icon !== undefined ||
|
|
1705
|
+
data.type !== undefined ||
|
|
1706
|
+
data.status !== undefined,
|
|
1707
|
+
{
|
|
1708
|
+
message: 'At least one field must be provided to update a skill',
|
|
1709
|
+
path: ['statement'],
|
|
1710
|
+
}
|
|
1711
|
+
);
|
|
1712
|
+
|
|
1713
|
+
export type UpdateSkillInput = z.infer<typeof UpdateSkillInputValidator>;
|
|
1714
|
+
|
|
1715
|
+
export const SkillDeletionStrategyValidator = z.enum(['recursive', 'reparent']);
|
|
1716
|
+
export type SkillDeletionStrategy = z.infer<typeof SkillDeletionStrategyValidator>;
|
|
1717
|
+
|
|
1718
|
+
export const DeleteSkillInputValidator = z.object({
|
|
1719
|
+
frameworkId: z.string(),
|
|
1720
|
+
id: z.string(),
|
|
1721
|
+
strategy: SkillDeletionStrategyValidator.optional().default('reparent'),
|
|
1722
|
+
});
|
|
1723
|
+
|
|
1724
|
+
export type DeleteSkillInput = z.infer<typeof DeleteSkillInputValidator>;
|
|
1725
|
+
|
|
1726
|
+
export const CreateSkillsBatchInputValidator = z.object({
|
|
1727
|
+
frameworkId: z.string(),
|
|
1728
|
+
skills: z.array(SkillTreeNodeInputValidator).min(1),
|
|
1729
|
+
parentId: z.string().nullable().optional(),
|
|
1730
|
+
});
|
|
1731
|
+
|
|
1732
|
+
export type CreateSkillsBatchInput = z.infer<typeof CreateSkillsBatchInputValidator>;
|
|
1733
|
+
|
|
1734
|
+
export const ReplaceSkillFrameworkSkillsInputValidator = z.object({
|
|
1735
|
+
frameworkId: z.string(),
|
|
1736
|
+
skills: z.array(SkillTreeNodeInputValidator).min(0),
|
|
1737
|
+
});
|
|
1738
|
+
|
|
1739
|
+
export type ReplaceSkillFrameworkSkillsInput = z.infer<
|
|
1740
|
+
typeof ReplaceSkillFrameworkSkillsInputValidator
|
|
1741
|
+
>;
|
|
1742
|
+
|
|
1743
|
+
export const ReplaceSkillFrameworkSkillsResultValidator = z.object({
|
|
1744
|
+
created: z.number().int().min(0),
|
|
1745
|
+
updated: z.number().int().min(0),
|
|
1746
|
+
deleted: z.number().int().min(0),
|
|
1747
|
+
unchanged: z.number().int().min(0),
|
|
1748
|
+
total: z.number().int().min(0),
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
export type ReplaceSkillFrameworkSkillsResult = z.infer<
|
|
1752
|
+
typeof ReplaceSkillFrameworkSkillsResultValidator
|
|
1753
|
+
>;
|
|
1754
|
+
|
|
1755
|
+
export const CountSkillsInputValidator = z.object({
|
|
1756
|
+
frameworkId: z.string(),
|
|
1757
|
+
skillId: z.string().optional(),
|
|
1758
|
+
recursive: z.boolean().optional().default(false),
|
|
1759
|
+
onlyCountCompetencies: z.boolean().optional().default(false),
|
|
1760
|
+
});
|
|
1761
|
+
|
|
1762
|
+
export type CountSkillsInput = z.infer<typeof CountSkillsInputValidator>;
|
|
1763
|
+
|
|
1764
|
+
export const CountSkillsResultValidator = z.object({
|
|
1765
|
+
count: z.number().int().min(0),
|
|
1766
|
+
});
|
|
1767
|
+
|
|
1768
|
+
export type CountSkillsResult = z.infer<typeof CountSkillsResultValidator>;
|
|
1769
|
+
|
|
1770
|
+
export const GetFullSkillTreeInputValidator = z.object({
|
|
1771
|
+
frameworkId: z.string(),
|
|
1772
|
+
});
|
|
1773
|
+
|
|
1774
|
+
export type GetFullSkillTreeInput = z.infer<typeof GetFullSkillTreeInputValidator>;
|
|
1775
|
+
|
|
1776
|
+
export const GetFullSkillTreeResultValidator = z.object({
|
|
1777
|
+
skills: z.array(SkillTreeNodeValidator),
|
|
1778
|
+
});
|
|
1779
|
+
|
|
1780
|
+
export type GetFullSkillTreeResult = z.infer<typeof GetFullSkillTreeResultValidator>;
|
|
1781
|
+
|
|
1782
|
+
export const GetSkillPathInputValidator = z.object({
|
|
1783
|
+
frameworkId: z.string(),
|
|
1784
|
+
skillId: z.string(),
|
|
1785
|
+
});
|
|
1786
|
+
|
|
1787
|
+
export type GetSkillPathInput = z.infer<typeof GetSkillPathInputValidator>;
|
|
1788
|
+
|
|
1789
|
+
export const GetSkillPathResultValidator = z.object({
|
|
1790
|
+
path: z.array(SkillValidator),
|
|
1791
|
+
});
|
|
1792
|
+
|
|
1793
|
+
export type GetSkillPathResult = z.infer<typeof GetSkillPathResultValidator>;
|
|
1794
|
+
|
|
1795
|
+
// Composite return shapes
|
|
1796
|
+
export const FrameworkWithSkillsValidator = z.object({
|
|
1797
|
+
framework: SkillFrameworkValidator,
|
|
1798
|
+
skills: PaginatedSkillTreeValidator,
|
|
1799
|
+
});
|
|
1800
|
+
|
|
1801
|
+
export type FrameworkWithSkills = z.infer<typeof FrameworkWithSkillsValidator>;
|
|
1802
|
+
|
|
1803
|
+
// Aliases used by the plugin type definitions
|
|
1804
|
+
export type CreateSkillTreeInput = SkillTreeInput;
|
|
1805
|
+
|
|
1806
|
+
// App Store Listing
|
|
1807
|
+
export const AppListingStatusValidator = z.enum(['DRAFT', 'PENDING_REVIEW', 'LISTED', 'ARCHIVED']);
|
|
1808
|
+
export type AppListingStatus = z.infer<typeof AppListingStatusValidator>;
|
|
1809
|
+
|
|
1810
|
+
export const LaunchTypeValidator = z.enum([
|
|
1811
|
+
'EMBEDDED_IFRAME',
|
|
1812
|
+
'SECOND_SCREEN',
|
|
1813
|
+
'DIRECT_LINK',
|
|
1814
|
+
'CONSENT_REDIRECT',
|
|
1815
|
+
'SERVER_HEADLESS',
|
|
1816
|
+
'AI_TUTOR',
|
|
1817
|
+
]);
|
|
1818
|
+
export type LaunchType = z.infer<typeof LaunchTypeValidator>;
|
|
1819
|
+
|
|
1820
|
+
export const PromotionLevelValidator = z.enum([
|
|
1821
|
+
'FEATURED_CAROUSEL',
|
|
1822
|
+
'CURATED_LIST',
|
|
1823
|
+
'STANDARD',
|
|
1824
|
+
'DEMOTED',
|
|
1825
|
+
]);
|
|
1826
|
+
export type PromotionLevel = z.infer<typeof PromotionLevelValidator>;
|
|
1827
|
+
|
|
1828
|
+
export const AgeRatingValidator = z.enum(['4+', '9+', '12+', '17+']);
|
|
1829
|
+
export type AgeRating = z.infer<typeof AgeRatingValidator>;
|
|
1830
|
+
|
|
1831
|
+
export const AppStoreListingSubmitterValidator = z.object({
|
|
1832
|
+
profileId: z.string(),
|
|
1833
|
+
displayName: z.string(),
|
|
1834
|
+
email: z.string().optional(),
|
|
1835
|
+
});
|
|
1836
|
+
|
|
1837
|
+
export type AppStoreListingSubmitter = z.infer<typeof AppStoreListingSubmitterValidator>;
|
|
1838
|
+
|
|
1839
|
+
export const AppStoreListingValidator = z.object({
|
|
1840
|
+
listing_id: z.string(),
|
|
1841
|
+
slug: z.string().optional(),
|
|
1842
|
+
display_name: z.string(),
|
|
1843
|
+
tagline: z.string(),
|
|
1844
|
+
full_description: z.string(),
|
|
1845
|
+
icon_url: z.string(),
|
|
1846
|
+
app_listing_status: AppListingStatusValidator,
|
|
1847
|
+
launch_type: LaunchTypeValidator,
|
|
1848
|
+
launch_config_json: z.string(),
|
|
1849
|
+
category: z.string().optional(),
|
|
1850
|
+
promo_video_url: z.string().optional(),
|
|
1851
|
+
promotion_level: PromotionLevelValidator.optional(),
|
|
1852
|
+
ios_app_store_id: z.string().optional(),
|
|
1853
|
+
android_app_store_id: z.string().optional(),
|
|
1854
|
+
privacy_policy_url: z.string().optional(),
|
|
1855
|
+
terms_url: z.string().optional(),
|
|
1856
|
+
highlights: z.array(z.string()).optional(),
|
|
1857
|
+
screenshots: z.array(z.string()).optional(),
|
|
1858
|
+
hero_background_color: z.string().optional(),
|
|
1859
|
+
min_age: z.number().int().min(0).max(18).optional(),
|
|
1860
|
+
age_rating: AgeRatingValidator.optional(),
|
|
1861
|
+
submitted_at: z.string().optional(),
|
|
1862
|
+
submitter: AppStoreListingSubmitterValidator.optional(),
|
|
1863
|
+
contact_email: z.string().email().optional(),
|
|
1864
|
+
});
|
|
1865
|
+
|
|
1866
|
+
export type AppStoreListing = z.infer<typeof AppStoreListingValidator>;
|
|
1867
|
+
|
|
1868
|
+
export const AppStoreListingCreateValidator = AppStoreListingValidator.omit({
|
|
1869
|
+
listing_id: true,
|
|
1870
|
+
app_listing_status: true,
|
|
1871
|
+
promotion_level: true,
|
|
1872
|
+
});
|
|
1873
|
+
|
|
1874
|
+
export type AppStoreListingCreateType = z.infer<typeof AppStoreListingCreateValidator>;
|
|
1875
|
+
|
|
1876
|
+
export const AppStoreListingUpdateValidator = AppStoreListingValidator.partial().omit({
|
|
1877
|
+
listing_id: true,
|
|
1878
|
+
app_listing_status: true,
|
|
1879
|
+
promotion_level: true,
|
|
1880
|
+
});
|
|
1881
|
+
|
|
1882
|
+
export type AppStoreListingUpdateType = z.infer<typeof AppStoreListingUpdateValidator>;
|
|
1883
|
+
|
|
1884
|
+
export const InstalledAppValidator = AppStoreListingValidator.extend({
|
|
1885
|
+
installed_at: z.string(),
|
|
1886
|
+
});
|
|
1887
|
+
|
|
1888
|
+
export type InstalledApp = z.infer<typeof InstalledAppValidator>;
|
|
1889
|
+
|
|
1890
|
+
export const PaginatedAppStoreListingsValidator = PaginationResponseValidator.extend({
|
|
1891
|
+
records: AppStoreListingValidator.array(),
|
|
1892
|
+
});
|
|
1893
|
+
|
|
1894
|
+
export type PaginatedAppStoreListings = z.infer<typeof PaginatedAppStoreListingsValidator>;
|
|
1895
|
+
|
|
1896
|
+
export const PaginatedInstalledAppsValidator = PaginationResponseValidator.extend({
|
|
1897
|
+
records: InstalledAppValidator.array(),
|
|
1898
|
+
});
|
|
1899
|
+
|
|
1900
|
+
export type PaginatedInstalledApps = z.infer<typeof PaginatedInstalledAppsValidator>;
|
|
1901
|
+
|
|
1902
|
+
// App Store Boost Association
|
|
1903
|
+
export const AppBoostValidator = z.object({
|
|
1904
|
+
templateAlias: z
|
|
1905
|
+
.string()
|
|
1906
|
+
.min(1)
|
|
1907
|
+
.max(50)
|
|
1908
|
+
.regex(/^[a-z0-9-]+$/),
|
|
1909
|
+
boostUri: z.string(),
|
|
1910
|
+
});
|
|
1911
|
+
|
|
1912
|
+
export type AppBoost = z.infer<typeof AppBoostValidator>;
|
|
1913
|
+
|
|
1914
|
+
// App Event Types (discriminated union for type safety)
|
|
1915
|
+
export const SendCredentialEventValidator = z.object({
|
|
1916
|
+
type: z.literal('send-credential'),
|
|
1917
|
+
templateAlias: z.string(),
|
|
1918
|
+
templateData: z.record(z.string(), z.unknown()).optional(),
|
|
1919
|
+
preventDuplicateClaim: z.boolean().optional(),
|
|
1920
|
+
});
|
|
1921
|
+
|
|
1922
|
+
export type SendCredentialEvent = z.infer<typeof SendCredentialEventValidator>;
|
|
1923
|
+
|
|
1924
|
+
export const CheckCredentialEventValidator = z
|
|
1925
|
+
.object({
|
|
1926
|
+
type: z.literal('check-credential'),
|
|
1927
|
+
templateAlias: z.string().optional(),
|
|
1928
|
+
boostUri: z.string().optional(),
|
|
1929
|
+
})
|
|
1930
|
+
.refine(input => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
1931
|
+
message: 'Exactly one of templateAlias or boostUri is required',
|
|
1932
|
+
});
|
|
1933
|
+
|
|
1934
|
+
export type CheckCredentialEvent = z.infer<typeof CheckCredentialEventValidator>;
|
|
1935
|
+
|
|
1936
|
+
export const CheckIssuanceStatusEventValidator = z
|
|
1937
|
+
.object({
|
|
1938
|
+
type: z.literal('check-issuance-status'),
|
|
1939
|
+
templateAlias: z.string().optional(),
|
|
1940
|
+
boostUri: z.string().optional(),
|
|
1941
|
+
recipient: z.string(),
|
|
1942
|
+
})
|
|
1943
|
+
.refine(input => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
1944
|
+
message: 'Exactly one of templateAlias or boostUri is required',
|
|
1945
|
+
});
|
|
1946
|
+
|
|
1947
|
+
export type CheckIssuanceStatusEvent = z.infer<typeof CheckIssuanceStatusEventValidator>;
|
|
1948
|
+
|
|
1949
|
+
export const GetTemplateRecipientsEventValidator = z
|
|
1950
|
+
.object({
|
|
1951
|
+
type: z.literal('get-template-recipients'),
|
|
1952
|
+
templateAlias: z.string().optional(),
|
|
1953
|
+
boostUri: z.string().optional(),
|
|
1954
|
+
limit: z.number().optional(),
|
|
1955
|
+
cursor: z.string().optional(),
|
|
1956
|
+
})
|
|
1957
|
+
.refine(input => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
1958
|
+
message: 'Exactly one of templateAlias or boostUri is required',
|
|
1959
|
+
});
|
|
1960
|
+
|
|
1961
|
+
export type GetTemplateRecipientsEvent = z.infer<typeof GetTemplateRecipientsEventValidator>;
|
|
1962
|
+
|
|
1963
|
+
// Request learner context event for AI tutoring systems
|
|
1964
|
+
export const RequestLearnerContextEventValidator = z.object({
|
|
1965
|
+
type: z.literal('request-learner-context'),
|
|
1966
|
+
includeCredentials: z.boolean().optional().default(true),
|
|
1967
|
+
includePersonalData: z.boolean().optional().default(false),
|
|
1968
|
+
format: z.enum(['prompt', 'structured']).optional().default('prompt'),
|
|
1969
|
+
instructions: z.string().optional(),
|
|
1970
|
+
detailLevel: z.enum(['compact', 'expanded']).optional().default('compact'),
|
|
1971
|
+
waitForSync: z.boolean().optional().default(false),
|
|
1972
|
+
});
|
|
1973
|
+
|
|
1974
|
+
export type RequestLearnerContextEvent = z.infer<typeof RequestLearnerContextEventValidator>;
|
|
1975
|
+
|
|
1976
|
+
export const SummaryCredentialKeywordValidator = z.object({
|
|
1977
|
+
occupations: z.array(z.string()).nullable(),
|
|
1978
|
+
careers: z.array(z.string()).nullable(),
|
|
1979
|
+
jobs: z.array(z.string()).nullable(),
|
|
1980
|
+
skills: z.array(z.string()).nullable(),
|
|
1981
|
+
fieldOfStudy: z.string().nullable(),
|
|
1982
|
+
});
|
|
1983
|
+
|
|
1984
|
+
export type SummaryCredentialKeyword = z.infer<typeof SummaryCredentialKeywordValidator>;
|
|
1985
|
+
|
|
1986
|
+
export const SummaryCredentialDataValidator = z.object({
|
|
1987
|
+
title: z.string().describe('Short, concise title for the learning session or credential'),
|
|
1988
|
+
summary: z.string().describe('Comprehensive summary of what happened during the session'),
|
|
1989
|
+
learned: z.array(z.string()).describe('Bullet points of key knowledge gained'),
|
|
1990
|
+
skills: z
|
|
1991
|
+
.array(
|
|
1992
|
+
z.object({
|
|
1993
|
+
title: z.string().describe('Name of the skill category'),
|
|
1994
|
+
description: z
|
|
1995
|
+
.string()
|
|
1996
|
+
.describe('Detailed description of what this skill category involves'),
|
|
1997
|
+
})
|
|
1998
|
+
)
|
|
1999
|
+
.describe('Categorized skills learned during the session'),
|
|
2000
|
+
nextSteps: z
|
|
2001
|
+
.array(
|
|
2002
|
+
z.object({
|
|
2003
|
+
title: z.string().describe('Title of the suggested next step'),
|
|
2004
|
+
description: z
|
|
2005
|
+
.string()
|
|
2006
|
+
.describe('Description explaining why this next step is recommended'),
|
|
2007
|
+
keywords: SummaryCredentialKeywordValidator.optional().describe(
|
|
2008
|
+
'Optional taxonomy keywords for occupations/careers/jobs/skills/fieldOfStudy. Omit if not relevant.'
|
|
2009
|
+
),
|
|
2010
|
+
})
|
|
2011
|
+
)
|
|
2012
|
+
.describe('Recommended follow-up activities or learning modules'),
|
|
2013
|
+
reflections: z
|
|
2014
|
+
.array(
|
|
2015
|
+
z.object({
|
|
2016
|
+
title: z.string().describe('Title of the reflection'),
|
|
2017
|
+
description: z
|
|
2018
|
+
.string()
|
|
2019
|
+
.describe('Detailed description of what this reflection involves'),
|
|
2020
|
+
})
|
|
2021
|
+
)
|
|
2022
|
+
.describe('Reflections on the learning experience'),
|
|
2023
|
+
});
|
|
2024
|
+
|
|
2025
|
+
export type SummaryCredentialData = z.infer<typeof SummaryCredentialDataValidator>;
|
|
2026
|
+
|
|
2027
|
+
// AI Session credential event for creating AI tutoring sessions
|
|
2028
|
+
export const SendAiSessionCredentialEventValidator = z.object({
|
|
2029
|
+
type: z.literal('send-ai-session-credential'),
|
|
2030
|
+
sessionTitle: z.string(),
|
|
2031
|
+
summaryData: SummaryCredentialDataValidator,
|
|
2032
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
2033
|
+
});
|
|
2034
|
+
|
|
2035
|
+
export type SendAiSessionCredentialEvent = z.infer<typeof SendAiSessionCredentialEventValidator>;
|
|
2036
|
+
|
|
2037
|
+
export const SendNotificationEventValidator = z.object({
|
|
2038
|
+
type: z.literal('send-notification'),
|
|
2039
|
+
title: z.string().optional(),
|
|
2040
|
+
body: z.string().optional(),
|
|
2041
|
+
actionPath: z.string().optional(),
|
|
2042
|
+
category: z.string().optional(),
|
|
2043
|
+
priority: z.enum(['normal', 'high']).optional(),
|
|
2044
|
+
});
|
|
2045
|
+
|
|
2046
|
+
export type SendNotificationEvent = z.infer<typeof SendNotificationEventValidator>;
|
|
2047
|
+
|
|
2048
|
+
const counterKeyValidator = z
|
|
2049
|
+
.string()
|
|
2050
|
+
.min(1)
|
|
2051
|
+
.max(64)
|
|
2052
|
+
.regex(/^[a-zA-Z0-9_-]+$/, 'Key must be alphanumeric with _ or -');
|
|
2053
|
+
|
|
2054
|
+
export const IncrementCounterEventValidator = z.object({
|
|
2055
|
+
type: z.literal('increment-counter'),
|
|
2056
|
+
key: counterKeyValidator,
|
|
2057
|
+
amount: z.number().int().finite(),
|
|
2058
|
+
});
|
|
2059
|
+
|
|
2060
|
+
export type IncrementCounterEvent = z.infer<typeof IncrementCounterEventValidator>;
|
|
2061
|
+
|
|
2062
|
+
export const GetCounterEventValidator = z.object({
|
|
2063
|
+
type: z.literal('get-counter'),
|
|
2064
|
+
key: counterKeyValidator,
|
|
2065
|
+
});
|
|
2066
|
+
|
|
2067
|
+
export type GetCounterEvent = z.infer<typeof GetCounterEventValidator>;
|
|
2068
|
+
|
|
2069
|
+
export const GetCountersEventValidator = z.object({
|
|
2070
|
+
type: z.literal('get-counters'),
|
|
2071
|
+
keys: z.array(counterKeyValidator).min(1).max(50).optional(),
|
|
2072
|
+
});
|
|
2073
|
+
|
|
2074
|
+
export type GetCountersEvent = z.infer<typeof GetCountersEventValidator>;
|
|
2075
|
+
|
|
2076
|
+
// Add new event types here as the union grows
|
|
2077
|
+
export const AppEventValidator = z.discriminatedUnion('type', [
|
|
2078
|
+
SendCredentialEventValidator,
|
|
2079
|
+
CheckCredentialEventValidator,
|
|
2080
|
+
CheckIssuanceStatusEventValidator,
|
|
2081
|
+
GetTemplateRecipientsEventValidator,
|
|
2082
|
+
RequestLearnerContextEventValidator,
|
|
2083
|
+
SendAiSessionCredentialEventValidator,
|
|
2084
|
+
SendNotificationEventValidator,
|
|
2085
|
+
IncrementCounterEventValidator,
|
|
2086
|
+
GetCounterEventValidator,
|
|
2087
|
+
GetCountersEventValidator,
|
|
2088
|
+
]);
|
|
2089
|
+
|
|
2090
|
+
export type AppEvent = z.infer<typeof AppEventValidator>;
|
|
2091
|
+
|
|
2092
|
+
// Full input including listingId (used by brain service)
|
|
2093
|
+
export const AppEventInputValidator = z.object({
|
|
2094
|
+
listingId: z.string(),
|
|
2095
|
+
event: AppEventValidator,
|
|
2096
|
+
});
|
|
2097
|
+
|
|
2098
|
+
export type AppEventInput = z.infer<typeof AppEventInputValidator>;
|
|
2099
|
+
|
|
2100
|
+
// Response is generic since different events may return different data
|
|
2101
|
+
export const AppEventResponseValidator = z.record(z.string(), z.unknown());
|
|
2102
|
+
|
|
2103
|
+
export type AppEventResponse = z.infer<typeof AppEventResponseValidator>;
|
|
2104
|
+
// Credential Activity
|
|
2105
|
+
export const CredentialActivityEventTypeValidator = z.enum([
|
|
2106
|
+
'CREATED',
|
|
2107
|
+
'DELIVERED',
|
|
2108
|
+
'CLAIMED',
|
|
2109
|
+
'EXPIRED',
|
|
2110
|
+
'FAILED',
|
|
2111
|
+
]);
|
|
2112
|
+
export type CredentialActivityEventType = z.infer<typeof CredentialActivityEventTypeValidator>;
|
|
2113
|
+
|
|
2114
|
+
export const CredentialActivityRecipientTypeValidator = z.enum(['profile', 'email', 'phone']);
|
|
2115
|
+
export type CredentialActivityRecipientType = z.infer<
|
|
2116
|
+
typeof CredentialActivityRecipientTypeValidator
|
|
2117
|
+
>;
|
|
2118
|
+
|
|
2119
|
+
export const CredentialActivitySourceTypeValidator = z.enum([
|
|
2120
|
+
'send',
|
|
2121
|
+
'sendBoost',
|
|
2122
|
+
'sendCredential',
|
|
2123
|
+
'contract',
|
|
2124
|
+
'claim',
|
|
2125
|
+
'inbox',
|
|
2126
|
+
'claimLink',
|
|
2127
|
+
'acceptCredential',
|
|
2128
|
+
'appEvent',
|
|
2129
|
+
]);
|
|
2130
|
+
export type CredentialActivitySourceType = z.infer<typeof CredentialActivitySourceTypeValidator>;
|
|
2131
|
+
|
|
2132
|
+
export const CredentialActivityValidator = z.object({
|
|
2133
|
+
id: z.string(),
|
|
2134
|
+
activityId: z.string(),
|
|
2135
|
+
eventType: CredentialActivityEventTypeValidator,
|
|
2136
|
+
timestamp: z.string(),
|
|
2137
|
+
actorProfileId: z.string().optional(),
|
|
2138
|
+
recipientType: CredentialActivityRecipientTypeValidator,
|
|
2139
|
+
recipientIdentifier: z.string(),
|
|
2140
|
+
boostUri: z.string().optional(),
|
|
2141
|
+
credentialUri: z.string().optional(),
|
|
2142
|
+
inboxCredentialId: z.string().optional(),
|
|
2143
|
+
integrationId: z.string().optional(),
|
|
2144
|
+
source: CredentialActivitySourceTypeValidator,
|
|
2145
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
2146
|
+
status: z.enum(['active', 'revoked', 'suspended']).optional(),
|
|
2147
|
+
});
|
|
2148
|
+
export type CredentialActivityRecord = z.infer<typeof CredentialActivityValidator>;
|
|
2149
|
+
|
|
2150
|
+
export const CredentialActivityWithDetailsValidator = CredentialActivityValidator.extend({
|
|
2151
|
+
boost: z
|
|
2152
|
+
.object({
|
|
2153
|
+
id: z.string(),
|
|
2154
|
+
name: z.string().optional(),
|
|
2155
|
+
category: z.string().optional(),
|
|
2156
|
+
})
|
|
2157
|
+
.optional(),
|
|
2158
|
+
recipientProfile: z
|
|
2159
|
+
.object({
|
|
2160
|
+
profileId: z.string(),
|
|
2161
|
+
displayName: z.string().optional(),
|
|
2162
|
+
})
|
|
2163
|
+
.optional(),
|
|
2164
|
+
});
|
|
2165
|
+
export type CredentialActivityWithDetails = z.infer<typeof CredentialActivityWithDetailsValidator>;
|
|
2166
|
+
|
|
2167
|
+
export const PaginatedCredentialActivitiesValidator = PaginationResponseValidator.extend({
|
|
2168
|
+
records: CredentialActivityWithDetailsValidator.array(),
|
|
2169
|
+
});
|
|
2170
|
+
export type PaginatedCredentialActivities = z.infer<typeof PaginatedCredentialActivitiesValidator>;
|
|
2171
|
+
|
|
2172
|
+
export const CredentialActivityStatsValidator = z.object({
|
|
2173
|
+
total: z.number(),
|
|
2174
|
+
created: z.number(),
|
|
2175
|
+
delivered: z.number(),
|
|
2176
|
+
claimed: z.number(),
|
|
2177
|
+
expired: z.number(),
|
|
2178
|
+
failed: z.number(),
|
|
2179
|
+
claimRate: z.number(),
|
|
2180
|
+
});
|
|
2181
|
+
export type CredentialActivityStats = z.infer<typeof CredentialActivityStatsValidator>;
|