Naar de inhoud

JSON Schema naar Zod Schema Transformer — Numio

Genereert Zod-validatiecode op basis van een JSON-schema met json-schema-to-zod. Beperkingen zoals minLength, minimum, patroon en standaard worden geketende Zod-methoden, en eigenschappen die niet in "vereist" staan, krijgen .optioneel().

U ontvangt een JSON-schema van een ander team en wilt runtime-validatie in een TypeScript-service zonder een JSON-schemavalidator.

JSON Schema

Zod Schema

Wanneer gebruik je dit?

  • U ontvangt een JSON-schema van een ander team en wilt runtime-validatie in een TypeScript-service zonder een JSON-schemavalidator.
  • U verplaatst de formuliervalidatie van een JSON Schema-validator zoals Ajv naar Zod en wilt dat de gegenereerde code begint.

Hoe werkt het

  1. Plak een JSON-schema in het paneel JSON Schema.
  2. Open eventueel de instellingen en wijzig de rootschemanaam (standaard "schema"); het wordt de naam van de geëxporteerde const.
  3. Kopieer de gegenereerde code, die z uit "zod" importeert, naar uw project. De conversie wordt uitgevoerd in de browser.

JSON-schema

{
  "type": "object",
  "properties": {
    "username": { "type": "string", "minLength": 3, "maxLength": 20 },
    "age": { "type": "integer", "minimum": 18 },
    "contact": {
      "oneOf": [
        { "type": "string", "format": "email" },
        { "type": "string", "pattern": "^\\+[0-9]+$" }
      ]
    },
    "newsletter": { "type": "boolean", "default": false }
  },
  "required": ["username", "contact"]
}

Zod-schema

import { z } from "zod"

export const schema = z.object({
  username: z.string().min(3).max(20),
  age: z.number().int().gte(18).optional(),
  contact: z.any().superRefine((x, ctx) => {
    const schemas = [
      z.string().email(),
      z.string().regex(new RegExp("^\\+[0-9]+$")),
    ]
    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",
      })
…

Details en beperkingen

oneOf wordt geconverteerd naar z.any().superRefine(...), waarmee wordt gecontroleerd of er precies één subschema wordt doorgegeven, zoals het voorbeeld laat zien.

$ref is niet opgelost: een eigenschap waarnaar wordt verwezen, wordt z.any().

geheel getal voegt .int() toe, het formaat "email" voegt .email() toe en het formaat "date-time" voegt .datetime() toe.

additionalProperties: false wordt .catchall(z.never()) in plaats van .strict().

FAQ

Hoe worden nulbare typen afgehandeld?

"type": ["string", "null"] wordt z.union([z.string(), z.null()]), met .optioneel() toegevoegd als de eigenschap niet vereist is.

Kan ik de naam van het geëxporteerde schema wijzigen?

Ja. Stel de rootschemanaam in de instellingen in; de uitvoer leest vervolgens export const <name> = ... in plaats van export const schema.

Worden definities en $ref ondersteund?

Nee. Een eigenschap die $ref gebruikt, wordt z.any(), dus inline het schema waarnaar wordt verwezen voordat het wordt geconverteerd.

Specificaties en referenties