cruder

CRUD for express and mongoose.

cruder

CRUD for express and mongoose.

mongoose = require "mongoose"
express = require "express"
cruder = require "cruder"
 
db = mongoose.createConnection "mongodb://localhost/test"
 
UserSchema = new mongoose.Schema
  username: type: Stringrequired: true
  password: type: Stringrequired: true
 
User = db.model "users"UserSchema
 
app = express()
app.use express.bodyParser()
 
resource = cruder appdb
 
# first argument is model name or model class, second is resource options 
resource "users",
  collection:
    get:
      query: -> @Model.find().sort(username: 1)
 
app.listen 3000 if require.main is module

Default values here is pseudo-values used for understanding.

options =
  # Document field name used for Last-Modified header. 
  # If model has date field and this field updated on every change 
  # then you should use name of this field. 
  modificationTimeField: undefined
 
  # Express-like url pattern used for Location header. 
  # Url params replaced by document fields. 
  # Required if options.document.url is RegExp. 
  # Example behaviour: 
  # if options.locationUrl is "/:group/users/:_id" 
  # and doc._id is "777" 
  # and doc.group is "admins" 
  # then Location header is "/admins/users/777" 
  locationUrl: options.document.url
 
  # Whole collection actions. 
  collection:
    # Collection actions url. 
    # Can be express-like url pattern or RegExp. 
    url: "/" + Model.modelName
 
    # Url params definition using for model queries. 
    # Requied if options.collection.url is RegExp. 
    # Example behaviour: 
    # if options.collection.url is "/users/:paramName" 
    # and options.collection.params is {"paramName": "modelField"} 
    # then options.collection.get.query is 
    #   Model.find({modelField: req.params.paramName}) 
    params: /:([^\/]+)/g.exec options.collection.url
 
    # GET / 
    get:
      # Respond with 405 status if disabled. 
      _disabled: false
 
      # Model query. 
      # Can be factory function or query object. 
      # Can use @Model for access to resource model. 
      query: (req, res) ->
        Model.find()
 
      # Function used for state changes before sending response. 
      # Should return modified documents array. 
      beforeSending: (req, res, docs) ->
        docs
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res, docs) ->
 
    # POST / 
    post:
      # Respond with 405 status if disabled. 
      _disabled: false
 
      # New document factory function. 
      # Must return new document object. 
      factory: (req, res) ->
        new Model req.body
 
      # Function used for state changes before sending response. 
      # Should return modified document object. 
      beforeSending: (req, res, doc) ->
        doc
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res, doc) ->
 
    # PUT / 
    # Responds with 405 status. 
    put:
      # Function used for state changes before sending response. 
      beforeSending: (req, res) ->
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res) ->
 
    # DELETE / 
    delete:
      # Respond with 405 status if disabled. 
      _disabled: false
 
      # Model query. 
      # Can be factory function or query object. 
      # Can use @Model for access to resource model. 
      query: (req, res) ->
        Model.remove()
 
      # Function used for state changes before sending response. 
      beforeSending: (req, res) ->
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res) ->
 
  # One document actions. 
  document:
    # Document actions url. 
    # Can be express-like url pattern or RegExp. 
    url: "/" + Model.modelName + "/:id"
 
    # Url params definition using for model queries. 
    # Requied if options.document.url is RegExp. 
    # Example behaviour: 
    # if options.document.url is "/users/:id" 
    # and options.document.params is {"id": "_id"} 
    # then options.document.get.query is 
    #   Model.findOne({_id: req.params.id}) 
    params: /:([^\/]+)/g.exec options.document.url
 
    # GET /:id 
    get:
      # Respond with 405 status if disabled. 
      _disabled: false
 
      # Model query. 
      # Can be factory function or query object. 
      # Can use @Model for access to resource model. 
      query: (req, res) ->
        Model.findOne _id: req.params.id
 
      # Function used for state changes before sending response. 
      # Should return modified document. 
      beforeSending: (req, res, doc) ->
        doc
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res, doc) ->
 
    # POST /:id 
    # Responds with 405 status. 
    post:
      # Function used for state changes before sending response. 
      beforeSending: (req, res) ->
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res) ->
 
    # PUT /:id 
    put:
      # Respond with 405 status if disabled. 
      _disabled: false
 
      # Model query. 
      # Can be factory function or query object. 
      # Can use @Model for access to resource model. 
      query: (req, res) ->
        Model.findOne _id: req.params.id
 
      # Function used for state changes before saving document. 
      # Must return modified document. 
      beforeSaving: (req, res, doc) ->
        data = req.body
        delete data._id
        doc[key= value for keyvalue of data
        doc
 
      # Function used for state changes before sending response. 
      # Should return modified document. 
      beforeSending: (req, res, doc) ->
        doc
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res, doc) ->
 
    # DELETE /:id 
    delete:
      # Respond with 405 status if disabled. 
      _disabled: false
 
      # Model query. 
      # Can be factory function or query object. 
      # Can use @Model for access to resource model. 
      query: (req, res) ->
        Model.findOne _id: req.params.id
 
      # Function used for state changes before sending response. 
      beforeSending: (req, res) ->
 
      # Function used to perform actions after response is sent. 
      afterSending: (req, res) ->

Every controller emits event before calling beforeSaving, beforeSending, or afterSending. You can subscribe to events in four ways:

  1. Subscribe to event from all controllers:
resource("users").on "beforeSending"(req, res) ->
  res.set "Expires"new Date(Date.now() + 1000 * 60 * 60).toGMTString()
  1. Subscribe to event from collection or document controllers:

    resource("users").on "document:beforeSending"(req, res, doc) ->
      if doc
        res.set "X-Doc-Id"doc._id
  2. Subscribe to event from concrete method from collection and document controllers:

resource("users").on "get:afterSending"(req, res, data) ->
  console.log req.urldata
  1. Subscribe to event from concrete controller:
resource("users").on "post:collection:afterSending"(req, res, doc) ->
  console.log "Created new document"doc