Kikobeats / Osom
Programming Languages
Labels
Projects that are alternatives of or similar to Osom
osom
An Awesome [/osom/] Object Data Modeling. Inspired in mongoose but Database Agnostic.
Installation
$ npm install osom --save
Preview
var osom = require('osom')
function trim (str) {
return str.trim()
}
function isValidTitle (str) {
return str.length > 0
}
// setup your schema
var schema = {
title: {
type: String,
validate: isValidTitle,
transform: [trim]
},
category: String,
type: String,
source: String,
link: String,
createdAt: String,
updatedAt: String
}
// create validator based on schemas
var validator = osom(schema)
// validate it!
validator({ title: ' 23 ' }) // => {title: '23'}
Usage
osom(schema, [global])
where:
-
schema
: It represents a set of rules (one per each key) that will be used for validate an object. -
global
(optional): It brings you the possibility to declare global rules definition as helper to avoid write repetitive code.
After that, you will have a validator function
that you can invoke passing the object to be validate.
Schema
Simple
The most common use case is validate the type
of something.
If you are only interested in the type
, you can provide a simple schema like:
var simpleSchema = {
age: Number
}
Where key
is the name of the rule and value
the type
of it.
Advanced
The basic mode is a simplification of the advanced mode for the most common use case.
While in basic mode only is possible setup type
, in advanced mode you can setup more things providing a configurable object
.
Each key of the object represent a rule . It's possible setup different things in the same rule.
Defining Rules
type
Type: function
As in basic mode, it specifies the type
of the output value:
var schema = {
age: {
type: Number
}
}
Internally it uses chaste. This makes easy casting compatible types:
var schema = {
age: {
type: Number
}
}
var validator = osom(schema)
validator({ age: '23' }) // => {age: 23}
casting
Type: boolean
Default: true
It enable/disable type casting.
An TypeError
will be throwed under different type
evaluation.
var schema = {
age: {
type: String,
casting: false
}
}
var validator = osom(schema)
validator({ age: '23' }) // => TypeError("Expected a {string} for 'age'.")
required
Type: boolean
|string
Default: false
It marks a rule as required field and throws TypeError
if value for the field is not present.
Additionally is possible provide a custom error message. For do it, pass an String
.
var schema = {
age: {
type: String,
required: 'sorry but you must provide an age.'
}
}
var validator = osom(schema)
validator({}) // => TypeError("sorry but you must provide an age")
default
Type: string
|object
|number
|boolean
|function
Default: null
It sets a default value if nill
value as input is provided.
Additionally you can provide a function
for set a dynamic value:
var schema = {
age: {
type: Number, default: function () { return 23 }
}
}
var validator = osom(schema)
validator({}) // => { age: 23 }
transform
Type: function
|array
Default: []
It transforms the input value.
The Methods provided in the array
are applied as pipeline (the input of the second is the output of the first).
function trim (str) {
return str.trim()
}
var schema = {
age: {
type: String,
transform: [trim]
}
}
var validator = osom(schema)
validator({ age: ' 23 ' }) // => { age: '23' }
validate
Type: function
|object
Default: null
It set up a function
that will be exec to validate the input value.
If it fails, it throws TypeError
.
var schema = {
age: {
type: String,
validate: function (v) {
return v === '23'
}
}
}
var validator = osom(schema)
validator({ age: 25 }) // => TypeError("Fail '25' validation for 'age'.")
Providing a object brings you the possibility set up a custom error message:
var schema = {
age: {
type: String,
validate: {
validator: function (v) {
return v === '23'
},
message: 'expected a millenial value instead of %s!'
}
}
}
var validator = osom(schema)
validator({ age: 25 }) // => TypeError("expected a millenial value instead of 25!")
Defining Global Rules
While is possible provide specific setup per each rule, also is possible provide them as global to apply to all rules.
This minimizes the schemas definitions.
function trim (str) {
return str.trim()
}
var schema = {
age: {
type: String
}
}
var globalFields = {
transform: [trim]
}
var validator = osom(schema, globalFields)
validator({ age: ' 23 ' }) // => {age: '23'}
No problem if later you need to avoid it for a specific case.
function trim (str) {
return str.trim()
}
var schema = {
age: {
type: String,
transform: []
}
}
var globalFields = {
transform: [trim]
}
var validator = osom(schema, globalFields)
validator({ age: ' 23 ' }) // => {age: ' 23 '}
Tips
Working with async code
This library works synchronously.
However, you can use it comfortably in a async workflow transforming the interface into a callback/promise style.
For example, consider use async#asyncify for do it. we could have a schema.js
file like:
var schema = osom({
title: {
type: String,
validate: isValidTitle,
transform: [trim]
},
category: String,
type: String,
source: String,
link: String,
createdAt: String,
updatedAt: String
})
module.exports = async.asyncify(schema)
module.exports.sync = schema
Then you only need use it into a async workflow:
var schema = require('./schema')
schema(data, function (validationError, instance) {
/** do something */
})
Be careful: this transformation doesn't mean that the function works now asynchronously; Just is converting
try-catch
interface into callback(err, data)
.
License
MIT © Kiko Beats