Giter Site home page Giter Site logo

zodex's Introduction

Zodex

Type-safe (de)serialization library for zod. It both serializes and simplifies types into a JSON format, in the following ways:

  • optional, nullable and default types are inlined into any given types itself
{ "type": "string", "defaultValue": "hi" }
  • number checks are also inlined into the type itself
{ "type": "number", "min": 23, "max": 42 }

Installation

pnpm add zodex
# or
yarn add zodex
# or
npm install zodex

Usage

import { z } from "zod";
import { zerialize } from "zodex";

const someZodType = z.discriminatedUnion("id", [
  z.object({ id: z.literal("a"), count: z.number().optional() }),
  z.object({ id: z.literal("b") }),
]);
const shape = zerialize(someZodType);

Now typeof shape will be

type Shape = {
  type: "discriminatedUnion";
  discriminator: "id";
  options: [
    {
      type: "object";
      properties: {
        id: { type: "literal"; value: "a" };
        count: { type: "number"; isOptional: true };
      };
    },
    { type: "object"; properties: { id: { type: "literal"; value: "b" } } }
  ];
};

which is exactly equal to its runtime value (shown in YAML for brevity, you probably shouldn't use YAML):

type: "discriminatedUnion"
discriminator: "id"
options:
  - type: "object"
    properties:
      id:
        type: "literal"
        value: "a"
      count:
        type: "number"
        isOptional: true
  - type: "object"
    properties:
      id:
        type: "literal"
        value: "b"

Options

Both zerialize and dezerialize accept an options object with the same properties.

Since Zod does not allow the specification of the names of effects (refinements, transforms, and preprocesses), we allow you to supply as options maps of names to effects so that these can be part of serialization and deserialization. If none of these options are supplied, the effects will be omitted.

Properties:

  • superRefinements - Map of name to .superRefine() functions
  • transforms - Map of name to .transform() functions
  • preprocesses - Map of name to z.preprocess() functions

Use of JSON References

JSON references are used to represent local references. If you wish to use JSON references for remote (non-cyclic) references, you may do so, but you will need to use a library like json-refs (with resolveRefs) to first resolve such references and then supply the object to dezerialize.

Zodex will serialize local references, including handling recursive ones. As with JSON Schema, the $defs property may be a reasonable top-level property to use as storage for local references, but it receives no special treatment by this library (any property could be targeted by one's references).

Note that if you wish to use additional properties with an item containing a reference, e.g., isOptional, you will first need to wrap the JSON reference within a single-item union such as in the following:

{
  "type": "union",
  "options": [
    {
      "$ref": "#/properties/id"
    }
  ]
}

Note that due to technical limitations with Zod, we are unable to allow a JSON reference in place of an object properties object. You can either resolve this first with another library (if it is a non-cyclic reference), or target the whole object or individual properties.

Roadmap

  • custom error messages are not included

Caveats

  • brand is not supportable and omitted
  • lazy and pipeline types are unwrapped
  • catch with a function can have its then-value serialized but it cannot then be deserialized back into using the original function
  • Due to technical limitations, we cannot support the regular refine(), custom() and instanceof methods (and they will be ignored), but these are really just implementations of superRefine() which is supported

zodex's People

Contributors

brettz9 avatar christophwitzko avatar gregoor avatar miunau avatar

Stargazers

smari avatar Spas Z. Spasov avatar Mike Rudge avatar Cahil Foley avatar Tom Manning avatar  avatar Raff Paquin avatar --- avatar  avatar  avatar Vaibhav Chopra avatar Zhang Yang avatar Budi Adiono avatar Brian Anglin avatar Drew Harris avatar Emiel van de Laar avatar Sam F avatar ethan avatar Kristjan avatar Fabio Franzini avatar Steven Salka avatar Ondřej Kocián avatar Simon Thiboutôt avatar Yogish Shenoy avatar Gabriel Almeida avatar Mantas Sidabras avatar Rob Gordon avatar Chad avatar  avatar Severin Ibarluzea avatar Douglas James avatar Dapeng Gong avatar Gilson Nunes Filho avatar Heiki avatar Charles avatar  avatar  avatar Eric Simon avatar  avatar

Watchers

 avatar  avatar

zodex's Issues

Switch to JSON

It appears to me that the Zodex format is JSON-compatible with the exception of the current use of a few BigInt's (min, max, and multipleOf on the "bigint" type).

In order to make the format serializable for the network out of the box, perhaps this small deviation from JSON could be changed, using strings to represent the BigInt values?

Handle recursive schemas

Although Zod doesn't support circular data, it does support recursive schemas, so it would be nice to support these. However, to implement this and track the current path to ensure we don't recurse, I think we'd either need to pass on a state object for each zerializer method (and potentially as part of the public function API) or if you didn't prefer that route, changing to a class which can track state internal to itself. Either one of those or I guess we could add each object to a global WeakMap to verify it hasn't been traversed. Thought I'd confirm what approach might be desired before attempting a PR.

Listing deviations from JSON Schema

Hi,

Great to see this project!

I might just suggest a section to indicate any deviations from JSON Schema (including the type values), as it looks like you're already thankfully leveraging familiarity with JSON Schema for the syntax.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.