@dgcode/schema v0.1.21
@dgcode/schema
generic schema validation utility with yaml integration
Install
$ npm install @dgcode/schema
Usage
import { Validator } from '@dgcode/schema';
const validator = new Validator();
const res = validator.validate(5, {
type: 'number'
});
res.isValid(); // true
Schema
A validator, as showcased above, accepts two arguments while validating: (value, schema)
. The value
is the one you want to test, and schema
defines the expected kind of value to accept.
A schema is an object defining the desired shape of the values you want to validate. They can be as simple as { type: 'number' }
or { type: 'boolean' }
but can also be customized with more complex properties, such as the following object-matching structure:
const objectSchema = {
type: 'object',
properties: {
foo: { type: 'string' },
bar: { type: 'number' }
}
};
Here objectSchema
will match JavaScript objects that implement the expected structure such as { foo: 'hello', bar: 5 }
.
Allowed types
import { listSchemaTypes } from '@dgcode/schema';
listSchemaTypes();
// ['string', 'number', ...] (see below)
You can use the listSchemaTypes()
method exposed by this library, for convenience, to get an overview of all allowed schema type strings such as 'string'
or 'object'
. Below are the allowed types:
Type value | Example |
---|---|
'string' | 'foo' , '' |
'number' | 5 , 10.1 , -30 |
'boolean' | true , false |
'int' | 5 , 0 , -1 |
'nint' | 5 , 100 |
'bigint' | BigInt(1932839) , 123n |
'symbol' | Symbol('hello') |
'undefined' | undefined |
'null' | null |
'nullish' | null , undefined |
'truthy' | true , 1 , {} |
'falsy' | false , 0 , null , '' |
'object' | {} , Object.create(null) |
'object-like | {} , function(){} , [] |
'array' | [] , Array(5) |
'function' | function(){} , () => {} |
'any' , '*' | null , {} , 5 |
YAML string conversion
YAML conversion is facilitated with help of the toYAML()
method (internally using the yaml package). It requires a value
to convert followed by a schema
describing the expected structure.
While you could just stringify your values by your own means, the main purpose is to inject description
s (and a little bit of prettyfying) into your YAML output.
import { toYAML } from '@dgcode/schema';
const value = {
foo: {
bar: 'Hello',
baz: 5
}
};
const schema = {
type: 'object',
properties: {
foo: {
type: 'object',
description: 'An object with detailed properties.',
properties: {
bar: {
type: 'string',
description: 'Hello,'
},
baz: {
type: 'number',
description: 'World!'
}
}
}
}
};
const str = toYAML(value, schema);
str
will be a string with valid YAML output equal to:
# An object with detailed properties.
foo:
# Hello,
bar: Hello
# World!
baz: 5
Prettyfication
If we wanted some additional spacing between comments:
const str = toYAML(value, schema, {
spaceAboveComments: true
});
which will yield:
# An object with detailed properties.
foo:
# Hello,
bar: Hello
# World!
baz: 5
Inline comments
By default, all comments are rendered above their keys / values. You can opt to render inline comments instead:
const str = toYAML(value, schema, {
preferInlineComments: true
});
which will yield:
foo: # An object with detailed properties.
bar: Hello # Hello,
baz: 5 # World!
You can also pre-configure your schemas instead to have specific components render their descriptions inline by default, with help of the inlineDescription: true
hint:
const schema = {
type: 'object',
properties: {
foo: {
type: 'object',
description: 'An object with detailed properties.',
inlineDescription: true,
properties: {
bar: {
type: 'string',
description: 'Hello,'
},
baz: {
type: 'number',
description: 'World!'
}
}
}
}
};
const str = toYAML(value, schema);
which will yield:
foo: # An object with detailed properties.
# Hello,
bar: Hello
# World!
baz: 5
Allow multiple value types
Case 1: simple types
If your tested value can be, for example, a string
or a number
, you can configure your own schema definition with those allowed types as:
// unknown value, we just know that we allow
// it to be a string or number
const value = ...;
const schema = {
type: {
$any: ['string', 'number']
}
};
Case 2: more complex types
If your tested value can be, for example, a string
or an object
with detailed properties, you need to split the schema into two whole schema scenarios:
// unknown value, we just know that we allow
// it to be a string or an object
const value = ...;
const schema = {
$any: [
{ type: 'string' },
{ type: 'object',
properties: { ... } }
]
};
Example
Note that you can apply both patterns at any nested level of your schema definitions.
Error detection
TODO
License
MIT