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

mongoman

v1.4.0

Published

MongoDB management utility

Downloads

2

Readme

Mongoman

Build Status

A node utility to simplify schema and model management. Most utility is wrapped around the mongoose module. If you would like to use mongoman as a replacement for mongoose, mongoose is aliased at both mon.mongoose and mon.goose

Key

Usage

npm install mongoman

leverage mongoman to cut down on bloat in model creation. For example, this

var mongoose = require('mongoose');

var newSchema = new mongoose.Schema({
  email : {
    type       : String,
    required   : true,
    validation : [{
      msg       : 'invalid email',
      validator : function (value) {
        return /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/.test(value);
      }
    }]
  password : {
    type       : String,
    required   : true,
    validation : [{
      msg       : 'too short',
      validator : function (value) {
        return value.length >= 6
      }
    }]
  }
});

mongoose.model('ExampleModel', newSchema);

becomes this

var mon = require('mongoman');

mon.register('ExampleModel', {
  email    : mon().string().required().email().fin(),
  password : mon().string().required().min(6).fin()
});

The focus of mongoman is to simplify validation and schema creation. However, I do recommed looking at the utilities section for some helpful utilities.

Property Builder

The core use of mongoman is schema creation via property building. To make a new schema, simply use the property builder chain, initiated with mongoman() and terminated with fin(). For example. a simple user schema might look something like this

mon = require('mongoman');

var user = {

  // validates the name to be a required string that fits the regex
  name : mon().string().required().regex(/[a-z]+\s*[a-z+]/i).fin(),

  // sets the registered propert to default tothe current date-time
  registered : mon().date().default(new Date()).fin(),

  // validates the age to be a required integer of at least 18
  age : mon().required().number().integer.min(18).fin()

}

Every validation middleware function has a default error, but errors can be augmented to inlude a property name by passing in a value to the mon() function call.

mon().email().fin(); // validation error : 'invalid email'
mon('My email').email().fin(); // validation error : 'My email is not a valid email'

Universal

If a property or validation isn't included as a supported chainable function, you can easily include it using the following functions.

prop.set(key, value)

Set the key/value passed in for the property

  schema.newProp = mon().set('type', String).fin();

prop.validate(errorMsg, valFunction)

Bind the validation function to the property, throwing the error message if it returns false

  function isOdd (value) {
    return (value % 2) == 1
  }

  schema.newProp = mon().validate('newProp must be odd', isOdd).fin();

prop.index(key|value, [value])

Bind the key and value to the index attribute of the property. Providing only one parameter will set index equal to that parameter

  schema.newProp = mon().index('unique', false).fin();
  // or
  schema.newProp = mon().index('hashed').fin();

Types

prop.string()

Set property type to String

  schema.newProp = mon().string().fin();

prop.date()

Set property type to Date

  schema.newProp = mon().date().fin();

prop.number()

Set property type to Number

  schema.newProp = mon().number().fin();

prop.buffer()

Set property type to Buffer

  schema.newProp = mon().buffer().fin();

prop.mixed()

Set property type to be mixed

  schema.newProp = mon().mixed().fin();

prop.objectId()

Set property type to be an object ID

  schema.newProp = mon().objectId().fin();

prop.array()

Set property type to be Array

  schema.newProp = mon().array().fin();

prop.schema(ref, type)

Set property type to be a reference to another schema

ref -- Required - name of referred schema type -- Optional - Defaults ObjectId, possible values (Number, String, Buffer)

  schema.newProp = mon().schema('schemaName').fin();

Middleware

Any time [] is a function parameter, its is optional.

Shared

prop.onGet(function)

type: any

Passes the value of the property into the function. the returned value is what is exposed to the document on get

  schema.newProp = mon().onGet(function (value) {
    return value ? value + '-example' : value;
  }).fin();

prop.onSet(function)

type: any

Passes the value of the property into the function. the returned value is what is saved to the document on get

  schema.newProp = mon().onSet(function (value) {
    return value ? value + '-example' : value;
  }).fin();

Date

prop.expires(dateTime)

type: date

Sets the expiration of the date

  schema.newProp = mon().expires('1.5h').fin();

String

prop.toUppercase()

type: string

Sets the value to uppercase

  schema.newProp = mon().toUppercase().fin();

prop.toLowercase()

type: string

Sets the value lowercase

  schema.newProp = mon().toLowercase().fin();

prop.trim()

type: string

Trims the whitespace off the beginning and end of the string

  schema.newProp = mon().trim().fin();

Validation

important: using validations that do not apply to the property type will throw an error. To allow them to pass silently, set mongo configuration strict : false.

Any time [] is a function parameter, its is optional. any time [message] is included, a default message will be used unless this parameter is specified.

Shared

prop.required()

type: any

return an error if the property is not defined

  schema.newProp = mon().required().fin();

prop.default(value)

type: any

If no value is set for the property, set it to the default value passed in

  schema.newProp = mon().default('default value').fin();

prop.select([bool])

type: any

[bool] true or undefined if this path should always be included in the results, false if it should be excluded by default. This setting can be overridden at the query level.

  schema.newProp = mon().select().fin();

prop.enum(values, [message])

type: any

If the value submitted is not uncluded in the list of enumerated properties, an error is returned.

  schema.newProp = mon().enum(['foo', 'bar'], 'custom error').fin();

prop.unique([bool])

type: any

Insures a unique index is generated for the property. defaults to true. False causes the DB to be indifferent

  schema.newProp = mon().unique().fin();

prop.ref(model)

type: any

Creates a reference to another model. This is used to populate data from another document

  schema.newProp = mon().objectId().ref('fooModel').fin();

prop.min(value, [message])

type: string (length), array (length), number (value), date (value), object (keys), buffer (length)

Check that the value being saved is greater than or equal to the value passed into the property builder

  schema.newProp = mon().min(5).fin();

prop.max(value, [message])

type: string (length), array (length), number (value), date (value), object (keys), buffer (length)

Check that the value being saved is less than or equal to the value passed into the property builder

  schema.newProp = mon().max(5).fin();

prop.length(value, [message])

type: string (length), array (length), object (keys), buffer (length)

Check that the value being saved is the same length as the value passed into the property builder

  schema.newProp = mon().length(5).fin();

Arrays

prop.sparse()

return an error if the array contains undefined values

  schema.newProp = mon().array().sparse().fin();

Strings

prop.alphanum([message])

return an error if the string contains non alpha-numeric values

  schema.newProp = mon().string().alphanum().fin();

prop.regex(expression, [message])

return an error if the string does not match the expression

  schema.newProp = mon().string().regex(expression).fin();

prop.email([message])

return an error if the string is not a valid email address

  schema.newProp = mon().string().email().fin();

prop.token([message])

return an error if the string is not a valid token

  schema.newProp = mon().string().token().fin();

prop.guid([message])

return an error if the string is not a valid GUID

  schema.newProp = mon().string().guid().fin();

prop.hostname([message])

return an error if the string is not a valid hostname

  schema.newProp = mon().string().hostname().fin();

prop.url([message])

return an error if the string is not a valid url

  schema.newProp = mon().string().url().fin();

prop.uppercase([message])

return an error if the string is not uppercase

  schema.newProp = mon().string().uppercase().fin();

prop.lowercase([message])

return an error if the string is not lowercase

  schema.newProp = mon().string().lowercase().fin();

Numbers

prop.greater(limit, [message])

return an error if the number is below the limit

  schema.newProp = mon().number().greater(5).fin();

prop.less(limit, [message])

return an error if the number is above the limit

  schema.newProp = mon().number().less(5).fin();

prop.integer([message])

return an error if the string is not an integer

  schema.newProp = mon().string().integer().fin();

Utilities

mon.drop(collection)

drop a collection by name (normally just 'db')

mon.drop('db');

mon.connect([options])

takes options, defaulting to 'mongodb://localhost/database'. returns an instance of the database. also accessable through mon.db

var db = mon.connect();

mon.schema(schema)

returns an instance of a schema with the given schema object definition

var mySchema = mon.schema({
  name : mon().string().required().fin()
});

mon.model(modelName)

returns the model matching the given name

var MyModel = mon.model('MyModel');

mon.new(modelName)

returns a new instance of the model specified. applies the inputs if they are defined

var tester = mon.new('MyModel', {
  name : 'tester'
});

mon.register(schema, [options])

registers a new model with the given schema and options. The options object is where middleware, methods, index properties, and virtual properties are defined. A minimalistic model is defined below

var mon    = require('mongoman');
var bcrypt = require('bcrypt-nodejs');

mon.register('Person', {
  firstName : mon().string().required().fin(),
  lastName  : mon().string().required().fin(),
  secret    : mon().string().fin()
}, {
  middleware : {
    pre : {
      save : function (callback) {
        if (this.isModified('secret'))  {
          this.secret = bcrypt.hashSync(this.secret, bcrypt.genSaltSync());
        }

        return callback();
      }
    }
  },
  methods : {
    findFamily : function (callback) {
      return mon.model('Person').find({
        lastName : this.lastName
      }, callback);
    },
    compareSecret : function(submitted, callback) {
      var result = bcrypt.compareSync(submitted, this.secret);
      return callback(null, result);
    }
  },
  statics : {
    findByFirst : function (first, callback) {
      return mon.model('Person').find({
        firstName : first
      }, callback);
    }
  },
  virtuals : {
    fullName : {
      get : function () {
        return this.firstName + ' ' + this.lastName;
      }
    }
  }
});

mon.registerAll(directory, [regex])

traverses the directory tree requiring all js files (to register models on server startup). optional regex to filter files

./models/foo.js

var mon = require('mongoman');
mon.register('foo', { foo : mon().string().fin() });

./models/sub_models/bar_model.js

var mon = require('mongoman');
mon.register('bar', { bar : mon().string().fin() });

./server.js

// ... server setup

mon.connect();

mon.registerAll('../models', /_model/); // registers ['bar']

// OR

mon.registerAll('../models'); // registers ['foo', 'bar']

// ... server finalizing

Running Unit Tests

To run the unit tests, execute the following:

  npm test

Please make sure all unit tests pass before making a new PR