Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to transform object to array before parsing in Zod

I do have an external URL endpoint that returns an array of field object when it is more than 2 and an object when there is only one, see the snippet below:

Return when the field count is one:

{
  "fields": { "fullName": "fieldFullname", "type": "fieldType" }
}

Return when the field is more than one:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
  "fields": [
      { "fullName": "fieldFullname", "type": "fieldType" },
      { "fullName": "fieldFullname", "type": "fieldType" }
   ]
}

Currently, this is my schema using zod:

export const sObjectMetadataSchema = z.object({
  fields: z.array(metadataFieldSchema).optional()
});

export const metadataFieldSchema = z.object({
  fullName: z.string().optional(),
  type: z.string().optional(),
});

It is configured that it will only accept an array of objects. When it returns only one field it throws an error:

{
  "code": "invalid_type",
  "expected": "array",
  "received": "object",
  "path": [],
  "message": "Expected array, received object"
}

My goal is if it returns a single object it will convert it to an array of objects during runtime. Currently trying to implement using transform but still not working:

An initial implementation using transform:

export const sObjectMetadataSchema = z.object({
fields: z.unknown().transform((rel) => {
    return Array.isArray(rel)
        ? z.array(metadataFieldSchema).optional()
        : 'Convert the rel to Array?';
    }),
});

>Solution :

I didn’t test that, but seems like should work:

const FieldsSchema = z.object({
  fullName: z.string(),
  type: z.string()
});

export const sObjectMetadataSchema = z.object({
fields: z.union([FieldsSchema, FieldsSchema.array()]).transform((rel) => {
    return Array.isArray(rel)
        ? rel
        : [rel];
    }),
});
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading