1"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6414],{3204:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>d});var r=s(4848),a=s(8453);const t={},i=void 0,o={id:"js-cookbook/data-validation",title:"data-validation",description:"Zod",source:"@site/docs/js-cookbook/13-data-validation.md",sourceDirName:"js-cookbook",slug:"/js-cookbook/data-validation",permalink:"/docs/js-cookbook/data-validation",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:13,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"JS-code-performance",permalink:"/docs/js-cookbook/JS-code-performance"},next:{title:"image-libraries",permalink:"/docs/js-cookbook/image-libraries"}},c={},d=[{value:"Zod",id:"zod",level:2},{value:"Basics",id:"basics",level:3},{value:"<code>z.infer<T></code>",id:"zinfert",level:3},{value:"zod types",id:"zod-types",level:3},{value:"<strong>primitive zod types</strong>",id:"primitive-zod-types",level:4},{value:"Special string zod types",id:"special-string-zod-types",level:4},{value:"<strong>object zod types</strong>",id:"object-zod-types",level:4},{value:"<strong>array zod types</strong>",id:"array-zod-types",level:4},{value:"Modifiers",id:"modifiers",level:3},{value:"<strong>universal modifiers</strong>",id:"universal-modifiers",level:4},{value:"Type branding: string modifiers",id:"type-branding-string-modifiers",level:4},{value:"Array modifiers",id:"array-modifiers",level:4},{value:"Object modifiers",id:"object-modifiers",level:4},{value:"Transforms, coerce, and preprocessing",id:"transforms-coerce-and-preprocessing",level:4},{value:"Miscellaneous Zod types",id:"miscellaneous-zod-types",level:3},{value:"Enums, unions, tuples, intersections",id:"enums-unions-tuples-intersections",level:4},{value:"Discriminated unions",id:"discriminated-unions",level:4},{value:"records, maps",id:"records-maps",level:4},{value:"Zod validation class",id:"zod-validation-class",level:3},{value:"Custom validation",id:"custom-validation",level:3},{value:"Adding custom messages",id:"adding-custom-messages",level:4},{value:"Creating recursive schemas with <code>z.lazy()</code>",id:"creating-recursive-schemas-with-zlazy",level:3},{value:"TypeScript types to zod schemas",id:"typescript-types-to-zod-schemas",level:3},{value:"Zod use cases",id:"zod-use-cases",level:3},{value:"Zod with basic form validation",id:"zod-with-basic-form-validation",level:4},{value:"Zod with React Hook Form",id:"zod-with-react-hook-form",level:4},{value:"Some bullshit",id:"some-bullshit",level:3}];function l(e){const n={code:"code",div:"div",em:"em",h2:"h2",h3:"h3",h4:"h4",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",path:"path",pre:"pre",strong:"strong",svg:"svg",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"zod",children:"Zod"}),"\n",(0,r.jsx)(n.p,{children:"Zod is a schema-based way of doing type-inference and checking at runtime while also getting TS compiler hints that make for a good dev experience."}),"\n",(0,r.jsx)(n.h3,{id:"basics",children:"Basics"}),"\n",(0,r.jsx)(n.p,{children:"previously to check if something was a user, you would have to run typescript type guards like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// Runtime type checking can impact performance\nfunction validateUser(data: unknown): User {\n if (\n typeof data !== 'object' ||\n data === null ||\n !('username' in data) ||\n !('email' in data) ||\n typeof data.username !== 'string' ||\n typeof data.email !== 'string'\n ) {\n throw new ValidationError('Invalid user data');\n }\n\n return data as User;\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"But with Zod, you reduce that unwieldiness to a more flexible form:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'import { z } from "zod";\n\nconst userSchema = z.object({\n name: z.string(),\n age: z.number(),\n});\n\n// simple type guard\nfunction isUser(user: unknown): user is z.infer<typeof userSchema> {\n return userSchema.safeParse(user).success;\n}\n\n// parse that throws error\nfunction validateUser(user: unknown) {\n return userSchema.parse(user);\n}\n\n// succeeds\nconst user = validateUser({ name: "John", age: 30 });\nconsole.log(user);\n\n// fails\nconst user2 = validateUser({ name: "John", age: "30" });\nconsole.log(user2);\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The basic flow of using zod is to first create a ",(0,r.jsx)(n.strong,{children:"schema"}),", and then use that schema to validate objects of an unknown type. You have two paths to do so:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"parsing"}),": throws an error if the value does not fit the schema"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"safe parsing"}),": does not throw an error, only returns a boolean telling whether or not the value fits the schema."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"But after validation, you will get back the object with typescript type inference both at runtime and compile time, offering great dx."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.infer<typeof someSchema>"}),": a custom generic typing that zod provides to extract the base type that a schema describes, reducing code duplication."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"schema.parse(value)"}),": parses the value and returns it if it passes, throws an error if it does not fit the schema."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"schema.safeParse(value)"}),": returns a ",(0,r.jsx)(n.code,{children:"success"})," property you can access that tells you whether or not the obejct you passed in fit the schema."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"We can generalize this pattern for any schema using generics"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'function isOfType<T>(value: unknown, schema: z.ZodType<T>): value is T {\n return schema.safeParse(value).success;\n}\n\nconst user3 = { name: "John", age: 30 };\nconst user4 = { name: "John", age: "30" };\n\nconsole.log(isOfType(user3, userSchema));\nconsole.log(isOfType(user4, userSchema));\n\nfunction validateSchema<T>(value: unknown, schema: z.ZodType<T>) {\n return schema.parse(value);\n}\n\nconst user5 = { name: "John", age: 30 };\nconst user6 = { name: "John", age: "30" };\n\nconsole.log(validateSchema(user5, userSchema));\nconsole.log(validateSchema(user6, userSchema));\n'})}),"\n",(0,r.jsx)(n.p,{children:"You can use the below class for general validation:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"export class Validation<T> {\n constructor(public schema: z.ZodType<T>) {}\n\n isOfType(value: unknown): value is T {\n return this.schema.safeParse(value).success;\n }\n\n validateSchema(value: unknown) {\n return this.schema.parse(value);\n }\n}\n"})}
1),"\n",(0,r.jsx)(n.p,{children:"Then I use it in an example:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'\nconst dogSchema = z.object({\n name: z.string(),\n breed: z.enum(["labador", "weenie"]),\n});\n\nconst dogValidator = new Validation(dogSchema);\nconsole.log(\n dogValidator.isOfType({\n name: "brah",\n breed: "labador",\n })\n);\n'})}),"\n",(0,r.jsx)(n.h3,{id:"zinfert",children:(0,r.jsx)(n.code,{children:"z.infer<T>"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"z.infer<T>"})," generic type takes in a zod object type and returns the inferred type structure that the schema specifies, which gives you a handy way to create a typescript interface derived from the schema structure. This has two main benefits:"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Keeps types and schemas in sync"}),"\n",(0,r.jsx)(n.li,{children:"Reduces code duplication (no need for separate typescript types, just derive them from zod.)"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import { z } from 'zod';\n\nexport const UserSchema = z.object({\n name: z.string().min(1, \"Name can't be empty\"),\n email: z.email('Invalid email format'),\n age: z.number().int().min(1).max(120),\n});\n\n// Automatically infer the TypeScript type\nexport type UserType = z.infer<typeof UserSchema>;\n"})}),"\n",(0,r.jsx)(n.h3,{id:"zod-types",children:"zod types"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Zod types"})," include objects, arrays, and primitives. For all purposes, zod types mean using any ",(0,r.jsx)(n.code,{children:"z.object()"}),", ",(0,r.jsx)(n.code,{children:"z.array()"}),", or any other zod primitive type."]}),"\n",(0,r.jsx)(n.h4,{id:"primitive-zod-types",children:(0,r.jsx)(n.strong,{children:"primitive zod types"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.p,{children:"It's important to understand a few primitive zod types:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.number()"}),": a number type"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.string()"}),": a string type"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.date()"}),": a ",(0,r.jsx)(n.code,{children:"Date"})," type"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.boolean()"}),": a boolean type"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.undefined()"}),": a undefined type"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.null()"}),": a null type"]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"special-string-zod-types",children:"Special string zod types"}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.p,{children:"Here are some special stirng zod types because they represent common types of validation:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.email()"}),": email validation"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.uuid()"}),": uuid validation"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.url()"}),": url validation"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.literal(str)"}),": specifies a string type that can only be the literal string value you pass in."]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"object-zod-types",children:(0,r.jsx)(n.strong,{children:"object zod types"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["You can build any schema based off the ",(0,r.jsx)(n.code,{children:"z.object()"})," type which represents a javascript object where the keys should have values that are primitive zod types."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const userSchema = z.object({\n name: z.string(),\n email: z.string(),\n age: z.number()\n});\n"})}),"\n",(0,r.jsx)(n.h4,{id:"array-zod-types",children:(0,r.jsx)(n.strong,{children:"array zod types"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["You can create array types in zod with the ",(0,r.jsx)(n.code,{children:"z.array()"})," method and then passing in any zod type. You can basically pass in anything:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const strArray = z.array(z.string())\nconst dogArray = z.array(z.object({\n name: z.string(),\n breed: z.string(),\n age: z.number().gt(0).lt(30)\n}))\n"})}),"\n",(0,r.jsx)(n.h3,{id:"modifiers",children:"Modifiers"}),"\n",(0,r.jsxs)(n.p,{children:["You can use ",(0,r.jsx)(n.strong,{children:"modifiers"})," which chain on primitive types to give more type checking at runtime, such as email check, strong password check, number value checking, etc., which is all invaluable stuff to have at runtime."]}),"\n",(0,r.jsxs)(n.p,{children:["The most basic modifier is ",(0,r.jsx)(n.code,{children:"z.optional()"}),", but there are others"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// create user schema with optional age, and email 6-40 chars long\nconst userSchema = z.object({\n name: z.string(),\n email: z.string().min(6).max(40),\n age: z.number().optional()\n});\n"})}),"\n",(0,r.jsx)(n.h4,{id:"universal-modifiers",children:(0,r.jsx)(n.strong,{children:"universal modifiers"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.p,{children:"these modifiers are universal and can be used on any primitive type:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.optional()"}),": makes the value optional"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.nullable()"}),": makes the value able to be equal to ",(0,r.jsx)(n.code,{children:"null"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.nullish()"}),": makes the value able to be equal to ",(0,r.jsx)(n.code,{children:"null"})," or ",(0,r.jsx)(n.code,{children:"undefined"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.default(value)"}),": provides a default value if a value is not provided. This only makes sense when combined with ",(0,r.jsx)(n.code,{children:"z.optional()"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.literal(value)"}),": forces the value to be typed literally, as if using ",(0,r.jsx)(n.code,{children:"as const"})]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"type-branding-string-modifiers",children:"Type branding: string modifiers"}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["These modifiers chain onto a ",(0,r.jsx)(n.code,{children:"z.string()"})," instance:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.brand<T>()"}),": used for ",(0,r.jsx)(n.strong,{children:"type branding"}),", when you want typescript to infer your string type as a literal."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Zod has a concept of \u201cbranded\u201d types, letting you layer on custom brand markers to differentiate otherwise identical primitives. This is great if you want to give a type special meaning without creating a new runtime type. For instance, you can have a UserId that\u2019s just a string under the hood but is recognized as a distinct brand in your code:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const hexColorSchema = z\n .string()\n .regex(/^#([0-9a-fA-F]{6})$/)\n .brand<HexColor>();\n\nconst hexColor = hexColorSchema.parse("#123456");\n'})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const userIdSchema = z.string().uuid().brand<'UserId'>();\n\ntype UserId = z.infer<typeof userIdSchema>; // string & { __brand: \"UserId\" }\n\nconst userId = userIdSchema.parse('7c45ae8a-cf6e-4f72-b12f-6fbb21ce3ab9'); // works\nuserIdSchema.parse('not-a-uuid'); // throws ZodError\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import { z } from 'zod';\n\nconst emailSchema = z.string().email().brand<'EmailAddress'>();\n\ntype EmailAddress = z.infer<typeof emailSchema>;\n// => string & { __brand: \"EmailAddress\" }\n\nconst email = emailSchema.parse('[email protected]');\n// Type is EmailAddress\n\nfunction sendEmail(to: EmailAddress) {\n console.log('Sending email to', to);\n}\n\nsendEmail(email);\n// Works\n\nsendEmail('unbranded string');\n// Type error: not EmailAddress\n"})}),"\n",(0,r.jsx)(n.h4,{id:"array-modifiers",children:"Array modifiers"}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["These modifiers chain onto a ",(0,r.jsx)(n.code,{children:"z.array()"})," instance:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.nonempty()"}),": ensures that the array has at least one element."]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"object-modifiers",children:"Object modifiers"}),"\n",(0,r.jsxs)(n.p,{children:["There are some modifiers that apply to ",(0,r.jsx)(n.code,{children:"z.object()"})," types:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.partial()"}),": makes all properties in the object optional (useful for updating)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.pick(object)"}),": returns only the specified keys, where you specify which ones you want is a ",(0,r.jsx)(n.code,{children:"Record<key
1of schema, true>"})," key value pair"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.omit(object)"}),": omits only the specified keys, where you specify which ones you want is a ",(0,r.jsx)(n.code,{children:"Record<keyof schema, true>"})," key value pair"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Here is how these work:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://res.cloudinary.com/dsmvtmv8z/image/upload/v1748038218/image-clipboard-assets/okwhvkfbh6ddeq5lvedv.webp",alt:""})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"extending schema"})}),"\n",(0,r.jsxs)(n.p,{children:["With the ",(0,r.jsx)(n.code,{children:"z.merge()"})," and ",(0,r.jsx)(n.code,{children:"z.extend()"})," modifiers, both which act on object schemas and take in additional object schemas as arguments, you can create new schemas from other object schemas."]}),"\n",(0,r.jsxs)(n.div,{className:"markdown-alert markdown-alert-note",dir:"auto",children:["\n",(0,r.jsxs)(n.p,{className:"markdown-alert-title",dir:"auto",children:[(0,r.jsx)(n.svg,{className:"octicon",viewBox:"0 0 16 16",width:"16",height:"16","aria-hidden":"true",children:(0,r.jsx)(n.path,{d:"M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"})}),"NOTE"]}),"\n",(0,r.jsx)(n.p,{children:"Extending and merging do the same thing. The only difference is that they take in different arguments:"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"merge()"})," takes in a zod object schema while ",(0,r.jsx)(n.code,{children:"extend()"})," takes in a javascript object."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Extending works by taking in a simple object of properties to add onto the schema, not a separate schema."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const dogSchema = z.object({\n name: z.string(),\n});\n\nconst tinyDogSchema = dogSchema.extend({\n tiny: z.literal(true),\n});\n\nconst { name, tiny } = tinyDogSchema.parse({});\n"})}),"\n",(0,r.jsx)(n.p,{children:"Merging works by taking in a zod object schema to merge into, making an entirely new schema:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const catSchema = z.object({\n name: z.string(),\n meows: z.literal(true),\n});\n\nconst dogOrCatSchema = dogSchema.merge(catSchema);\nconst {meows, name} = dogOrCatSchema.parse({});\n"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Zod modes"})}),"\n",(0,r.jsxs)(n.p,{children:["There are three main modes in zod when it deals with the concept of ",(0,r.jsx)(n.strong,{children:"duck typing"})," and how to deal with objects that fit the schema but have have extra properties:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"strip mode (default)"}),": If an object that fits the schema also has extra properties, Zod will automatically transform it to strip those extra properties so that the returned object EXACTLY fits the schema"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"passthrough mode"}),": If an object that fits the schema also has extra properties, Zod will let the object keep those properties. This is useful for being permissive and for doing debugging."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"strict mode"}),": If an object that fits the schema also has extra properties, Zod will interpret that as failing the schema and will throw an error."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const baseObj = z.object({ name: z.string() });\n\n// Strict\nconst strictObj = baseObj.strict();\nstrictObj.parse({ name: 'Zod', age: 99 });\n// => throws: unrecognized key \"age\"\n\n// Passthrough\nconst passObj = baseObj.passthrough();\npassObj.parse({ name: 'Zod', age: 99 });\n// => { name: \"Zod\", age: 99 }\n\n// Default (strip)\nbaseObj.parse({ name: 'Zod', age: 99 });\n// => { name: \"Zod\" } (age is stripped out)\n"})}),"\n",(0,r.jsxs)(n.div,{className:"markdown-alert markdown-alert-note",dir:"auto",children:["\n",(0,r.jsxs)(n.p,{className:"markdown-alert-title",dir:"auto",children:[(0,r.jsx)(n.svg,{className:"octicon",viewBox:"0 0 16 16",width:"16",height:"16","aria-hidden":"true",children:(0,r.jsx)(n.path,{d:"M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"})}),"NOTE"]}),"\n",(0,r.jsx)(n.p,{children:"To remember it better, you can think about these modes from least permissive to most permissive:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"strict"})," (least permissive) -> ",(0,r.jsx)(n.strong,{children:"strip"})," (default) -> ",(0,r.jsx)(n.strong,{children:"passthrough"})," (most permissive)"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h4,{id:"transforms-coerce-and-preprocessing",children:"Transforms, coerce, and preprocessing"}),"\n",(0,r.jsxs)(n.p,{children:["Transforms work to ensure that a variable fits a zod schema first, and after it does so, it runs additional transformations on that value using ",(0,r.jsx)(n.code,{children:"z.transform()"}),". This is useful for reusable pipelines:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'import { z } from "npm:zod";
1\n\nconst stringToDateSchema = z.string().transform((val) => {\n try {\n return new Date(val);\n } catch (e) {\n throw e\n }\n});\n\nconst date = stringToDateSchema.parse("2025-05-25");\nconsole.log(date);\n'})}),"\n",(0,r.jsxs)(n.p,{children:["In the example above, we approached the difficult problem of determining whether or not a string represents a valid date string by first ensuring it was a string, and then trying to transform it into a ",(0,r.jsx)(n.code,{children:"Date"})," object in javascript with ",(0,r.jsx)(n.code,{children:"z.transform()"}),":"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"If transformation works, then date string was valid"}),"\n",(0,r.jsx)(n.li,{children:"If transformation fails, throw an error"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"coercing"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["If you don't want to go through the hassle of writing a custom transform and instead just want to force an input to be a certain type, you can use the ",(0,r.jsx)(n.code,{children:"z.coerce.<type>"})," modifier, of which there are three types:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.coerce.boolean(val)"}),": schema that casts the passed in value to a boolean."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.coerce.date(val)"}),": schema that casts the passed in value to a date."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"z.coerce.number(val)"}),": schema that casts the passed in value to a number."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"This is how we can rewrite the above example in less code to check if a string represents a date, and if so, convert it to a date else throw an error."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const stringToDateSchema = z.string().pipe(z.coerce.date());\n\nconst date = stringToDateSchema.parse("2025-05-25"); // "dog" would fail\nconsole.log(date);\n'})}),"\n",(0,r.jsxs)(n.div,{className:"markdown-alert markdown-alert-note",dir:"auto",children:["\n",(0,r.jsxs)(n.p,{className:"markdown-alert-title",dir:"auto",children:[(0,r.jsx)(n.svg,{className:"octicon",viewBox:"0 0 16 16",width:"16",height:"16","aria-hidden":"true",children:(0,r.jsx)(n.path,{d:"M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"})}),"NOTE"]}),"\n",(0,r.jsxs)(n.p,{children:["If you pass in a value into ",(0,r.jsx)(n.code,{children:"z.coerce()"})," that cannot be coerced at all (zod tries its hardest), then it would throw an error."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"preprocessing"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"z.preprocess(fn: (input: unknown) => unknown, schema: ZodSchema)"}),"\xa0applies a preprocessing function\xa0",(0,r.jsx)(n.em,{children:"before"}),"\xa0validation. Useful for cleaning up or transforming input data before it\u2019s validated against the core schema."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const preprocessNumberSchema = z.preprocess((val) => {\n if (typeof val === 'string') {\n return parseInt(val, 10); // Try to parse string to number\n }\n return val; // Otherwise, return original value\n}, z.number().positive());\n\npreprocessNumberSchema.parse('42'); // Valid, returns 42 (number)\npreprocessNumberSchema.parse(42); // Valid, returns 42 (number)\n// preprocessNumberSchema.parse(\"abc\"); // Throws ZodError (after preprocessing): Expected number, received nan\n"})}),"\n",(0,r.jsx)(n.p,{children:"Keeping these validations separate from the raw schema logic keeps your code cleaner and more manageable."}),"\n",(0,r.jsx)(n.h3,{id:"miscellaneous-zod-types",children:"Miscellaneous Zod types"}),"\n",(0,r.jsx)(n.h4,{id:"enums-unions-tuples-intersections",children:"Enums, unions, tuples, intersections"}),"\n",(0,r.jsx)(n.p,{children:"you can create an enum like so to create union literal typing like so:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const dogSchema = z.object({\n breed: z.enum(["labador", "weenie"] as const),\n});\n'})}),"\n",(0,r.jsxs)(n.p,{children:["You can create a tuple with ",(0,r.jsx)(n.code,{children:"z.tuple()"})," and then pass in an array of zod types:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const coords = z.tuple([z.number(), z.number(), z.number()]) // x,y,x\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can create a union type with ",(0,r.jsx)(n.code,{children:"z.union()"})," type which takes in an array of zod types:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const stringOrNumber = z.union([z.string(), z.number()])\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Intersections are basically the same thing as merging schemas, but can be applied to all zod types, not just objects. You use them with the ",(0,r.jsx)(n.code,{children:"z.intersect()"})," method:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const stringSchema = z.object({ a: z.string() });\nconst numberSchema = z.object({ b: z.number() });\nconst intersectionSchema = z.intersection(stringSchema, numberSchema);\n"})}),"\n",(0,r.jsx)(n.h4,{id:"discriminated-unions",children:"Discriminated unions"}),"\n",(0,r.jsxs)(n.p,{children:["When your data has a known \u201cdiscriminator\u201d field,\xa0",(0,r.jsx)(n.code,{children:"z.discriminatedUnion()"}),"\xa0is more efficient (and more explicit) than normal unions."]}),"\n",(0,r.jsx)(n.p,{children:"here are the benefits:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Performance"}),": Zod can skip checking every union branch once it sees the discriminator."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Clarity"}),": If your input object\u2019s\xa0",(0,r.jsx)(n.code,{children:"type"}),"\xa0or\xa0",(0,r.jsx)(n.code,{children:"kind"}),"\xa0is incorrect, you\u2019ll get an immediate error."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import { z } from 'zod';\n\nconst customerSchema = z.object({\n type: z.literal('customer'),\n orders: z.array(z.string()),\n});\n\nconst adminSchema = z.object({\n type: z.literal('admin'),\n permissions: z.array(z.string()),\n});\n\nconst userSchema = z.discriminatedUnion('type', [customerSchema, adminSchema]);\n\n// Succeeds if type === 'customer' or 'admin'\nuserSchema.parse({\n type: 'customer',\n orders: ['order1', 'order2'],\n});\n"})}),"\n",(0,r.jsx)(n.h4,{id:"records-maps",children:"records, maps"}),"\n",(0,r.jsxs)(n.p,{children:["Records in zod have a string up on their TS counterparts because of the power of runtime val
1idation and stringent requirements. You can use the ",(0,r.jsx)(n.code,{children:"z.record()"})," method and then pass in any single zod type."]}),"\n",(0,r.jsx)(n.p,{children:"Check, for example, this record that maps user ids to their emails:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const userToEmailMap = z.record(\n z.string().min(6).max(40).endsWith("@gmail.com")\n);\n\n'})}),"\n",(0,r.jsxs)(n.p,{children:["For a more performant solution concerning dealing with objects with an immense number of keys, you can use maps with ",(0,r.jsx)(n.code,{children:"z.map()"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const stringOrNumber = z.union([z.string(), z.number()]);\n\nconst userSchema2 = z.object({\n name: z.string(),\n email: z.string(),\n});\n// create map of type Map<string, {name: string, email: string}>\nconst userIdToInfoMap = z.map(z.uuid(), userSchema2);\n\nconst map = new Map([\n ["thing", {\n email: "[email protected]", \n name: "thing2"\n }]\n]) as z.infer<typeof userIdToInfoMap>\n'})}),"\n",(0,r.jsx)(n.h3,{id:"zod-validation-class",children:"Zod validation class"}),"\n",(0,r.jsx)(n.p,{children:"Here is a wrapper I wrote around some common zod functionality:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'export class Validation<T extends Record<string, any>> {\n constructor(public schema: z.ZodObject<T>) {}\n\n createObjectWithAutocomplete(obj: T) {\n return obj;\n }\n\n isOfType(value: unknown): value is T {\n return this.schema.safeParse(value).success;\n }\n\n validateSchema(value: unknown) {\n return this.schema.parse(value);\n }\n\n pick(value: unknown, keys: (keyof T)[]) {\n const obj: Partial<Record<keyof T, true>> = {};\n for (let key of keys) {\n obj[key] = true;\n }\n return this.schema\n .pick(obj as unknown as Parameters<z.ZodObject<T>["pick"]>[0])\n .parse(value);\n }\n\n omit(value: unknown, keys: (keyof T)[]) {\n const obj: Partial<Record<keyof T, true>> = {};\n for (let key of keys) {\n obj[key] = true;\n }\n return this.schema\n .omit(obj as unknown as Parameters<z.ZodObject<T>["omit"]>[0])\n .parse(value);\n }\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"custom-validation",children:"Custom validation"}),"\n",(0,r.jsxs)(n.p,{children:["You can add custom validation functions with the universal ",(0,r.jsx)(n.code,{children:"z.refine()"})," modifier, which takes in a callback with the value as a parameter and must return a boolean: ",(0,r.jsx)(n.code,{children:"true"})," if passing, ",(0,r.jsx)(n.code,{children:"false"})," if failing."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const userSchema2 = z.object({\n name: z.string(),\n email: z.string().refine(value => {\n return value.endsWith("[email protected],")\n }),\n});\n'})}),"\n",(0,r.jsx)(n.h4,{id:"adding-custom-messages",children:"Adding custom messages"}),"\n",(0,r.jsx)(n.p,{children:"You can add custom messages for when validation fails at certain stages, which is possible at each modifier as an optional argument."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const fancySchema = z.number().int().min(1, {\n message: 'Number must be a positive integer. This includes you, 0.',\n});\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"creating-recursive-schemas-with-zlazy",children:["Creating recursive schemas with ",(0,r.jsx)(n.code,{children:"z.lazy()"})]}),"\n",(0,r.jsxs)(n.p,{children:["You can create recursive schemas that reference themselves by using ",(0,r.jsx)(n.code,{children:"z.lazy()"})," and returning a self-referential schema in the callback:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const serializableSchema = z.lazy(() => {\n return z.record(\n z.string(),\n z.union([z.string(), z.number(), z.boolean(), z.null(), z.undefined(), serializableSchema])\n );\n});\n\nconst parent = z.lazy(() => {\n return z.object({\n name: z.string(),\n children: z.array(parent),\n });\n});\n"})}),"\n",(0,r.jsx)(n.h3,{id:"typescript-types-to-zod-schemas",children:"TypeScript types to zod schemas"}),"\n",(0,r.jsx)(n.p,{children:"If you want to use a typescript type or interface as a general shape for a zod schema to adhere to, then you can use these approaches:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.strong,{children:["approach 1 : use ",(0,r.jsx)(n.code,{children:"satisfies"})]})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["If you are using TypeScript 4.9+, the\xa0",(0,r.jsx)(n.code,{children:"satisfies"}),"\xa0keyword allows you to check that your schema matches your interface"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'import { z } from "zod";\n\ninterface User {\n id: number;\n name: string;\n email?: string;\n}\n\nconst UserSchema = z.object({\n id: z.number(),\n name: z.string(),\n email: z.string().optional(),\n}) satisfies z.ZodType<User>; // Ensures UserSchema produces a valid User type\n\n'})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsxs)(n.strong,{children:["approach 2: use ",(0,r.jsx)(n.code,{children:"z.ZodType<T>"})]}),":"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["You can explicitly type your schema variable as\xa0",(0,r.jsx)(n.code,{children:"z.ZodType<InterfaceName>"}),". This will trigger a TypeScript error if the schema and the interface ever go out of sync."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'import { z } from "zod";\n\ninterface Product {\n price: number;\n title: string;\n}\n\n// Any missing or mismatched fields here will cause a compilation error\nconst ProductSchema: z.ZodType<Product> = z.object({\n price: z.number(),\n title: z.string(),\n});\n\n'})}),"\n",(0,r.jsx)(n.h3,{id:"zod-use-cases",children:"Zod use cases"}),"\n",(0,r.jsx)(n.h4,{id:"zod-with-basic-form-validation",children:"Zod with basic form validation"}),"\n",(0,r.jsxs)(n.p,{children:["here is an exampel of using zod and zod errors to validate the ",(0,r.jsx)(n.code,{children:"FormData"})," object when a form is submitted and aggregate and display errors:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:"import React, { useState } from 'react';\nimport { z } from 'zod';\n\nconst contactFormSchema = z.object({\n name: z.string().min(2),\n email: z.string().email(),\n message: z.string().min(10),\n});\ntype ContactFormData = z.infer<typeof contactFormSchema>;\n\nfunction ContactForm() {\n const [formData, setFormData] = useState<ContactFormData>({\n name: '',\n email: '',\n message: '',\n });\n const [errors, setErrors] = useState<z.ZodError<ContactFormData> | null>(\n null,\n );\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n const validationResult = contactFormSchema.safeParse(formData);
1 // Validate form data\n\n if (validationResult.success) {\n console.log('Form data is valid:', validationResult.data);\n setErrors(null); // Clear errors\n // ... (Submit form data) ...\n } else {\n console.error('Form validation errors:', validationResult.error.errors);\n setErrors(validationResult.error); // Set errors to display to user\n }\n };\n\n const handleChange = (\n e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,\n ) => {\n setFormData({ ...formData, [e.target.name]: e.target.value });\n };\n\n return (\n <form onSubmit={handleSubmit}>\n <div>\n <label htmlFor=\"name\">Name:</label>\n <input\n type=\"text\"\n id=\"name\"\n name=\"name\"\n value={formData.name}\n onChange={handleChange}\n />\n {errors?.formErrors\n .filter((err) => err.path[0] === 'name')\n .map((err) => (\n <p className=\"error\">{err.message}</p>\n ))}\n </div>\n {/* ... (Email and Message fields and error display similar to Name) ... */}\n <button type=\"submit\">Submit</button>\n </form>\n );\n}\n"})}),"\n",(0,r.jsx)(n.h4,{id:"zod-with-react-hook-form",children:"Zod with React Hook Form"}),"\n",(0,r.jsx)(n.p,{children:"This is an example of providing a zod object schema to react hook form so you can get strong typing, runtime validation, and meaningful errors:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-tsx",children:'import { useForm } from \'react-hook-form\';\nimport { zodResolver } from \'@hookform/resolvers/zod\';\n\n// 1. create a schema\nconst FormSchema = z.object({\n username: z.string().min(3),\n password: z.string().min(8)\n});\ntype FormData = z.infer<typeof FormSchema>;\n\nfunction MyFormComponent() {\n // 2. create the hook, passing in zod resolver\n const { register, handleSubmit, formState: { errors } } = useForm<FormData>({\n resolver: zodResolver(FormSchema)\n });\n\n // 3. guaranteed that all data that reaches onSubmit will be valid\n const onSubmit = (data: FormData) => {\n console.log("Valid form data:", data);\n };\n\n return (\n <form onSubmit={handleSubmit(onSubmit)}>\n <input {\u2026register("username")} placeholder="Username" />\n {errors.username && <span>{errors.username.message}</span>}\n\n <input {\u2026register("password")} type="password" placeholder="Password" />\n {errors.password && <span>{errors.password.message}</span>}\n\n <button type="submit">Sign Up</button>\n </form>\n );\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"some-bullshit",children:"Some bullshit"}),"\n",(0,r.jsx)(n.p,{children:"Like wtf is this AI just be cooking lowkey"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"/**\n * This is a file for abstractions over zod validations and parsing zod errors,\n * can be added to any package, so it is best to put this in its own \"utils\" package in the future\n */\n\nimport { AnyZodObject, z, ZodError, ZodIssue } from 'zod'\n\ninterface ParsedZodIssue {\n path: string\n message: string\n code: string\n}\n\ninterface ParsedZodError {\n errors: ParsedZodIssue[]\n}\n\nfunction parseZodError(error: ZodError): ParsedZodError {\n return {\n errors: error.errors.map((issue: ZodIssue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n code: issue.code,\n })),\n }\n}\n\nexport class ZodValidation<T extends AnyZodObject> {\n constructor(public schema: T) {}\n\n createObjectWithAutocomplete(obj: z.infer<T>) {\n return obj\n }\n\n isOfType(value: unknown): value is z.infer<T> {\n return this.schema.safeParse(value).success\n }\n\n validateSchema(value: unknown) {\n return this.schema.parse(value)\n }\n\n validateSchemaWithAutcomplete(value: z.infer<T>) {\n return this.schema.parse(value) as z.infer<T>\n }\n\n pick(value: unknown, keys: (keyof z.infer<T>)[]) {\n const obj: Partial<Record<keyof z.infer<T>, true>> = {}\n for (const key of keys) {\n obj[key] = true\n }\n return this.schema\n .pick(obj as unknown as Parameters<T['pick']>[0])\n .parse(value)\n }\n\n omit(value: unknown, keys: (keyof z.infer<T>
1)[]) {\n const obj: Partial<Record<keyof z.infer<T>, true>> = {}\n for (const key of keys) {\n obj[key] = true\n }\n return this.schema\n .omit(obj as unknown as Parameters<T['omit']>[0])\n .parse(value)\n }\n\n static isZodError(error: unknown) {\n const isZodError =\n error instanceof ZodError ||\n (error instanceof Error && error.message.includes('ZodError'))\n return isZodError\n }\n\n static getZodErrorInfo(error: unknown) {\n const isZodError = this.isZodError(error)\n if (isZodError) {\n return parseZodError(error as ZodError)\n }\n if (error instanceof Error) {\n return {\n message: error.message,\n }\n }\n return null\n }\n}\n\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"import {\n OpportunitySchema,\n integrationJobLockSchema,\n integrationJobSchema,\n vendorCommsJobDetailSchema,\n} from '@bidscale/select-entity'\nimport z from 'zod'\nimport { ZodValidation } from './ZodValidation'\n\nexport const integrationJobValidators = {\n integrationJobErrorValidator: new ZodValidation(\n integrationJobSchema.IntegrationJobError\n ),\n opportunityDetailValidator: new ZodValidation(\n vendorCommsJobDetailSchema.PublishOpportunityDetail\n ),\n}\n\ntype ParsedType<M, K extends keyof M> = M[K] extends ZodValidation<infer Schema>\n ? z.infer<Schema>\n : never\n\nexport function createQuickParser<M extends Record<string, ZodValidation<any>>>(\n validators: M\n) {\n return function quickParse<K extends keyof M>(key: K, obj: ParsedType<M, K>) {\n return validators[key].validateSchemaWithAutcomplete(obj)\n }\n}\n\nexport const ijParse = createQuickParser(integrationJobValidators)\n\nexport function parseOpportunity(opportunity: OpportunitySchema.Opportunity) {\n return OpportunitySchema.OpportunitySchema.parse(opportunity)\n}\n\nexport function parseIntegrationJob(\n integrationJob: integrationJobSchema.IntegrationJob\n) {\n return integrationJobSchema.IntegrationJobSchema.parse(integrationJob)\n}\n\nexport function parseIntegrationJobLock(\n integrationJobLock: integrationJobLockSchema.IntegrationJobLock\n) {\n return integrationJobLockSchema.IntegrationJobLockSchema.parse(\n integrationJobLock\n )\n}\n\n"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>o});var r=s(6540);const a={},t=r.createContext(a);function i(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.