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

@clocklimited/schemata

v7.0.5

Published

Define, create, and validate your business objects, based on well defined schema.

Downloads

410

Readme

schemata - Define, create, and validate objects from a simple schema.

NPM Details

Build Status Coverage Status Dependency Status NPM version Greenkeeper badge

schemata allows you to define schemas to ensure your objects are well formed. This is similar to the concept of a schema in mongoose but unlike mongoose schemata has nothing to do with data persistence. This lightweight decoupled approach gives the ultimate flexibility and freedom to use the module within your application whether you are storing your objects or not.

Changelog

v7.0.0

This should be compatible with v6 but has some major rewrites, hence the version bump.

You can now validate using regular functions, promises and the old style callback.

const databaseLookup = async () => null

// Regular function
const isOfWizardingAge = (propertyName, name, entity) =>
  entity[propertyName] < 17 && 'Sorry you are not of age'

// Promise
const isUniqueAge = async (propertyName, name, entity) => {
  const found = await databaseLookup({ age: entity[propertyName] })
  if (found) return `${entity[propertyName]} already exists`
}

const properties = createContactSchema().getProperties()
properties.age.validators = [
  isOfWizardingAge,
  isUniqueAge,
  (propertyName, name, object, cb) =>
    cb(null, `${propertyName} ${name} ${object[propertyName]}`)
]
const schema = createNamedSchemata(properties)
const errors = await schema.validate(
  schema.makeDefault({ name: 'Paul', age: 16 })
)
console.error(errors)

This version is the first to be transpiled using babel and with async.js removed.

v6.0.0

Moves castProperty to a static function.

v5.0.0

The main initialization arguments have now changed so you must provide a name and can also provide a description. The schema definition is now set via the properties property.

v4.1.0

Validate now return a promise if a callback is not provided.

v4.0.0

Node 6+ upgrade. Direct access to the schema has been removed (schema.schema) and getProperties() must now be used.

v3.2.0

  • Introduces shorthand for schema.validators.all = []. Now schema.validators = [] is equivalent.

v3.1.0

  • Fixed a bug where stripUnknownProperties() was not stripping out properties of type array that were null.

v3.0.0

This version prevents you from using arrays and objects for defaultValue. Now only primitives and functions are allowed. If you are not doing this in your project then you can safely upgrade from v2. See https://github.com/serby/schemata/pull/34 for more details.

Installation

npm install schemata

Usage

Creating a basic schema

const schemata = require('schemata')

const contactSchema = schemata({
  name: 'Contact',
  description: 'One of my friends or acquaintance',
  properties: {
    name: {
      name: 'Full Name'
    },
    age: {
      type: Number
      defaultValue: 0
    },
    active: {
      type: Boolean,
      defaultValue: true
    },
    phoneNumber: { // If no type is given String will be assumed
    },
    createdDate: {
      type: Date,
      defaultValue: () => new Date()
    }
  }
})

Schema Properties

  • name: (optional) The friendly version of the property name. If omitted a decamlcased version of the property name will be used.
  • type: (optional) The javascript type that the property value will be coerced into via the cast() and castProperty() functions. If this is omitted the property will be of type String. Type can be any of the following: String, Number, Boolean, Array, Object, Date or another instance of a schemata schema.
  • defaultValue: (optional) The property value return when using makeDefault() If this is a function, it will be the return value.
  • tag[]: (optional) Some functions such as cast() and stripUnknownProperties() take a tag option. If this is passed then only properties with that tag are processed.
  • validators{}: (optional) A object containing all the validator set for this property. By default the validator set 'all' will be used by validate(). schemata gives you the ability defined any number of validator sets, so you can validate an object in different ways. Since 3.1, if you only want one set of validators you can set .validators = [ validatorA, validatorB ] as a shorthand. Since 4.0.0 you can also omit the callback and provide a promise.

Creating a new object

const blank = contactSchema.makeBlank()
{
  name: null,
  age: null,
  active: null,
  phoneNumber: null
}

Creating a new object with the default values

const default = contactSchema.makeDefault()
{
  name: null,
  age: 0,
  active: true,
  phoneNumber: null
}

Strip unknown properties from an object

Sometimes you've receive data from a POST or another IO operation that may have more properties than your business object expect. stripUnknownProperties will take an object and strip out any properties that aren't defined in the schemata scheme.

var stripped = contactSchema.stripUnknownProperties({
  name: 'Dom',
  extra: 'This should not be here'
})
{
  name: 'Dom'
}

Validate an object against the schema

Validation is easy in schemata, just call validate() on your schema passing in the object to validate:

contactSchema.validate(objectToValidate, function(error, errors) {
  // errors
})

Validators are assigned to a field of the schema by adding them as an array to the validators property of the object as follows (this is an extension of the example at the top):

name: {
  name: 'Full Name',
  validators: { all: [validator1, validator2] }
}

Validators are functions that have the following signature:

function(propertyName, errorPropertyName, object, callback) {}

The callback must be called with a falsy value (such as undefined or null) if the validation passes, or with a string with the appropriate error message if it fails validation.

A full validator example:

const required = function (propertyName, errorPropertyName, object, callback) {
  return callback(object[propertyName] ? undefined : errorPropertyName + ' is required')
}

name: {
  name: 'Full Name',
  validators: { all: [ required ] }
}

If any of the validators fail then the errors will be returned in the callback from validate() with the object key being the field name and the value being the error message.

For a comprehensive set of validators including: email, integer, string length, required & UK postcode. Check out validity.

Cast an object to the types defined in the schema

Type casting is done in schemata using the cast() and castProperty() functions. cast() is used for when you want to cast multiple properties against a schema, castProperty() is used if you want to cast one property and explicitly provide the type.

const schemata = require('schemata')

const person = schemata({
  name: 'Person',
  description: 'Someone',
  properties: {
    name: {
      type: String
    },
    age: {
      type: Number
    },
    active: {
      type: Boolean
    },
    birthday: {
      type: Date
    },
    friends: {
      type: Array
    },
    extraInfo: {
      type: Object
    }
  }
})

const objectToCast = {
  name: 123456,
  age: '83',
  active: 'no',
  birthday: '13 February 1991',
  friends: '',
  extraInfo: undefined
}

var casted = person.cast(objectToCast)
{
    name: '123456',
    age: 83,
    active: false,
    birthday: Date('Wed Feb 13 1991 00:00:00 GMT+0000 (GMT)'),
    friends: [],
    extraInfo: {}
}

Get friendly name for property

If you want to output the name of a schema property in a human-readable format then you need the propertyName() function. If your schema field has a name attribute, then that is returned. If that is not set then the name is obtained by decamelcasing the field name.

Consider the following example:

const schemata = require('schemata')

const address = schemata({
  name: 'Address',
  description: 'Postal location',
  properties: {
    addressLine1: {},
    addressLine2: {},
    addressLine3: {
      name: 'Town'
    },
    addressLine4: {
      name: 'Region'
    }
  }
})

console.log(address.propertyName('addressLine1'))
// Returns 'Address Line 1' because there is no name set

console.log(address.propertyName('addressLine3'))
// Returns 'Town' because there is a name set

Credits

Paul Serby follow me on twitter @serby

Dom Harrington

Licence

ISC