Git Product home page Git Product logo

js-schema's Introduction

schema

A library designed to implement both TypeScript Interface and json-schema.

install

npm install @japan-d2/schema

or

yarn add @japan-d2/schema

Usage

Schema definition

Construct JSON Schema and TypeScript types simultaneously in the method chain for defineSchema(). The following methods are provided for schema definition:

  • string (name, options?)
  • number (name, options?)
  • integer (name, options?)
  • boolean (name, options?)
  • null (name, options?):
  • const (name, value, options?)
  • enum (name, type, values, options?)
  • array (name, type, itemOptions?, arrayOptions?)
  • object (name, options, objectOptions?)

For example:

import { defineSchema } from '@japan-d2/schema'

const exampleUserSchema = defineSchema()
  .string('name', {
    maxLength: 32,
    minLength: 1
  })
  .integer('age', {
    minimum: 0
  })

Extend other schema

schema.extend (otherSchema) -> schema

import { defineSchema } from '@japan-d2/schema'

const withAdmin = defineSchema()
  .const('admin', true)

const exampleUserSchemaWithAdmin = exampleUserSchema
  .extend(withAdmin)

Direct object definition

defineObjectSchema() -> schema

import { defineObjectSchema, field } from '@japan-d2/schema'

const user = defineObjectSchema({
  // required fields
  name: field.string(),
  type: field.enum('string', ['creator', 'observer']),
}, {
  // optional fields
  channels: field.array('object', {
    name: field.string(),
    category: field.enum('string', ['music', 'nature', 'game'])
  })
})

Omit specific key

schema.omit (...keys) -> schema

import { defineSchema } from '@japan-d2/schema'

const exampleUserSchemaWithoutPrivateInfo = exampleUserSchema
  .omit(
    'age',
    'name',
    'phoneNumber'
  )

Pick specific key

schema.pick (...keys) -> schema

import { defineSchema } from '@japan-d2/schema'

const exampleUserSchemaOnlyPublicInfo = exampleUserSchema
  .pick(
    'id',
    'email',
    'nickName'
  )

Combine

combineSchema.oneOf ([schema1, schema2, ...]) -> schema

import { defineSchema, combineSchema } from '@japan-d2/schema'

const contactSchema = combineschema.oneOf([
  phoneNumberContactSchema,
  emailContactSchema,
])

Runtime conversion to JSON Schema

call instance method toJSONSchema() of schema.

const jsonSchema = exampleUserSchema.toJSONSchema()
console.log(jsonSchema)

The return value is a standard JSON Schema object (supports Draft 7).

{
  type: 'object',
  properties: {
    name: { type: 'string', maxLength: 32, minLength: 1 },
    age: { type: 'integer', minimum: 0 }
  },
  required: [ 'name', 'age' ]
}

Validation

Assume the following "dirty" data for validation.

const dirtyUser = {
  name: 'roa',
  age: Math.random() < 0.5 ? 13 : '13'
}

dirtyUser.age // number | string

Validation with User-Defined Type Guard

validate (instance, schema) -> boolean

Returns true or false using validate function in jsonschema package with options { throwError: false }. When used inside an if conditional expression, type guard is enabled.

import { validate } from '@japan-d2/schema'

if (validate(dirtyUser, exampleUserSchema)) {
  dirtyUser.age // number
}
dirtyUser.age // number | string

Validation with Assertion Function

assertValid (instance, schema) -> void

Throws ValidationError if instance are invalid, and does nothing if valid. Internally it uses validate function in jsonschema package with options { throwError: true }. This function is an Assertion Function that uses the new features of TS3.7 and this fixes the type in a scope where no error occurred.

import { validate } from '@japan-d2/schema'

// throw validation error if age is not a number
assertValid(dirtyUser, exampleUserSchema)

dirtyUser.age // number

Type utilities

Pure

Provides a purified schema type. Same as guarded by validate or assertValid.

import { Pure } from '@japan-d2/schema'
type UserType = Pure<typeof exampleUserSchema>

const user: UserType = {
  name: 'roa',
  age: 13,
}

Dirty

Provides an explicitly tainted schema type. It can be used to indicate an external value as input value for validate or assertValid.

import { Dirty, assertValid } from '@japan-d2/schema'
type DirtyUserType = Dirty<typeof exampleUserSchema>

app.post('/users', (req) => {
  const user: DirtyUserType = req.body

  user.name // unknown
  user.age // unknown

  assertValid(user)

  user.name // string
  user.age // number
})

License

MIT

js-schema's People

Contributors

himanoa avatar uneco avatar

Watchers

 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.