@dgcode/schema
v0.1.21
Published
generic schema validation utility with yaml integration
Downloads
2
Readme
@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