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

livegoose

v1.0.1

Published

declarative api building with mongoose

Downloads

4

Readme

WIP

This is still an early wip. It has not yet been tested as thoroughly as I would like, but appears to be working for everything except the populate methods on the routes. If anyone has the courage to be an early adopter I welcome the feedback.

LiveGoose

Livegoose is very lightweight module which allows for extremely declarative rest programming with mongoose backends. Livegoose is built on top of the preston module, which supplies most of the functionality. Livegoose simply allows the process to be more declarative.

All the user needs to do is to create a folder (./models by default, but configurable) which contains a file for each mongoose schema/model (see the models section for details). Then with a minimal amount of setup mongoose is off and running.

Setup

Set up for livegoose is extremely simple. The user simply requires livegoose and then passes in a mongoose instance. The user is then returned a livegoose object which can be configured by modifying the values for models and/or url. Then simply call the render function and pass in the app object created from express to enable your routes.

Example:

#LiveScript

#setup
require! livegoose
require! mongoose
mongoose.connect = 'localhost:..'
goose = livegoose mongoose #pass in a mongoose instance

#optional configuration
goose.models = "#{__dirname}/myfolder" #default "#{process.cwd()/models}"
goose.url = '/api' # defualt '/'

#usage
app = express!
#app setup
goose.render app #goose.render returns the app so it can be chained
// JavaScript

// setup
var livegoose, mongoose, goose, app;
livegoose = require('livegoose');
mongoose = require('mongoose');
mongoose.connect = 'localhost:..';
goose = livegoose(mongoose);

// optional configuration
goose.models = __dirname + "/myfolder"; //default process.cwd() + "/models"
goose.url = '/api';

//usage
app = express();
goose.render(app);

Models

Each file in the livegoose.models folder (default './models') returns a single object. From this object livegoose will build your schemas, models, routes and subroutes.

These objects have two required fields:

  • name: which will the name of the model and, if the model will be a route, serve as the basis for the name of the route (routes are converted to lowercase-plural)

    name: 'MyModel' #model = 'MyModel', route 'mymodels' (if generated)
  • schema: this is simply a mongoose schema

    schema:
      firstName: String
      lastName: String
      dob: Date

Additionally, there are several optional fields that can be set.

  • pre: If pre is set, pre itself is an object which can be used to set pre-hooks on the schema. Currently mongoose supports pre-hooks for save, remove, and validate. All pre-hooks are given a next function from mongoose which needs to be called on the conclusion of the user's function.

    pre:
      save: (next) !->
        console.log 'saving object'
        next!
      remove: (next) !->
        console.log 'removing object'
        next!
      validate: (next) !->
        console.log 'validating'
        next!
  • post: Similar to pre, but defines post hooks. Post-hooks also have save, remove and validate options. Post-hooks are not given a next function and do not need to call anything on completion.

    post:
      save: !-> console.log 'object saved'
      remove: !-> console.log 'object removed'
      validate: !-> console.log 'validated'
  • index: This field is an array of objects used to set indices that are not set on the schemas. This is especially useful for multi-field indices or coding styles that prefer to set all indices in one location.

    index:
      * lastName: 1
        firstName: 1
      ...
  • route: If the route field is set to false or not set, the model will be created but will not be a standalone route. This allows models to be created which will be sub-routes for another route and not routes themselves. If route is set to true, the model will be turned into a standalone route (i.e. no sub-routes). If route is set to an object, each sub-object will be used to create a sub-route. Route names will be determined by the name field in the object, converted to lowercase-plural. Sub-route names are determined by the keys of the route object.

    # standalone route
    route: true
    
    # route with sub-routes
    route:
      emails: #key defines how you want the subroute to be called from the client
        ref: \clientId #the attibute from the model which references the main model
        model: \email #the name of the model as defined in the name key of your object
      macros:
        ref: \client
        model: \clientMacro
  • cascade: If cascade is set to true. Livegoose will automatically generate a pre-remove hook which removes all documents in the sub-routes whose 'ref' field matches the _id of the document being removed.

    cascade: true

Mongoose Connections

When you require livegoose you are given a function. This function only returns the livegoose object when it is passed a mongoose instance. This allows users to create different livegoose models for different mongoose connections. For example.

#LiveScript

firstconn = mongoose.createConnection "..."
secondconn = mongoose.createConnection "different ..."
firstgoose = livegoose firstconn
secondgoose = livegoose secondconn
firstgoose.models = "./firstmodels"
firstgoose.url = "/firstapi"
secondgoose.models = "./secondmodel"
secondgoose.url = "/secondapi"

#some time later after app creation
firstgoose.render app
secondgoose.render app
// JavaScript

var firstconn, secondconn, firstgoose, secondgoose;
firstconn = mongoose.createConnection("...");
secondconn = mongoose.createConnection("different ...");
firstgoose = livegoose(firstconn);
secondgoose = livegoose(secondconn);
firstgoose.models = "./firstmodels";
firstgoose.url = "/firstapi";
secondgoose.models = "./secondmodel";
secondgoose.url = "/secondapi";

// some time later after app creation
firstgoose.render(app);
secondgoose.render(app);

Another advantage to setting up livegoose this way is that a user could choose to use a mongoose fork, or similar module, as long as it contained the same api, and livegoose will work correctly.