json-sequelize v1.2.0
json-sequelize
Translate JSON Schemas to Sequelize model definitions.
Install
npm i --save json-sequelizeUse
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 Mixins to the sequelizer function, each with a selector and a handler.
Mixin handler
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 objectkey- the current property keyproperty- the current property objectdefinition- the current model definitionSKIP- Symbol required to exclude a propertySequelize- the Sequelize object
Using handler to ignore props
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: {}
}Using handler to modify props
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:
Mixin selector
The selector can be a String, Object, or Function:
Mixin selector (String)
The simplest way is providing the property key as a String:
const mixin = {
selector: 'id',
handler: () => ({/* */})
}Mixin selector (Object)
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: () => ({/* */})
}Mixin selector (Function)
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 objectkey- the property keyproperty- 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.