@learncard/types 5.17.4 → 5.17.6
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 +9 -2
- 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 +1 -1
- package/dist/queries.d.ts.map +1 -1
- package/dist/types.cjs.development.cjs +83 -81
- package/dist/types.cjs.development.cjs.map +3 -3
- package/dist/types.cjs.production.min.cjs +1 -1
- package/dist/types.cjs.production.min.cjs.map +3 -3
- package/dist/types.esm.js +15 -13
- 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 -62
- 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 +2182 -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/learncard.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { CredentialSubjectValidator, ProfileValidator } from './vc';
|
|
3
|
+
import { CredentialFormatValidator, type CredentialFormat } from './credential-format';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Per-entry result for the credentialStatus check.
|
|
7
|
+
*
|
|
8
|
+
* Surfaced from `ssi-ldp::StatusCheckEntry` (see ssi PR
|
|
9
|
+
* `lc-status-array-and-structured-result`) through didkit's
|
|
10
|
+
* `verifyCredential` JSON output. One entry per `credentialStatus`
|
|
11
|
+
* entry on the verified credential — VC 2.0 allows multiple
|
|
12
|
+
* (e.g. one revocation entry + one suspension entry).
|
|
13
|
+
*
|
|
14
|
+
* Combine `statusPurpose` + `isSet` to render structured UI without
|
|
15
|
+
* string-matching the human-readable error in `errors`:
|
|
16
|
+
*
|
|
17
|
+
* - `statusPurpose: "revocation"`, `isSet: true` → revoked
|
|
18
|
+
* - `statusPurpose: "suspension"`, `isSet: true` → suspended
|
|
19
|
+
* - `isSet: false` → active for that purpose
|
|
20
|
+
*/
|
|
21
|
+
export const StatusCheckEntryValidator = z.object({
|
|
22
|
+
/**
|
|
23
|
+
* The `credentialStatus.type` as it appeared on the credential.
|
|
24
|
+
* One of `BitstringStatusListEntry`, `StatusList2021Entry`,
|
|
25
|
+
* `RevocationList2020Status`, or any future custom status type.
|
|
26
|
+
*/
|
|
27
|
+
entryType: z.string(),
|
|
28
|
+
/**
|
|
29
|
+
* The claimed purpose of the entry. Standard values are
|
|
30
|
+
* `"revocation"` and `"suspension"`; the spec allows arbitrary
|
|
31
|
+
* strings.
|
|
32
|
+
*/
|
|
33
|
+
statusPurpose: z.string(),
|
|
34
|
+
/**
|
|
35
|
+
* Whether the bit at the credential's index in the status list
|
|
36
|
+
* bitstring was set.
|
|
37
|
+
*/
|
|
38
|
+
isSet: z.boolean(),
|
|
39
|
+
/** URL of the status list credential, when known. */
|
|
40
|
+
statusListCredential: z.string().optional(),
|
|
41
|
+
/** Original (string) index within the status list. */
|
|
42
|
+
statusListIndex: z.string().optional(),
|
|
43
|
+
});
|
|
44
|
+
export type StatusCheckEntry = z.infer<typeof StatusCheckEntryValidator>;
|
|
45
|
+
|
|
46
|
+
export const VerificationCheckValidator = z.object({
|
|
47
|
+
checks: z.string().array(),
|
|
48
|
+
warnings: z.string().array(),
|
|
49
|
+
errors: z.string().array(),
|
|
50
|
+
/**
|
|
51
|
+
* Per-entry results for the `credentialStatus` check, populated
|
|
52
|
+
* by `@learncard/didkit-plugin` when the verified credential
|
|
53
|
+
* carries one or more `credentialStatus` entries. Empty / absent
|
|
54
|
+
* for credentials without a status entry.
|
|
55
|
+
*
|
|
56
|
+
* Marked `.optional()` because the underlying `ssi-ldp`
|
|
57
|
+
* serializer omits the field when empty (`skip_serializing_if`),
|
|
58
|
+
* so older WASM builds that pre-date the structured-status
|
|
59
|
+
* change still validate against this schema.
|
|
60
|
+
*/
|
|
61
|
+
status: StatusCheckEntryValidator.array().optional(),
|
|
62
|
+
});
|
|
63
|
+
export type VerificationCheck = z.infer<typeof VerificationCheckValidator>;
|
|
64
|
+
|
|
65
|
+
export const VerificationStatusValidator = z.enum(['Success', 'Failed', 'Error']);
|
|
66
|
+
export type VerificationStatus = z.infer<typeof VerificationStatusValidator>;
|
|
67
|
+
export const VerificationStatusEnum = VerificationStatusValidator.enum;
|
|
68
|
+
|
|
69
|
+
export const VerificationItemValidator = z.object({
|
|
70
|
+
check: z.string(),
|
|
71
|
+
status: VerificationStatusValidator,
|
|
72
|
+
message: z.string().optional(),
|
|
73
|
+
details: z.string().optional(),
|
|
74
|
+
});
|
|
75
|
+
export type VerificationItem = z.infer<typeof VerificationItemValidator>;
|
|
76
|
+
|
|
77
|
+
export const CredentialInfoValidator = z.object({
|
|
78
|
+
title: z.string().optional(),
|
|
79
|
+
createdAt: z.string().optional(),
|
|
80
|
+
issuer: ProfileValidator.optional(),
|
|
81
|
+
issuee: ProfileValidator.optional(),
|
|
82
|
+
credentialSubject: CredentialSubjectValidator.optional(),
|
|
83
|
+
});
|
|
84
|
+
export type CredentialInfo = z.infer<typeof CredentialInfoValidator>;
|
|
85
|
+
|
|
86
|
+
export type CredentialRecord<Metadata extends Record<string, any> = Record<never, never>> = {
|
|
87
|
+
id: string;
|
|
88
|
+
uri: string;
|
|
89
|
+
/**
|
|
90
|
+
* Wire-format discriminator for the credential. Optional — when
|
|
91
|
+
* absent, legacy readers infer it from `vc` shape (see
|
|
92
|
+
* `toStoredCredential` in `@learncard/helpers`). Populated on new
|
|
93
|
+
* writes once the consumer is format-aware.
|
|
94
|
+
*
|
|
95
|
+
* Added in ADR-0001 Phase 1 as additive metadata; existing
|
|
96
|
+
* records without this field continue to work unchanged.
|
|
97
|
+
*/
|
|
98
|
+
format?: CredentialFormat;
|
|
99
|
+
/**
|
|
100
|
+
* Optional semantic type hint for fast filtering without parsing
|
|
101
|
+
* the full credential — `vct` for SD-JWT-VC, last-non-VC type for
|
|
102
|
+
* W3C VCs, doctype for mDoc. Added in ADR-0001 Phase 1.
|
|
103
|
+
*/
|
|
104
|
+
semanticType?: string;
|
|
105
|
+
/**
|
|
106
|
+
* On-the-wire representation for formats whose `vc` field cannot
|
|
107
|
+
* hold the canonical form (SD-JWT compact, JWT-VC compact, base64
|
|
108
|
+
* mDoc CBOR). Undefined for W3C VCs (`vc` IS the wire form). Added
|
|
109
|
+
* in ADR-0001 Phase 1.
|
|
110
|
+
*/
|
|
111
|
+
rawWireForm?: string;
|
|
112
|
+
[key: string]: any;
|
|
113
|
+
} & Metadata;
|
|
114
|
+
|
|
115
|
+
export const CredentialRecordValidator = z
|
|
116
|
+
.object({
|
|
117
|
+
id: z.string(),
|
|
118
|
+
uri: z.string(),
|
|
119
|
+
format: CredentialFormatValidator.optional(),
|
|
120
|
+
semanticType: z.string().optional(),
|
|
121
|
+
rawWireForm: z.string().optional(),
|
|
122
|
+
})
|
|
123
|
+
.catchall(z.any()) satisfies z.ZodType<CredentialRecord>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
import { PaginationResponseValidator } from './mongo';
|
|
4
|
+
import { JWEValidator } from './crypto';
|
|
5
|
+
|
|
6
|
+
export const EncryptedRecordValidator = z
|
|
7
|
+
.object({ encryptedRecord: JWEValidator, fields: z.string().array() })
|
|
8
|
+
.catchall(z.any());
|
|
9
|
+
export type EncryptedRecord = z.infer<typeof EncryptedRecordValidator>;
|
|
10
|
+
|
|
11
|
+
export const PaginatedEncryptedRecordsValidator = PaginationResponseValidator.extend({
|
|
12
|
+
records: EncryptedRecordValidator.array(),
|
|
13
|
+
});
|
|
14
|
+
export type PaginatedEncryptedRecordsType = z.infer<typeof PaginatedEncryptedRecordsValidator>;
|
|
15
|
+
|
|
16
|
+
export const EncryptedCredentialRecordValidator = EncryptedRecordValidator.extend({
|
|
17
|
+
id: z.string(),
|
|
18
|
+
});
|
|
19
|
+
export type EncryptedCredentialRecord = z.infer<typeof EncryptedCredentialRecordValidator>;
|
|
20
|
+
|
|
21
|
+
export const PaginatedEncryptedCredentialRecordsValidator = PaginationResponseValidator.extend({
|
|
22
|
+
records: EncryptedCredentialRecordValidator.array(),
|
|
23
|
+
});
|
|
24
|
+
export type PaginatedEncryptedCredentialRecordsType = z.infer<
|
|
25
|
+
typeof PaginatedEncryptedCredentialRecordsValidator
|
|
26
|
+
>;
|
package/src/mongo.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
export const PaginationOptionsValidator = z.object({
|
|
4
|
+
limit: z.number(),
|
|
5
|
+
cursor: z.string().optional(),
|
|
6
|
+
sort: z.string().optional(),
|
|
7
|
+
});
|
|
8
|
+
export type PaginationOptionsType = z.infer<typeof PaginationOptionsValidator>;
|
|
9
|
+
|
|
10
|
+
export const PaginationResponseValidator = z.object({
|
|
11
|
+
cursor: z.string().optional(),
|
|
12
|
+
hasMore: z.boolean(),
|
|
13
|
+
});
|
|
14
|
+
export type PaginationResponseType = z.infer<typeof PaginationResponseValidator>;
|
package/src/obv3.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import {
|
|
3
|
+
UnsignedVCValidator,
|
|
4
|
+
ProofValidator,
|
|
5
|
+
ProfileValidator,
|
|
6
|
+
ImageValidator,
|
|
7
|
+
IdentifierEntryValidator,
|
|
8
|
+
} from './vc';
|
|
9
|
+
|
|
10
|
+
export const AlignmentTargetTypeValidator = z
|
|
11
|
+
.enum([
|
|
12
|
+
'ceasn:Competency',
|
|
13
|
+
'ceterms:Credential',
|
|
14
|
+
'CFItem',
|
|
15
|
+
'CFRubric',
|
|
16
|
+
'CFRubricCriterion',
|
|
17
|
+
'CFRubricCriterionLevel',
|
|
18
|
+
'CTDL',
|
|
19
|
+
])
|
|
20
|
+
.or(z.string());
|
|
21
|
+
export type AlignmentTargetType = z.infer<typeof AlignmentTargetTypeValidator>;
|
|
22
|
+
|
|
23
|
+
export const AlignmentValidator = z.object({
|
|
24
|
+
type: z.string().array().nonempty(),
|
|
25
|
+
targetCode: z.string().optional(),
|
|
26
|
+
targetDescription: z.string().optional(),
|
|
27
|
+
targetName: z.string(),
|
|
28
|
+
targetFramework: z.string().optional(),
|
|
29
|
+
targetType: AlignmentTargetTypeValidator.optional(),
|
|
30
|
+
targetUrl: z.string(),
|
|
31
|
+
});
|
|
32
|
+
export type Alignment = z.infer<typeof AlignmentValidator>;
|
|
33
|
+
|
|
34
|
+
export const KnownAchievementTypeValidator = z.enum([
|
|
35
|
+
'Achievement',
|
|
36
|
+
'ApprenticeshipCertificate',
|
|
37
|
+
'Assessment',
|
|
38
|
+
'Assignment',
|
|
39
|
+
'AssociateDegree',
|
|
40
|
+
'Award',
|
|
41
|
+
'Badge',
|
|
42
|
+
'BachelorDegree',
|
|
43
|
+
'Certificate',
|
|
44
|
+
'CertificateOfCompletion',
|
|
45
|
+
'Certification',
|
|
46
|
+
'CommunityService',
|
|
47
|
+
'Competency',
|
|
48
|
+
'Course',
|
|
49
|
+
'CoCurricular',
|
|
50
|
+
'Degree',
|
|
51
|
+
'Diploma',
|
|
52
|
+
'DoctoralDegree',
|
|
53
|
+
'Fieldwork',
|
|
54
|
+
'GeneralEducationDevelopment',
|
|
55
|
+
'JourneymanCertificate',
|
|
56
|
+
'LearningProgram',
|
|
57
|
+
'License',
|
|
58
|
+
'Membership',
|
|
59
|
+
'ProfessionalDoctorate',
|
|
60
|
+
'QualityAssuranceCredential',
|
|
61
|
+
'MasterCertificate',
|
|
62
|
+
'MasterDegree',
|
|
63
|
+
'MicroCredential',
|
|
64
|
+
'ResearchDoctorate',
|
|
65
|
+
'SecondarySchoolDiploma',
|
|
66
|
+
]);
|
|
67
|
+
export type KnownAchievementType = z.infer<typeof KnownAchievementTypeValidator>;
|
|
68
|
+
|
|
69
|
+
export const AchievementTypeValidator = KnownAchievementTypeValidator.or(z.string());
|
|
70
|
+
export type AchievementType = z.infer<typeof AchievementTypeValidator>;
|
|
71
|
+
|
|
72
|
+
export const CriteriaValidator = z
|
|
73
|
+
.object({ id: z.string().optional(), narrative: z.string().optional() })
|
|
74
|
+
.catchall(z.any());
|
|
75
|
+
export type Criteria = z.infer<typeof CriteriaValidator>;
|
|
76
|
+
|
|
77
|
+
export const EndorsementSubjectValidator = z.object({
|
|
78
|
+
id: z.string(),
|
|
79
|
+
type: z.string().array().nonempty(),
|
|
80
|
+
endorsementComment: z.string().optional(),
|
|
81
|
+
});
|
|
82
|
+
export type EndorsementSubject = z.infer<typeof EndorsementSubjectValidator>;
|
|
83
|
+
|
|
84
|
+
export const EndorsementCredentialValidator = UnsignedVCValidator.extend({
|
|
85
|
+
credentialSubject: EndorsementSubjectValidator,
|
|
86
|
+
proof: ProofValidator.or(ProofValidator.array()).optional(),
|
|
87
|
+
});
|
|
88
|
+
export type EndorsementCredential = z.infer<typeof EndorsementCredentialValidator>;
|
|
89
|
+
|
|
90
|
+
export const RelatedValidator = z.object({
|
|
91
|
+
id: z.string(),
|
|
92
|
+
'@language': z.string().optional(),
|
|
93
|
+
version: z.string().optional(),
|
|
94
|
+
});
|
|
95
|
+
export type Related = z.infer<typeof RelatedValidator>;
|
|
96
|
+
|
|
97
|
+
export const ResultTypeValidator = z
|
|
98
|
+
.enum([
|
|
99
|
+
'GradePointAverage',
|
|
100
|
+
'LetterGrade',
|
|
101
|
+
'Percent',
|
|
102
|
+
'PerformanceLevel',
|
|
103
|
+
'PredictedScore',
|
|
104
|
+
'RawScore',
|
|
105
|
+
'Result',
|
|
106
|
+
'RubricCriterion',
|
|
107
|
+
'RubricCriterionLevel',
|
|
108
|
+
'RubricScore',
|
|
109
|
+
'ScaledScore',
|
|
110
|
+
'Status',
|
|
111
|
+
])
|
|
112
|
+
.or(z.string());
|
|
113
|
+
export type ResultType = z.infer<typeof ResultTypeValidator>;
|
|
114
|
+
|
|
115
|
+
export const RubricCriterionValidator = z
|
|
116
|
+
.object({
|
|
117
|
+
id: z.string(),
|
|
118
|
+
type: z.string().array().nonempty(),
|
|
119
|
+
alignment: AlignmentValidator.array().optional(),
|
|
120
|
+
description: z.string().optional(),
|
|
121
|
+
level: z.string().optional(),
|
|
122
|
+
name: z.string(),
|
|
123
|
+
points: z.string().optional(),
|
|
124
|
+
})
|
|
125
|
+
.catchall(z.any());
|
|
126
|
+
export type RubricCriterion = z.infer<typeof RubricCriterionValidator>;
|
|
127
|
+
|
|
128
|
+
export const ResultDescriptionValidator = z
|
|
129
|
+
.object({
|
|
130
|
+
id: z.string(),
|
|
131
|
+
type: z.string().array().nonempty(),
|
|
132
|
+
alignment: AlignmentValidator.array().optional(),
|
|
133
|
+
allowedValue: z.string().array().optional(),
|
|
134
|
+
name: z.string(),
|
|
135
|
+
requiredLevel: z.string().optional(),
|
|
136
|
+
requiredValue: z.string().optional(),
|
|
137
|
+
resultType: ResultTypeValidator,
|
|
138
|
+
rubricCriterionLevel: RubricCriterionValidator.array().optional(),
|
|
139
|
+
valueMax: z.string().optional(),
|
|
140
|
+
valueMin: z.string().optional(),
|
|
141
|
+
})
|
|
142
|
+
.catchall(z.any());
|
|
143
|
+
export type ResultDescription = z.infer<typeof ResultDescriptionValidator>;
|
|
144
|
+
|
|
145
|
+
export const EvidenceValidator = z
|
|
146
|
+
.object({
|
|
147
|
+
id: z.string().optional(),
|
|
148
|
+
type: z.array(z.string()).nonempty(),
|
|
149
|
+
name: z.string().optional(),
|
|
150
|
+
narrative: z.string().optional(),
|
|
151
|
+
description: z.string().optional(),
|
|
152
|
+
genre: z.string().optional(),
|
|
153
|
+
audience: z.string().optional(),
|
|
154
|
+
})
|
|
155
|
+
.catchall(z.any());
|
|
156
|
+
|
|
157
|
+
export type Evidence = z.infer<typeof EvidenceValidator>;
|
|
158
|
+
|
|
159
|
+
export const AchievementValidator = z
|
|
160
|
+
.object({
|
|
161
|
+
id: z.string().optional(),
|
|
162
|
+
type: z.array(z.string()).nonempty(),
|
|
163
|
+
alignment: AlignmentValidator.array().optional(),
|
|
164
|
+
achievementType: AchievementTypeValidator.optional(),
|
|
165
|
+
creator: ProfileValidator.optional(),
|
|
166
|
+
creditsAvailable: z.number().optional(),
|
|
167
|
+
criteria: CriteriaValidator,
|
|
168
|
+
description: z.string(),
|
|
169
|
+
endorsement: EndorsementCredentialValidator.array().optional(),
|
|
170
|
+
fieldOfStudy: z.string().optional(),
|
|
171
|
+
humanCode: z.string().optional(),
|
|
172
|
+
image: ImageValidator.optional(),
|
|
173
|
+
'@language': z.string().optional(),
|
|
174
|
+
name: z.string(),
|
|
175
|
+
otherIdentifier: IdentifierEntryValidator.array().optional(),
|
|
176
|
+
related: RelatedValidator.array().optional(),
|
|
177
|
+
resultDescription: ResultDescriptionValidator.array().optional(),
|
|
178
|
+
specialization: z.string().optional(),
|
|
179
|
+
tag: z.array(z.string()).optional(),
|
|
180
|
+
version: z.string().optional(),
|
|
181
|
+
})
|
|
182
|
+
.catchall(z.any());
|
|
183
|
+
export type Achievement = z.infer<typeof AchievementValidator>;
|
|
184
|
+
|
|
185
|
+
export const IdentityObjectValidator = z.object({
|
|
186
|
+
type: z.string(),
|
|
187
|
+
hashed: z.boolean(),
|
|
188
|
+
identityHash: z.string(),
|
|
189
|
+
identityType: z.string(),
|
|
190
|
+
salt: z.string().optional(),
|
|
191
|
+
});
|
|
192
|
+
export type IdentityObject = z.infer<typeof IdentityObjectValidator>;
|
|
193
|
+
|
|
194
|
+
export const ResultStatusTypeValidator = z.enum([
|
|
195
|
+
'Completed',
|
|
196
|
+
'Enrolled',
|
|
197
|
+
'Failed',
|
|
198
|
+
'InProgress',
|
|
199
|
+
'OnHold',
|
|
200
|
+
'Withdrew',
|
|
201
|
+
]);
|
|
202
|
+
export type ResultStatusType = z.infer<typeof ResultStatusTypeValidator>;
|
|
203
|
+
|
|
204
|
+
export const ResultValidator = z
|
|
205
|
+
.object({
|
|
206
|
+
type: z.string().array().nonempty(),
|
|
207
|
+
achievedLevel: z.string().optional(),
|
|
208
|
+
alignment: AlignmentValidator.array().optional(),
|
|
209
|
+
resultDescription: z.string().optional(),
|
|
210
|
+
status: ResultStatusTypeValidator.optional(),
|
|
211
|
+
value: z.string().optional(),
|
|
212
|
+
})
|
|
213
|
+
.catchall(z.any());
|
|
214
|
+
export type Result = z.infer<typeof ResultValidator>;
|
|
215
|
+
|
|
216
|
+
export const AchievementSubjectValidator = z
|
|
217
|
+
.object({
|
|
218
|
+
id: z.string().optional(),
|
|
219
|
+
type: z.string().array().nonempty(),
|
|
220
|
+
activityEndDate: z.string().optional(),
|
|
221
|
+
activityStartDate: z.string().optional(),
|
|
222
|
+
creditsEarned: z.number().optional(),
|
|
223
|
+
achievement: AchievementValidator.optional(),
|
|
224
|
+
identifier: IdentityObjectValidator.array().optional(),
|
|
225
|
+
image: ImageValidator.optional(),
|
|
226
|
+
licenseNumber: z.string().optional(),
|
|
227
|
+
narrative: z.string().optional(),
|
|
228
|
+
result: ResultValidator.array().optional(),
|
|
229
|
+
role: z.string().optional(),
|
|
230
|
+
source: ProfileValidator.optional(),
|
|
231
|
+
term: z.string().optional(),
|
|
232
|
+
})
|
|
233
|
+
.catchall(z.any());
|
|
234
|
+
export type AchievementSubject = z.infer<typeof AchievementSubjectValidator>;
|
|
235
|
+
|
|
236
|
+
export const UnsignedAchievementCredentialValidator = UnsignedVCValidator.extend({
|
|
237
|
+
name: z.string().optional(),
|
|
238
|
+
description: z.string().optional(),
|
|
239
|
+
image: ImageValidator.optional(),
|
|
240
|
+
credentialSubject: AchievementSubjectValidator.or(
|
|
241
|
+
AchievementSubjectValidator.array()
|
|
242
|
+
) as z.ZodUnion<
|
|
243
|
+
[typeof AchievementSubjectValidator, z.ZodArray<typeof AchievementSubjectValidator>]
|
|
244
|
+
>,
|
|
245
|
+
endorsement: UnsignedVCValidator.array().optional(),
|
|
246
|
+
});
|
|
247
|
+
export type UnsignedAchievementCredential = z.infer<typeof UnsignedAchievementCredentialValidator>;
|
|
248
|
+
|
|
249
|
+
export const AchievementCredentialValidator = UnsignedAchievementCredentialValidator.extend({
|
|
250
|
+
proof: ProofValidator.or(ProofValidator.array()),
|
|
251
|
+
});
|
|
252
|
+
export type AchievementCredential = z.infer<typeof AchievementCredentialValidator>;
|
package/src/queries.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
// Helper to extract flags and pattern from regex string
|
|
4
|
+
const parseRegexString = (regexStr: string) => {
|
|
5
|
+
const match = regexStr.match(/^\/(.*)\/([gimsuy]*)$/);
|
|
6
|
+
if (!match) throw new Error('Invalid RegExp string format');
|
|
7
|
+
return { pattern: match[1], flags: match[2] };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// TRPC validator that converts Regex strings into RegExps
|
|
11
|
+
const RegExpStringValidator = z
|
|
12
|
+
.string()
|
|
13
|
+
.refine(
|
|
14
|
+
str => {
|
|
15
|
+
try {
|
|
16
|
+
parseRegexString(str);
|
|
17
|
+
return true;
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
message: "Invalid RegExp string format. Must be in format '/pattern/flags'",
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
.transform(str => {
|
|
27
|
+
const { pattern, flags } = parseRegexString(str);
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
return new RegExp(pattern, flags);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
throw new Error(`Invalid RegExp: ${(error as Error).message}`);
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.meta({ override: { type: 'string' } });
|
|
36
|
+
|
|
37
|
+
// Do not use z.instanceof(RegExp) here: it is a `custom` Zod type that crashes
|
|
38
|
+
// zod-openapi document generation at service boot, and `.meta({ override })` is
|
|
39
|
+
// not honored for custom types. Coercing a RegExp to its `/source/flags` string
|
|
40
|
+
// keeps the OpenAPI schema a plain string while still accepting RegExp inputs.
|
|
41
|
+
export const RegExpValidator = z.preprocess(
|
|
42
|
+
value => (value instanceof RegExp ? `/${value.source}/${value.flags}` : value),
|
|
43
|
+
RegExpStringValidator
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const BaseStringQuery = z
|
|
47
|
+
.string()
|
|
48
|
+
.or(z.object({ $in: z.string().array() }))
|
|
49
|
+
.or(z.object({ $regex: RegExpValidator }));
|
|
50
|
+
|
|
51
|
+
export const StringQuery = z.union([
|
|
52
|
+
BaseStringQuery,
|
|
53
|
+
z.object({
|
|
54
|
+
$or: BaseStringQuery.array(),
|
|
55
|
+
}),
|
|
56
|
+
]);
|