Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Zod able to parse content of JSON files?

Tags:

zod

This might be a duplicate of Zod: Parse external JSON file


I have a function that expects a JSON string and parses it to a given type, inferred by a Zod schema

const createConfigurationFromJson = (content: string): Configuration => {
  const rawConfiguration = JSON.parse(content);

  return configurationSchema.parse(rawConfiguration);
};

This function might throw if the JSON content is invalid JSON or Zod throws a parse error. Without using another third party library, is it possible to let Zod parse the JSON string? So I can be sure there can only be a Zod error?

like image 649
baitendbidz Avatar asked Sep 18 '25 20:09

baitendbidz


1 Answers

If you want it completely in zod, before you can send that to the configurationSchema, you need to transform the string content to an object, and add an issue if and only if parsing the JSON fails. Then you can use .pipe to pass that to configurationSchema.

const configurationSchema = z.object({
  name: z.string(),
  version: z.string(),
  description: z.string(),
});

type Configuration = z.infer<typeof configurationSchema>;

const createConfigurationFromJson = (content: string): Configuration => {
  return z
    .string()
    .transform((_, ctx) => {
      try {
        return JSON.parse(content);
      } catch (error) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: 'invalid json',
        });
        return z.never;
      }
    })
    .pipe(configurationSchema)
    .parse(content);
};

When tested with

const configuration1 = createConfigurationFromJson(`{
  "name": "my-app",
  "version": "1.0.0",
  "description": "My awesome app"
}`);

const configuration2 = createConfigurationFromJson(`{
  "banana": "🍌"
}`);

const configuration3 = createConfigurationFromJson(`{
  fiadsjfoiajsdoivjdaoij
`);

it outputs the success and errors as

configuration1 {
  name: "my-app",
  version: "1.0.0",
  description: "My awesome app"
}
configuration2 159 |     const json = JSON.stringify(obj, null, 2);
160 |     return json.replace(/"([^"]+)":/g, "$1:");
161 | };
162 | class ZodError extends Error {
163 |     constructor(issues) {
164 |         super();
            ^
ZodError: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "name"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "version"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "description"
    ],
    "message": "Required"
  }
]
 errors: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "name"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "version"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "description"
    ],
    "message": "Required"
  }
]

      at new ZodError (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:164:8)
      at /Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:537:30
      at parse (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:636:14)
      at /Users/sgunter/code/zod-parse-json/index.ts:46:25

configuration3 159 |     const json = JSON.stringify(obj, null, 2);
160 |     return json.replace(/"([^"]+)":/g, "$1:");
161 | };
162 | class ZodError extends Error {
163 |     constructor(issues) {
164 |         super();
            ^
ZodError: [
  {
    "code": "custom",
    "message": "invalid json",
    "fatal": true,
    "path": []
  }
]
 errors: [
  {
    "code": "custom",
    "message": "invalid json",
    "fatal": true,
    "path": []
  }
]

      at new ZodError (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:164:8)
      at /Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:537:30
      at parse (/Users/sgunter/code/zod-parse-json/node_modules/zod/lib/index.mjs:636:14)
      at /Users/sgunter/code/zod-parse-json/index.ts:55:25
like image 116
Samathingamajig Avatar answered Sep 23 '25 07:09

Samathingamajig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!