1.2.0 • Published 1 year ago

zoxy v1.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Installation

pnpm add zod zoxy

Basic usage (live demo)

import { z } from 'zod';
import { zoxy } from 'zoxy';

const User = z.object({
  username: z.string().min(4),
  email: z.string().email().optional(),
  phone: z.object({
    home: z.string().min(10).max(42).optional(),
    work: z.string().min(10).max(42).optional(),
  }),
  foo: z.object({ bar: z.object({ baz: z.string().max(3).optional() }).optional() }).optional(),
});

const user = zoxy(User, { username: 'anonymous', phone: {} });

// Pass
user.username = 'nyan';
user.email = undefined;
user.phone.home = '555 042 42 42';
user.phone = { home: '555 042 42 42', work: '555 024 24 24' };

// Fail
user.email = 'xxx'; // throw 'Invalid email'
user.phone = { home: 'xxx' }; // throw 'String must contain at least 10 character(s)'

Ensure default value

In the example below the schema has three levels which are all optional and if you want to define the last level it can be quite verbose. Zoxy offers a solution to this with a little helper that makes sure that a default value is set. Simply prefix the desired value with a '$' sign and you get a method that allows you to set a default value.

const Data = z.object({
  foo: z
    .object({
      bar: z
        .object({
          baz: z.string().max(3).optional(),
        })
        .optional(),
    })
    .optional(),
});

const data = zoxy(Data, {});

// Get `data.foo.bar.baz` if defined or set default value where needed.
const baz = data.$foo({}).$bar({}).$baz('baz'); // 'baz'

The above line will perform the following actions:

  • if data.foo is undefined set it to {}
  • if data.foo.bar is undefined set it to {}
  • if data.foo.bar.baz is undefined set it to 'baz'
  • return data.foo.bar.baz

Note that the returned value can be something different from the default value if it has already been initialized previously.

Set deep optional property

If you want to assign a new value deeply you must use the following syntax.

// Set default value on `foo.bar` where needed and set `foo.bar.baz` to 'buzz'.
data.$foo({}).$bar({}).baz = 'buzz';

console.log(data.foo?.bar?.baz); // 'buzz'

Signature

function zoxy(schema: ZodObject, data: Data, options?: ZoxyOptions): Zoxy;

Options

type ZoxyOptions = {
  prefix: string; // default '$'
};

Scaffolded with @skarab/skaffold