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

officer

v0.2.0

Published

Officer is a schema-based JavaScript object validator and transformer.

Downloads

2

Readme

#Officer

Officer is a powerful schema-based JavaScript object validator and transformer. Keep your objects in line with Officer.

  • Operates on arbitrary, multi-level JavaScript objects
  • Supports collections and sub-objects
  • Specify pre- and post-validation functions
  • Supports a large variety of validation and transformation options
  • Provides detailed reports about processing and failures

##Use

###tl;dr

Officer = require('officer');
var officer = new Officer(schema);
officer.validate(data);
  1. Specify an object schema
  2. Create a new Officer object, passing in the schema and object to validate
  3. Validate your object with your shiny new Officer
  • Optional: Enjoy access to a large report about what happened to your object as well as detailed error messages

###Longer version:

First you need a schema to validate against. For this example, we'll be checking that some incoming cat JSON objects are the correct format, modifying and adding any information that can and should be, and then storing them.

Sample POST data

[{
  "name": "Shadow",
  "fur": { "coverage": 1, "color": { "h": 0, "s": 0, "l":  2 } }
},{
  "name": "Mittens",
  "fur": [
    { "coverage": 0.96, "color": { "h": 0, "s": 0, "l": 100 } },
    { "coverage": 0.04, "color": { "h": 0, "s": 0, "l":  50 } }
  ]
},{
  "name": "Patches",
  "fur": [
    { "coverage": 0.45, "color": { "h":  0, "s":  0, "l": 100 } },
    { "coverage": 0.30, "color": { "h": 33, "s": 90, "l":  45 } },
    { "coverage": 0.25, "color": { "h":  0, "s":  0, "l":   0 } }
  ]
}]

First, the schema as a single file (not as awesome).

The Full Schema) ./schema/full-cat.js

var rangedInteger = function(min, max) {
  return  {
    type: Number,
    min: min,
    max: max,
    // You can provide a function to perform on the value before it's validated with built-in validation an .after() function can also be provided
    before: function (n) {
      return Math.round(n);
    }
  };
};

module.exports = {
  name: {
    type: String,
    "default": "Kitty",
    regExp: {
      pattern: (/^[a-z\.\s]{1,32}$/i),
      error: "What kind of name is that?"
    }
  },
  fur: {
    type: {
      color: {
        type: {
          h: rangedInteger(0, 255),
          s: rangedInteger(0, 100),
          l: rangedInteger(0, 100),
          a: {
            type: Number,
            fallback: 1,
            min: 0,
            max: 1
          }
        },
      },
      coverage: {
        type: Number,
        min: 0,
        max: 1
      }
    },
    collection: true
  }
};

And then the schema broken up into sub-files to define sub-objects (more awesome).

Schema Level 1) ./schema/cat.js

module.exports = {
  // each top-level key matches the object property to look for and validate
  name: {
    // the type can be a JavaScript constructor function
    type: String,
    // If the data is missing, we can specify a default value or function
    "default": "Kitty",
    // regular expressions can be specified with an option error message
    regExp: {
      pattern: (/^[a-z\.\s]{1,32}$/i),
      error: "What kind of name is that?"
    }
  },
  fur: {
    // the type can be an embedded object literal describing the structure (a schema)
    type: require('./fur'),
    // this tells Officer to also accept an array of matching values
    collection: true
  }
};

Schema Level 2) ./schema/fur.js

module.exports = {
  color: {
    // nesting can go as deep as you'd like
    type: require('./color-hsla'),
  },
  coverage: {
    type: Number,
    // there are a few special built-in validation functions: Numbers->min, max being among them
    min: 0,
    max: 1
  }
};

Schema Level 3) ./schema/color-hsla

var rangedInteger = function(min, max) {
  return  {
    type: Number,
    min: min,
    max: max,
    // You can provide a function to perform on the value before it's validated with built-in validation. An .after() function can also be provided
    before: function (n) {
      return Math.round(n);
    }
  };
};

module.exports = {
  h: rangedInteger(0, 255),
  s: rangedInteger(0, 100),
  l: rangedInteger(0, 100),
  a: {
    type: Number,
    fallback: 1,
    min: 0,
    max: 1
  }
};

Once you have your schema, you can load it up and verify your object.

App) index.js

var Officer   = require('officer');
var catSchema = require('./schema/cat');
var catModel  = /* require our cat model */
var cats      = /* pull in our POST data */

cats.each(function (cat) {
  var catOfficer = new Officer(catSchema);

  if (catOfficer.validate(cat)) {
    catModel.save(cat); // The cat object has been modified directly
  }
  else {
    console.log(catOfficer.err.getMessages())
    // Also see what was done on an object with catOfficer.info.getMessages()
  }
});

##Why did I make this?

I was unhappy with the validation tools available online and wanted something that would work on complex objects with powerful schemas. I developed this tool as a way to work with JSON data going into my MongoDB collections without having to use a tool like Mongoose. It's in no way tied to MongoDB though.

##Version

0.2.0

##Requirements

Officer requires node.js and npm. It is dependent on the underscore package, but that will be removed in a later release.

##Installation

The easiest way to get it into your node project is through npm

npm install officer --save

##Contribution and Feedback

If you find an error in the tool, please fork the code, fix it and request a pull.

Feedback and feature requests are welcome.

##License

MIT

Free Software, Hell Yeah!