json-sequelize
Translate JSON Schemas to Sequelize model definitions.
Install
npm i --save json-sequelize
Use
Simply provide a valid JSON schema to the sequelizer
function.
const { sequelizer } = require('json-sequelize')
const schema = {
title: 'User Schema',
unique: ['username', 'email'],
required: ['username', 'email', 'password'],
properties: {
id: { type: 'integer' },
active: { type: 'boolean' },
username: { type: 'string', maxLength: 255 },
password: { type: 'string' },
email: { type: 'string', format: 'email' },
role: { type: 'string', enum: ['admin', 'staff', 'guest'], default: 'guest' },
tags: { type: 'array', items: { type: 'string' } },
createdAt: { type: 'string', format: 'date-time' }
}
}
const model = sequelizer(schema)
console.log(model)
Yields:
{
id: { type: Sequelize.INTEGER },
active: { type: Sequelize.BOOLEAN },
username: { type: Sequelize.STRING, unique: true, allowNull: false },
password: { type: Sequelize.TEXT, allowNull: false },
email: { type: Sequelize.TEXT, unique: true, allowNull: false },
role: { type: Sequelize.ENUM('admin', 'staff', 'guest'), defaultValue: 'guest' },
tags: { type: Sequelize.JSONB },
createdAt: { type: Sequelize.DATE, defaultValue: Sequelize.NOW }
}
Mixins
You can provide one or more Mixin
s to the sequelizer
function, each with a selector
and a handler
.
handler
Mixin The handler
must be a Function
that returns a new Sequelize model definition or SKIP
if ignoring selected properties.
The handler
function gets called with an object containing:
-
schema
- the schema object -
key
- the current property key -
property
- the current property object -
definition
- the current model definition -
SKIP
- Symbol required to exclude a property -
Sequelize
- the Sequelize object
handler
to ignore props
Using Sometimes it can be useful to include computed properties in the JSON Schema but to exclude them in the Sequelize model definitions.
const schema {
computed: ['beep', 'boop'],
properties: {
id: {},
beep: {},
boop: {}
}
}
const mixin = {
handler: ({ key, schema, SKIP }) => schema.computed.includes(key) && SKIP
}
The resulting model will only include the id
property:
{
id: {}
}
handler
to modify props
Using Typically, the handler
is used to update one or more properties with Sequelize definitions.
const schema = {
properties: {
id: { type: 'integer' }
}
}
const mixin = {
selector: 'id',
handler: ({ Sequelize }) => ({
type: Sequelize.STRING,
defaultValue: () => nanoid(),
primaryKey: true
})
}
const model = sequelizer(schema, mixin)
The resulting model:
{
id: { type: Sequelize.STRING, primaryKey: true, defaultValue: [Function Anonymous] }
}
The above model definition will be replicated in each of the following examples:
selector
Mixin The selector
can be a String
, Object
, or Function
:
selector
(String
)
Mixin The simplest way is providing the property key as a String
:
const mixin = {
selector: 'id',
handler: () => ({/* */})
}
selector
(Object
)
Mixin Another way is to provide a matching key:value pair to match one or more of the schema.properties
:
const mixin = {
selector: { type: 'integer' },
handler: ({ Sequelize }) => ({/* */})
}
Using the key
property, allows targeting by schema.properties
keys. This approach is equivalent to providing the value as a plain String
.
const mixin = {
selector: { key: 'id' },
handler: () => ({/* */})
}
selector
(Function
)
Mixin A function will execute against each property in schema.properties
and should return a truthy value.
const mixin = {
selector: ({ key }) => key === 'id',
handler: () => ({/* */})
}
The selector
function gets called with an object containing:
-
schema
- the schema object -
key
- the property key -
property
- the property object
Multiple Mixins
Combining mixins is done by adding them to an array, where each mixin will run consecutively.
const model = sequelizer(schema, [mixin1, mixin2, ...mixins])
Tests
Run npm test
to run tests.
Run npm coverage
to produce a test coverage report.
Credits
Originally forked from ronalddddd/sequelizer - upgraded to a purely functional style with some added sugar.