Migrate to v0.31.0

JavaScript pattern

You can use Grit to automatically update your code to the new API. See the migration guide for more details on the changes.


Apply with the Grit CLI
grit apply github.com/fabian-hiller/valibot#migrate_to_v0_31_0

Should transform simple pipe

Before:

BEFORE
const Schema1 = v.string([v.email('Email required')]);
const Schema2 = v.string([v.email(), v.endsWith('@example.com')]);
const Schema3 = v.string([v.email(), v.endsWith('@example.com'), v.maxLength(30)]);

After:

AFTER
const Schema1 = v.pipe(v.string(), v.email('Email required'));
const Schema2 = v.pipe(v.string(), v.email(), v.endsWith('@example.com'));
const Schema3 = v.pipe(v.string(), v.email(), v.endsWith('@example.com'), v.maxLength(30));

Should transform nested pipe

Before:

BEFORE
const Schema1 = v.map(
  v.number(),
  v.string([v.url(), v.endsWith('@example.com')]),
  [v.maxSize(10)]
);

const Schema2 = v.object(
  {
    list: v.array(
      v.string([v.minLength(3)]),
      [v.minLength(3), v.includes('foo')]
    ),
    length: v.number([v.integer()]),
  },
  [v.custom((input) => input.list.length === input.length)],
);

After:

AFTER
const Schema1 = v.pipe(v.map(v.number(),v.pipe(v.string(), v.url(), v.endsWith('@example.com'))), v.maxSize(10));

const Schema2 = v.pipe(v.object({
    list: v.pipe(v.array(v.pipe(v.string(), v.minLength(3))), v.minLength(3), v.includes('foo')),
    length: v.pipe(v.number(), v.integer()),
  }), v.check((input) => input.list.length === input.length));

Should not transform non pipe

Before:

BEFORE
const Schema = v.object({
  normal: v.string([v.email(() => 'Email required')]),
  union: v.union([v.string([v.decimal()]), v.number()], [v.minValue(10)]),
  intersection: v.intersect([v.object({ a: v.string() }), v.object({ b: v.number() })]),
  variant: v.variant('type', [v.object({ type: v.literal('a') }), v.object({ type: v.literal('b') })]),
  picklist: v.picklist(['a', 'b']),
  tuple: v.tuple([v.string(), v.number()]),
});

After:

AFTER
const Schema = v.object({
  normal: v.pipe(v.string(), v.email(() => 'Email required')),
  union: v.pipe(v.union([v.pipe(v.string(), v.decimal()), v.number()]), v.minValue(10)),
  intersection: v.intersect([v.object({ a: v.string() }), v.object({ b: v.number() })]),
  variant: v.variant('type', [v.object({ type: v.literal('a') }), v.object({ type: v.literal('b') })]),
  picklist: v.picklist(['a', 'b']),
  tuple: v.tuple([v.string(), v.number()]),
});

Should transform coerce method

Before:

BEFORE
const Schema = v.coerce(v.date(), (input) => new Date(input));

After:

AFTER
const Schema = v.pipe(v.unknown(), v.transform((input) => new Date(input)));

Should transform flatten argument

Before:

BEFORE
const flatErrors1 = v.flatten(error);

// This should be unchanged
const flatErrors2 = v.flatten([issue]);
const flatErrors3 = v.flatten(result.issues);

After:

AFTER
const flatErrors1 = v.flatten(error.issues);

// This should be unchanged
const flatErrors2 = v.flatten([issue]);
const flatErrors3 = v.flatten(result.issues);

Should transform any Valibot wildcard

Before:

BEFORE
import * as foo from 'valibot';
import * as notFoo from 'zod';

const Schema1 = foo.string([foo.email()]);
const Schema2 = notFoo.string([notFoo.email()]);

After:

AFTER
import * as foo from 'valibot';
import * as notFoo from 'zod';

const Schema1 = foo.pipe(foo.string(), foo.email());
const Schema2 = notFoo.string([notFoo.email()]);

Should transform direct Valibot imports

Before:

BEFORE
import { email, string } from 'valibot';

const Schema = string([email()]);

After:

AFTER
import { email, string, pipe } from 'valibot';

const Schema = pipe(string(), email());

Should transform brand and transform method

Before:

BEFORE
const Schema1 = v.brand(v.string([v.url()]), 'foo');
const Schema2 = v.transform(v.string(), (input) => input.length);
const Schema3 = v.transform(v.brand(v.string(), 'Name'), (input) => input.length);
const Schema4 = v.brand(v.brand(v.string(), 'Name1'), 'Name2');
const Schema5 = v.transform(v.coerce(v.date(), (input) => new Date(input)), (input) => input.toJSON());

After:

AFTER
const Schema1 = v.pipe(v.string(), v.url(), v.brand('foo'));
const Schema2 = v.pipe(v.string(), v.transform((input) => input.length));
const Schema3 = v.pipe(v.string(), v.brand('Name'), v.transform((input) => input.length));
const Schema4 = v.pipe(v.string(), v.brand('Name1'), v.brand('Name2'));
const Schema5 = v.pipe(v.pipe(v.unknown(), v.transform((input) => new Date(input))), v.transform((input) => input.toJSON()));

Should transform unnecessary pipes

Before:

BEFORE
const Schema1 = v.pipe(v.pipe(v.pipe(v.string()), v.email()), v.maxLength(10));
const Schema2 = v.transform(v.coerce(v.date(), (input) => new Date(input)), (input) => input.toJSON());

After:

AFTER
const Schema1 = v.pipe(v.string(), v.email(), v.maxLength(10));
const Schema2 = v.pipe(v.pipe(v.unknown(), v.transform((input) => new Date(input))), v.transform((input) => input.toJSON()));