StefanTerdell / json-schema-to-zod

ISC License
334 stars 48 forks source link

Getting unexpected zod schema as output #56

Closed sukeshpabolu closed 1 year ago

sukeshpabolu commented 1 year ago

For the below JSON schema. I am getting unexpected zod schema as output.

{ "required": [ "entityIdentification" ], "properties": { "entityIdentification": { "maxLength": 80, "minLength": 1, "type": "string" }, "contentOwner": { "required": [ "gln" ], "properties": { "gln": { "pattern": "\\d{13}", "type": "string" }, "additionalPartyIdentification": { "oneOf": [ { "type": "object", "allOf": [ { "maxLength": 80, "minLength": 1, "type": "string" }, { "required": [ "content", "@additionalPartyIdentificationTypeCode", "@codeListVersion" ], "properties": { "content": { "type": "string" }, "@additionalPartyIdentificationTypeCode": { "enum": [ "BUYER_ASSIGNED_IDENTIFIER_FOR_A_PARTY", "CASHSSP", "CNPJ", "COMPANY_CAD", "DEA_DRUG_ENFORCEMENT_AGENCY", "DUNS", "DUNS_PLUS_FOUR", "EU_VAT_IDENTIFICATION_NUMBER", "FOR_INTERNAL_USE_1", "FOR_INTERNAL_USE_10", "FOR_INTERNAL_USE_11", "FOR_INTERNAL_USE_12", "FOR_INTERNAL_USE_13", "FOR_INTERNAL_USE_14", "FOR_INTERNAL_USE_15", "FOR_INTERNAL_USE_16", "FOR_INTERNAL_USE_17", "FOR_INTERNAL_USE_18", "FOR_INTERNAL_USE_19", "FOR_INTERNAL_USE_2", "FOR_INTERNAL_USE_20", "FOR_INTERNAL_USE_3", "FOR_INTERNAL_USE_4", "FOR_INTERNAL_USE_5", "FOR_INTERNAL_USE_6", "FOR_INTERNAL_USE_7", "FOR_INTERNAL_USE_8", "FOR_INTERNAL_USE_9", "HIN_CANADIAN_HEALTHCARE_IDENTIFICATION_NUMBER", "PARTITA_IVA", "SCAC", "SELLER_ASSIGNED_IDENTIFIER_FOR_A_PARTY", "SIRET", "SRN", "TD_LINK_TRADE_DIMENSIONS", "UCC_COMMUNICATION_IDENTIFICATION", "UN_LOCATION_CODE", "UNKNOWN", "USDA_ESTABLISHMENT_NUMBER" ], "type": "string" }, "@codeListVersion": { "maxLength": 35, "minLength": 1, "type": "string" } } } ] }, { "items": { "type": "object", "allOf": [ { "maxLength": 80, "minLength": 1, "type": "string" }, { "required": [ "content", "@additionalPartyIdentificationTypeCode", "@codeListVersion" ], "properties": { "content": { "type": "string" }, "@additionalPartyIdentificationTypeCode": { "enum": [ "BUYER_ASSIGNED_IDENTIFIER_FOR_A_PARTY", "CASHSSP", "CNPJ", "COMPANY_CAD", "DEA_DRUG_ENFORCEMENT_AGENCY", "DUNS", "DUNS_PLUS_FOUR", "EU_VAT_IDENTIFICATION_NUMBER", "FOR_INTERNAL_USE_1", "FOR_INTERNAL_USE_10", "FOR_INTERNAL_USE_11", "FOR_INTERNAL_USE_12", "FOR_INTERNAL_USE_13", "FOR_INTERNAL_USE_14", "FOR_INTERNAL_USE_15", "FOR_INTERNAL_USE_16", "FOR_INTERNAL_USE_17", "FOR_INTERNAL_USE_18", "FOR_INTERNAL_USE_19", "FOR_INTERNAL_USE_2", "FOR_INTERNAL_USE_20", "FOR_INTERNAL_USE_3", "FOR_INTERNAL_USE_4", "FOR_INTERNAL_USE_5", "FOR_INTERNAL_USE_6", "FOR_INTERNAL_USE_7", "FOR_INTERNAL_USE_8", "FOR_INTERNAL_USE_9", "HIN_CANADIAN_HEALTHCARE_IDENTIFICATION_NUMBER", "PARTITA_IVA", "SCAC", "SELLER_ASSIGNED_IDENTIFIER_FOR_A_PARTY", "SIRET", "SRN", "TD_LINK_TRADE_DIMENSIONS", "UCC_COMMUNICATION_IDENTIFICATION", "UN_LOCATION_CODE", "UNKNOWN", "USDA_ESTABLISHMENT_NUMBER" ], "type": "string" }, "@codeListVersion": { "maxLength": 35, "minLength": 1, "type": "string" } } } ] }, "type": "array" } ] } }, "type": "object" } }, "type": "object" }

`import { z } from "zod";

export default z.object({ entityIdentification: z.string().min(1).max(80), contentOwner: z .object({ gln: z.string().regex(new RegExp("\d{13}")), additionalPartyIdentification: z .any() .superRefine((x, ctx) => { const schemas = [z.record(z.any()), z.array(z.record(z.any()))]; const errors = schemas.reduce( (errors: z.ZodError[], schema) => ((result) => "error" in result ? [...errors, result.error] : errors)( schema.safeParse(x) ), [] ); if (schemas.length - errors.length !== 1) { ctx.addIssue({ path: ctx.path, code: "invalid_union", unionErrors: errors, message: "Invalid input: Should pass single schema", }); } }) .optional(), }) .optional(), });`

Please help me with this.

StefanTerdell commented 1 year ago

properties/contentOwner/properties/additionalPartyIdentification/oneOf/allOf is broken. It requires the item to be both a string and an object. You should avoid using allOf.

Another issue has to do with this package: when combining xxxOf schemas, it still needs the type flag in all of the members, meaning { "type": "object", "allOf": [ { "properties": { ... } } ] } won't work.

I'm working on a new version that should address this though.