Skip to content
This repository has been archived by the owner on Apr 7, 2020. It is now read-only.

HomeServicesOfAmerica/mongoose-babelmodel

Repository files navigation

mongoose-babelmodel

A library for using babeljs to create mongoose models from classes

Installation

npm i --save mongoose-babelmodel

Requirements

BabelJs for compiling to ES5 using --stage 0 flag for decorators

Usage Example

import {Model, pre} from 'mongoose-babelmodel'

class User extends Model {
    name = String;
    password = String;
    email = String;
    roles = {type: Array, default: ['Subscriber']};
    _posts: Array;

    // added to schema using .method()
    verifyPassword(password) {
        let encrypted = yourEncryptionFunc(password);
        return encrypted === this.password;
    }

    // added to schema using .method()
    hasRole(role) {
        return role.name in this.roles;
    }

    // added to schema using .pre()
    @pre('save')
    static encryptPass(next) {
        this.password = yourEncryptionFunc(this.password);
    }

    // added to schema using .virtual().get()
    get posts() {
        return this._posts;
    }

    // added to schema using .virtual().set()
    set posts(posts) {
        this._posts = posts;
    }

    // added to schema using .static
    static usersWithPosts() {
        return this.find({$where: 'this.posts.length > 0'});
    }
}

let user = new User();

export default user.generateModel();

Declaring Schema

You can declare your schema as class properties ( ES7 stage 0 candidate ) in the following fashion:

class Example extends Model {
    _schema = {
        name: String,
        type; String
    };
    
    // OR 
    
    name = String;
    type = String;
}

You can also declare your _schema in the constructor.

class Example extends Model {
    constructor () {
        super();
        this._schema = { name: String, type: String };
    }
}

Or you can rely on the super constructor to pass in your schema upon initialization

class Example extends Model {
    instanceMethod () {
        return this.name;
    }
}

let example = new Example({name: String, type: String});

You can add schema paths easily

example.newPath = {type: Boolean, default: true};

You can remove schema paths easily

delete example.newPath;

How it works: the _schema property is what is used during model generation. however all instance items are added to the _schema object during generateSchema(). Please note that _schema is the base. If you declare a path in _schema and then add the same path to the instance object it will overwrite. Like so:

class Example extends Model {
    _schema = {
        name: String,
        type: String
    };
}

let example = new Example();

// During generateSchema _schema.type will be set to {type: String, default: 'Test'}
example.type = {type: String, default: 'Test'};

API Documentation

Model

The Model class is the base class that contains the core functions for generating the Mongoose model. It has the following methods available:

model.extend(modelInstance)

You can call extend and pass in another instance of model extended from babelmodel in order to combine all methods, Schema paths, pre/post middleware, static functions and validators into the calling instance.

class Post extends Model {
    @pre('save')
    static generateSlug(next) {
        this.slug = this.title.toLowerCase().replace(' ', '-');
        next();
    }
}

class Tag extends Model {
    static withTag(tag) {
        return this.find({tags: {$in: tag}}).exec();
    }
}

// String 'ObjectId' as schema type will get replaced with Schema.Types.ObjectId
let post = new Post({
    title: {type: String, required: true},
    content: {type: String, required: true},
    author: {type: 'ObjectId', ref: 'User'}
});

let tag = new Tag({
    tags: {type: Array, default: []}
});

post.extend(tag);

export default post.generateModel();
model.generateSchema()

generates the mongoose schema and adds all functions/middleware/validations/virtuals to the appropriate places. Getter and Setter functions are added using .virtual(name).get() and .set() respectively. Static functions get added using .static() Regular functions added through .method() calls Specially annotated functions (@validation, @pre, @post) get added using appropriate markup

model.generateModel()

returns mongoose.model() call, with your Model's name as the name and the generated schema

model.schema

Getter/setter functions. schema.add(schema, overwrite = false) allows you to add schema paths to a model instance before generateModel() is called schema.remove(schema) - as you would expect, removes schema paths that are found in the schema parameter schema.list() - returns the schema object schema = {} - sets the schema object overwriting anything previously set.

Method Decorators

All of the following decorators are also exported by the module. They must be declared on static methods.

pre(action, priority = 10)

Decorators that wrap the decorated function, creating a new function that allows it to be automatically added to the schema during model.generateSchema(). action accepts any hook action defined in the mongoose documentation. Priority allows you to control the order in which hooks are executed. the lowest priority hook is executed last, highest first. Defaults to 10. Hooks added through extensions will honor this order as well so if you add a hook in a extension with a very high priority it will happen first as long as there isn't a hook with a higher priority on the base model.

post(action)

Decorators that wrap the decorated function, creating a new function that allows it to be automatically added to the schema during model.generateSchema(). action accepts any hook action defined in the mongoose documentation

validation(path, message)

Decorator that wraps the function, creating a new function that allows it to be automatically added to the schema during model.generateSchema(). path accepts a string referencing the path to validate, message is the error message returned if the validation fails.

plugin(plugin, options = {})

Decorator for the class to use plugins. Just pass in the plugin function and options. Can stack multiple plugins. Plugins are added right before the schema is returned so they will be the last things added to the stack.

@plugin(autopopulate)
@plugin(findorcreate)
class Document {
    // Your class definition
}

About

A library for using babeljs to create mongoose models from classes

Resources

License

Stars

Watchers

Forks

Packages

No packages published