npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

osom

v3.1.4

Published

An Awesome [/osom/] Object Schema Modeling

Downloads

139

Readme

osom

An Awesome [/osom/] Object Data Modeling. Inspired in mongoose but Database Agnostic.

Last version Coverage Status NPM Status

Installation

$ npm install osom --save

Preview

const osom = require('osom')

function trim (str) {
  return str.trim()
}

function isValidTitle (str) {
  return str.length > 0
}

// setup your schema
const 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
const 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:

const 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:

const schema = {
  age: {
    type: Number
  }
}

Internally it uses chaste. This makes easy casting compatible types:

const schema = {
  age: {
    type: Number
  }
}

const 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.

const schema = {
  age: {
    type: String,
    casting: false
  }
}

const 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.

const schema = {
  age: {
    type: String,
    required: 'sorry but you must provide an age.'
  }
}

const 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:

const schema = {
  age: {
    type: Number, default: function () { return 23 }
  }
}

const 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()
}

const schema = {
  age: {
    type: String,
    transform: [trim]
  }
}

const 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.

const schema = {
  age: {
    type: String,
    validate: function (v) {
      return v === '23'
    }
  }
}

const 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:

const schema = {
  age: {
    type: String,
    validate: {
      validator: function (v) {
        return v === '23'
      },
      message: 'expected a millenial value instead of %s!'
    }
  }
}

const 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()
}

const schema = {
  age: {
    type: String
  }
}

const globalFields = {
  transform: [trim]
}

const 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()
}

const schema = {
  age: {
    type: String,
    transform: []
  }
}

const globalFields = {
  transform: [trim]
}

const 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:

const 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:

const 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