@japan-d2/schema
v0.10.1
Published
A library designed to implement both TypeScript Interface and json-schema.
Downloads
12
Readme
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