StefanTerdell / zod-to-json-schema

Converts Zod schemas to Json schemas
ISC License
886 stars 71 forks source link

Add best-effort support for RegExp flags in `z.string().regex()` validations #122

Closed Spappz closed 4 months ago

Spappz commented 5 months ago

Summary

Reworked the string parser to attempt to mutate provided regexes into a flag-independent form. When the applyRegexFlags option is falsy, nothing actually changes; the regex.source that was previously fed into addPattern's arguments now just happens within addPattern itself.

The following flags are supported:

I introduced a new option applyRegexFlags because, on inspection, it's not mutually exclusive to patternStrategy: the former applies for z.string().regex(), but latter applies only for .includes(), .startsWith(), and .endsWith(). I've reworded the description for patternStrategy to highlight this a little more clearly—I honestly didn't properly understand it until I took a look at the code!

To make the code cleaner, I also changed zodPatterns to be the full regexes from Zod (made case-insensitive). I also updated a couple that were out-of-date relative to Zod itself 😅

Example

import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
const zodSchema = z.string().regex(/foo .\* (ba[r-z_])+$/ims).startsWith("@foo").min(5);
const jsonSchema = zodToJsonSchema(zodSchema, { applyRegexFlags: true });
console.log(JSON.stringify(jsonSchema, null, "   "));
{
   "type": "string",
   "allOf": [
      {
         "pattern": "[fF][oO][oO] [.\r\n]\\* ([bB][aA][r-zR-Z_])+($|(?=[\r\n]))"
      },
      {
         "pattern": "^\\@foo"
      }
   ],
   "minLength": 5,
   "$schema": "http://json-schema.org/draft-07/schema#"
}

Caveats


Sorry for the delay; life suddenly got a little busy!

Resolves #116

StefanTerdell commented 4 months ago

Don't have time for a thorough review right now, but this PR just makes me all warm and fuzzy. Issue->Discussion->PR with a great description, tests included, and readme updated. Bravo!

StefanTerdell commented 4 months ago

Sorry the wait! Great work.

Spappz commented 4 months ago

Thank you! Glad to have helped.

Though, as a nit, I think you mistook me for another guy with an open PR in 23195b3 and 9275d61 😅

StefanTerdell commented 4 months ago

@Spappz I'm an idiot. Fixed though :) https://github.com/StefanTerdell/zod-to-json-schema/commit/3e7c648e626a73517bccb846869d15ef66531a00