You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The validation within this library is mainly done manually. Because there's a lot of models and types, this can result in a lot of manual validation logic.
We've been adopting zod into our stack, and it has been working very well for us. You define a zod object, which defines the validation logic, and based on that you can infer the typescript type (as a simple type).
This way you can easily validate every interface you have in your library. It does add some overhead as you need to validate, but I don't think it will be very significant, and it does allow to clean up a lot of the validation code.
You can use things like refine to have very special validation logic, and I think this would enforce separating validation logic from the actual implementation side of the spec.
An example with some of the credential offer types
import{z}from'zod'constzJwtVcJsonOfferFormat=z.object({format: z.literal('jwt_vc_json'),types: z.array(z.string())})constzLdpVcOfferFormat=z.object({format: z.literal('ldp_vc'),"@context": z.array(z.string().url()),types: z.array(z.string())})constzCredentialOfferFormat=z.discriminatedUnion("format",[zJwtVcJsonOfferFormat,zLdpVcOfferFormat])constzCredentialOfferPayload=z.object({credential_issuer: z.string().url(),credentials: z.array(z.union([z.string(),zCredentialOfferFormat])).nonempty()})constzCredentialOffer=z.union([z.object({credential_offer_uri: z.string().url(),}),z.object({credential_offer: zCredentialOfferPayload})])typeCredentialOfferPayload=z.infer<typeofzCredentialOfferPayload>typeCredentialOffer=z.infer<typeofzCredentialOffer>constresults=[zCredentialOffer.safeParse({credential_offer_uri: 'https://google.com'}),// validzCredentialOffer.safeParse({credential_offer: {credential_issuer: 'https://google.com',credentials: []}satisfiesCredentialOfferPayload}),// invalid, credentials must have at least one entryzCredentialOffer.safeParse({credential_offer: {credential_issuer: 'https://google.com',credentials: [{format: 'ldp_vc',"@context": ["https://google.com"],types: ["VerifiableCredential"]}]}satisfiesCredentialOfferPayload}),// validzCredentialOffer.safeParse({credential_offer: {credential_issuer: 'https://google.com',credentials: [{format: 'jwt_vc_json',"@context": ["https://google.com"],types: ["VerifiableCredential"]}]}satisfiesCredentialOfferPayload})// "@context" is not defiend for jwt_vc_json. If we enable .strict() on the object it will error, but by default it will remove unknown properties]console.log(JSON.stringify(results,null,2))
Yes for sure like this approach. Given it is a standalone library with 0 deps focused on something we now do manually I have no objections to using something like this, as it will only make all our lives better and reduce the amount of bugs
The validation within this library is mainly done manually. Because there's a lot of models and types, this can result in a lot of manual validation logic.
We've been adopting zod into our stack, and it has been working very well for us. You define a zod object, which defines the validation logic, and based on that you can infer the typescript type (as a simple type).
This way you can easily validate every interface you have in your library. It does add some overhead as you need to validate, but I don't think it will be very significant, and it does allow to clean up a lot of the validation code.
You can use things like
refine
to have very special validation logic, and I think this would enforce separating validation logic from the actual implementation side of the spec.An example with some of the credential offer types
This results in the following output:
Here's a codesandbox with the code: https://codesandbox.io/s/typescript-playground-export-forked-nrwgg4
The text was updated successfully, but these errors were encountered: