Giter VIP home page Giter VIP logo

schema-to-yup's Introduction

Schema to Yup schema

Build a Yup schema from a JSON Schema, GraphQL schema (type definition) or any other similar type/class and field/properties model or schema :)

See Advanced config for all the more advanced configuration options available to customize this builder to support any of your requirements.

Schemas

  • JSON
  • GraphQL
  • Avro
  • Custom

JSON schema

The builder currently supports the most commonly used JSON Schema layout

To support other schemas see Advanced config

Typescript and Typings

Typings are available in the types folder

Generate typings

npx -p typescript tsc src/**/*.js --declaration --allowJs --emitDeclarationOnly --outDir types

You can use the YupBuilderConfig and TypeHandlerConfig type interfaces to facilitate building up the config object to pass to the YupBuilder.

Build and Sample run

$ yarn run build

Sample runs (uses built file in dist)

node sample-runs/person-schema.mjs

This sample run is configured with detailed logging in the config object:

{
  logging: true,
  logDetailed: [{
    propName: 'exclusiveMinimum',
    key: 'age'
  }]
}

Quick start

Install

npm install schema-to-yup -S or yarn add schema-to-yup

Use

const schema = {
  $schema: "http://json-schema.org/draft-07/schema#",
  $id: "http://example.com/person.schema.json",
  title: "Person",
  description: "A person",
  type: "object",
  properties: {
    name: {
      description: "Name of the person",
      type: "string",
    },
    email: {
      type: "string",
      format: "email",
    },
    foobar: {
      type: "string",
      matches: "(foo|bar)",
    },
    age: {
      description: "Age of person",
      type: "number",
      exclusiveMinimum: 0,
      required: true,
    },
    characterType: {
      enum: ["good", "bad"],
      enum_titles: ["Good", "Bad"],
      type: "string",
      title: "Type of people",
      propertyOrder: 3,
    },
  },
  required: ["name", "email"],
};

const config = {
  // for error messages...
  errMessages: {
    age: {
      required: "A person must have an age",
    },
    email: {
      required: "You must enter an email address",
      format: "Not a valid email address",
    },
  },
};

const { buildYup } = require("schema-to-yup");
const yupSchema = buildYup(schema, config);
// console.dir(schema)
const valid = await yupSchema.isValid({
  name: "jimmy",
  age: 24,
});

console.log({
  valid,
});
// => {valid: true}

This would generate the following Yup validation schema:

const schema = yup.object().shape({
  name: yup.string().required(),
  age: yup.number().required().positive(),
});

Note the "required": true for the age property (not natively supported by JSON schema).

Refs

Please note that this library does not currently resolve $ref (JSON Pointers) out of the box. You can use another library for that.

You could f.ex use json-schema-ref-parser to preprocess your schema. Also see:

Mode

By default, any property will be explicitly notRequired unless set to be required, either via required: true in the property constraint object or via the required list of properties of the object schema definition (of the property).

You can override the notRequired behavior by setting it on the new mode object of the configuration which can be used to control and fine-tune runtime behaviour.

const jsonSchema = {
  title: "users",
  type: "object",
  properties: {
    username: { type: "string" },
  },
};
const yupSchema = buildYup(jsonSchema, {
  mode: {
    notRequired: true, // default setting
  },
});

// will be valid since username is not required by default
const valid = yupSchema.validateSync({
  foo: "dfds",
});
const yupSchema = buildYup(jsonSchema, {
  mode: {
    notRequired: true, // default setting
  },
});
// will be invalid since username is required by default when notRequired mode is disabled
const valid = yupSchema.validateSync({
  foo: "dfds",
});

The new run time mode settings are demonstrated under sample-runs/mode

No validation error (prop not required unless explicitly specified):

$ npx babel-node sample-runs/modes/not-required-on.js

Validation error if not valid type:

$ npx babel-node sample-runs/modes/not-required-on.js

Shape

You can access the internal Yup shape, via shapeConfig on the yup schema returned by the buildYup schema builder function. Alternatively simply call propsToShape() on the yup builder.

This allows you to easily mix and match to suit more advanced requirements.

const { buildYup } = require("json-schema-to-yup");
const { shapeConfig } = buildYup(json, config);
// alternatively
// const shape = buildYup(json, config).propsToShape()
const schema = yup.object().shape({
  ...shapeConfig,
  ...customShapeConfig,
});

Types

Currently the following schema types are supported:

  • array
  • boolean
  • date
  • number
  • object
  • string

Mixed (any type)

  • strict
  • default
  • nullable
  • const
  • required
  • notRequired
  • oneOf (enum, anyOf)
  • notOneOf
  • refValueFor for confirm password scenario
  • typeError custom type error message
  • when
  • isType
  • nullable (isNullable)

Reference constraints

Reference constraints within the schema can be defined as follows:

schema = {
  required: ["startDate", "endDate"],
  type: "object",
  properties: {
    startDate: {
      type: "number",
    },
    endDate: {
      type: "number",
      min: "startDate",
    },
  },
};

Internally this will be resolved using Yup.ref as documented here in the Yup readme.

ref allows you to reference the value of a sibling (or sibling descendant) field to validate the current field.

Yup.ref is supported in the Yup docs for the following:

Array

  • ensure
  • compact
  • items (of)
  • maxItems (max)
  • minItems (min)
  • itemsOf (of)

Boolean

No keys

Date

  • maxDate (max)
  • minDate (min)

Number

  • integer
  • moreThan (exclusiveMinimum)
  • lessThan (exclusiveMaximum)
  • positive
  • negative
  • min (minimum)
  • max (maximum)
  • truncate
  • round

Object

  • camelCase
  • constantCase
  • noUnknown (propertyNames)

String

  • minLength (min)
  • maxLength (max)
  • pattern (matches or regex)
  • email (format: 'email')
  • url (format: 'url')
  • lowercase
  • uppercase
  • trim

For pattern (RegExp) you can additionally provide a flags property, such as flags: 'i'. This will be converted to a RegExp using new RegExp(pattern, flags)

For the pattern constraint you can also pass in excludeEmptyString to exclude empty string from being evaluated as a pattern constraints.

Similar projects

The library JSON Schema model builder is a powerful toolset to build a framework to create any kind of output model from a JSON schema.

If you enjoy this declarative/generator approach, try it out!

Advanced config

See Advanced config

Testing

Uses jest for unit testing.

  • Have unit tests that cover most of the constraints supported.
  • Could use some refactoring using the latest infrastructure (see NumericConstraint)
  • Please help add more test coverage and help refactor to make this lib even more awesome :)

Development

A new version is under development at schema-to-yup-mono which is this code ported to a lerna monorepo with a cleaner, mode modular structyure. More work needs to be done in terms of TDD and unit testing. Ideally this repo should be ported to Nx

Ideas and suggestions

Please feel free to come with ideas and suggestions on how to further improve this library.

Author

2018 Kristian Mandrup (CTO@Tecla5)

schema-to-yup's People

Contributors

andresouza avatar benoit-nadaud avatar buildxyz-git avatar dependabot[bot] avatar designbyonyx avatar ecnaidar avatar jamaybyrone avatar kristianmandrup avatar lookfirst avatar matthewfaircliff avatar mrloh avatar npup avatar ritchieanesco avatar syastrebov avatar

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.