<commit_before>function main(configuration) {
  var config = configuration;
  var util = require('./util.js').configure(config);
  var properties =
  [
    {
      "name": "direction",
      "expr": /direction/im,
      "action": function (prop, value) {
        return { 'prop': prop, 'value': util.swapLtrRtl(value) };
      }
    },
    {
      "name": "left",
      "expr": /left/im,
      "action": function (prop, value) {
        return { 'prop': prop.replace(this.expr, function () { return "right"; }), 'value': value };
      }
    },
    {
      "name": "right",
      "expr": /right/im,
      "action": function (prop, value) {
        return { 'prop': prop.replace(this.expr, function () { return "left"; }), 'value': value };
      }
    },
    {
      "name": "four-value syntax",
      "expr": /^(margin|padding|border-(color|style|width))$/ig,
      "match": /[^\s]+/g,
      "other": /hsl(a?)\(.*?\)|rgb(a?)\(.*?\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" + self.others.length });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp(\d+)/ig, function (m, i) { return self.others[i - 1]; });
      },
      "action": function (prop, value) {
        var newValue = this.saveOthers(value);
        var result = newValue.split(' ');
        if (result && result.length == 4 && (this.others.length > 0 || result[1] != result[3])) {
          var i = 0;
          newValue = newValue.replace(this.match, function () { return result[(4 - i++) % 4]; });
        }
        return { 'prop': prop, 'value': this.restoreOthers(newValue) };
      }
    },
    {
      "name": "border radius",
      "expr": /border-radius/ig,
      "match": /(\-?(\d*?\.\d+|\d+))(:?ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)?/ig,
      "flip": function (value) {
        var parts = value.match(this.match);
        var i;
        if (parts)
          switch (parts.length) {
            case 2:
              i = 1;
              if (parts[0] != parts[1])
                return value.replace(this.match, function () { return parts[i--]; });
              break;
            case 3:
              return parts[1] + ' ' + value;
            case 4:
              i = 0;
              if (parts[0] != parts[1] || parts[2] != parts[3])
                return value.replace(this.match, function () { return parts[(5 - i++) % 4]; });
          }
        return value;
      },
      "action": function (prop, value) {
        var parts = value.split("/");
        for (var x = 0; x < parts.length; x++)
          parts[x] = this.flip(parts[x]);
        return { 'prop': prop, 'value': parts.join("/") };
      }
    },
    {
      "name": "shadow",
      "expr": /shadow/ig,
      "replace": /(\-?(\d*?\.\d+|\d+))/i,
      "other": /hsl(a?)\(.*?\)|rgb(a?)\(.*?\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp/ig, function () { return self.others.shift(); });
      },
      "action": function (prop, value) {
        var parts = this.saveOthers(value).split(",");
        for (var x = 0; x < parts.length; x++)
          parts[x] = util.negate(parts[x]);
        return { 'prop': prop, 'value': this.restoreOthers(parts.join(",")) };
      }
    },
    {
      "name": "transform origin",
      "expr": /transform-origin/ig,
      "percent": /%/,
      "xKeyword": /(left|right)/i,
      "yKeyword": /(center|top|bottom)/i,
      "match": /(\-?(\d*?\.\d+|\d+)%)|(\-?(\d*?\.\d+|\d+))(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?/g,
      "flip": function (value) {
        if (value == "0")
          return "100%";
        else if (value.match(this.percent))
          return util.complement(value);
        return value;
      },
      "action": function (prop, value) {
        var newValue = value;
        if (value.match(this.xKeyword))
          newValue = util.swapLeftRight(value);
        else {
          var parts = value.match(this.match);
          if (parts && parts.length > 0) {
            parts[0] = this.flip(parts[0]);
            newValue = value.replace(this.match, function () { return parts.shift(); })
          }
        }
        return { 'prop': prop, 'value': newValue };
      }
    },
    {
      "name": "transform",
      "expr": /^(?!text\-).*?transform$/ig,
      "match": /((translate)(x|3d)?|skew(x|y)?|rotate(z|3d)?|matrix(3d)?)\((.|\s)*?\)/ig,
      "matrix": /matrix\(/i,
      "flipMatrix": function (value) {
        var i = 0;
        return value.replace(/(\-?(\d*?\.\d+|\d+))/ig, function (num) {
          if (++i == 2 || i == 3 || i == 5)
            return parseFloat(num, 10) * -1;
          return num
        });
      },
      "matrix3D": /matrix3d\(/i,
      "flipMatrix3D": function(value){
        var i = 0;
        return value.replace(/(\-?(\d*?\.\d+|\d+))(?!d\()/ig, function (num) {
          if (++i == 2 || i == 4 || i == 5 || i == 13)
            return parseFloat(num, 10) * -1;
          return num
        });
      },
      "rotate3D": /rotate3d\(/i,
      "flipRotate3D": function (value) {
        var i = 0;
        return value.replace(/(\-?(\d*?\.\d+|\d+))(?!d\()/ig, function (num) {
          if (++i == 2 || i == 4)
            return parseFloat(num, 10) * -1;
          return num
        });
      },
      "skewXY": /skew(x|y)?/i,
      "action": function (prop, value) {
        var parts = value.match(this.match);
        for (var x = 0; parts && x < parts.length; x++) {
          if (parts[x].match(this.matrix3D))
            parts[x] = this.flipMatrix3D(parts[x]);
          else if (parts[x].match(this.matrix))
            parts[x] = this.flipMatrix(parts[x]);
          else if (parts[x].match(this.rotate3D))
            parts[x] = this.flipRotate3D(parts[x]);
          else if (parts[x].match(this.skewXY))
            parts[x] = util.negateAll(parts[x]);
          else
            parts[x] = util.negate(parts[x]);
        }
        return { 'prop': prop, 'value': value.replace(this.match, function () { return parts.shift(); }) };
      }
    },
    {
      "name": "transition",
      "expr": /transition(-property)?$/i,
      "action": function (prop, value) {
        return { 'prop': prop, 'value':  util.swapLeftRight(value)};
      }
    },
    {
      "name": "background",
      "expr": /background(-position(-x)?|-image)?$/i,
      "match": /left|center|right|top|bottom|(?:\-?(?:\d*?\.\d+|\d+)%)|(?:\-?(?:\d*?\.\d+|\d+))(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?/i,
      "percent": /%/,
      "other": /url\([^]*?\)|#[0-9a-f]{3,6}|hsl(a?)\([^]*?\)|rgb(a?)\([^]*?\)|color-stop\([^]*?\)|\b.*?gradient\([^]*\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp/ig, function () {
          var item = self.others.shift();
          if (item.match(/.*?gradient/)) {
            item = util.swapLeftRight(item);
            if (item.match(/\d+(deg|g?rad|turn)/i))
              item = util.negate(item);
          }
          else if (item.match(/^url/i)) {
            item = util.applyStringMap(item, false, true);
          }

          return item;
        });
      },
      "flip": function (value) {
        var parts = value.match(this.match);
        if (parts && parts.length > 0) {
          parts[0] = parts[0] == "0" ? "100%" : (parts[0].match(this.percent) ? util.complement(parts[0]) : util.swapLeftRight(parts[0]));
          return value.replace(this.match, function () { return parts.shift(); });
        }
        return value;
      },
      "action": function (prop, value) {
        var newValue = this.saveOthers(value);
        var parts = newValue.split(",");
        if (prop.toLowerCase() != "background-image")
          for (var x = 0; x < parts.length; x++)
            parts[x] = this.flip(parts[x]);
        newValue = this.restoreOthers(parts.join(","));
        return { 'prop': prop, 'value': newValue };
      }
    },
    {
      "name": "keyword",
      "expr": /float|clear|text-align/i,
      "action": function (prop, value) {
        return { 'prop': prop, 'value': util.swapLeftRight(value) };
      }
    },
    {
      "name": "cursor",
      "expr": /cursor/i,
      "match": /(?:\-?(?:\d*?\.\d+|\d+))|(?:\-?(?:\d*?\.\d+|\d+))(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?/i,
      "replace": /\b([news]{1,4})-resize/ig,
      "other": /url\(.*?\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp/ig, function () {

          var item = self.others.shift();

          if (item.match(/^url/i)) {
            item = util.applyStringMap(item, false, true);
          }

          return item;
        });
      },
      "flip": function (value) {
        return value.replace(this.replace, function (s, m) { return s.replace(m, m.replace(/e/i, "*").replace(/w/i, "e").replace(/\*/i, "w")); });
      },
      "action": function (prop, value) {
        var newValue = this.saveOthers(value);
        var parts = newValue.split(",");
        for (var x = 0; x < parts.length; x++)
          parts[x] = this.flip(parts[x]);
        newValue = this.restoreOthers(parts.join(","));
        return { 'prop': prop, 'value': newValue };
      }
    }
  ];
  return properties;
}
module.exports.configure = main;
<commit_msg>Remove unused variable<commit_after>function main(configuration) {
  var config = configuration;
  var util = require('./util.js').configure(config);
  var properties =
  [
    {
      "name": "direction",
      "expr": /direction/im,
      "action": function (prop, value) {
        return { 'prop': prop, 'value': util.swapLtrRtl(value) };
      }
    },
    {
      "name": "left",
      "expr": /left/im,
      "action": function (prop, value) {
        return { 'prop': prop.replace(this.expr, function () { return "right"; }), 'value': value };
      }
    },
    {
      "name": "right",
      "expr": /right/im,
      "action": function (prop, value) {
        return { 'prop': prop.replace(this.expr, function () { return "left"; }), 'value': value };
      }
    },
    {
      "name": "four-value syntax",
      "expr": /^(margin|padding|border-(color|style|width))$/ig,
      "match": /[^\s]+/g,
      "other": /hsl(a?)\(.*?\)|rgb(a?)\(.*?\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" + self.others.length });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp(\d+)/ig, function (m, i) { return self.others[i - 1]; });
      },
      "action": function (prop, value) {
        var newValue = this.saveOthers(value);
        var result = newValue.split(' ');
        if (result && result.length == 4 && (this.others.length > 0 || result[1] != result[3])) {
          var i = 0;
          newValue = newValue.replace(this.match, function () { return result[(4 - i++) % 4]; });
        }
        return { 'prop': prop, 'value': this.restoreOthers(newValue) };
      }
    },
    {
      "name": "border radius",
      "expr": /border-radius/ig,
      "match": /(\-?(\d*?\.\d+|\d+))(:?ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc|%)?/ig,
      "flip": function (value) {
        var parts = value.match(this.match);
        var i;
        if (parts)
          switch (parts.length) {
            case 2:
              i = 1;
              if (parts[0] != parts[1])
                return value.replace(this.match, function () { return parts[i--]; });
              break;
            case 3:
              return parts[1] + ' ' + value;
            case 4:
              i = 0;
              if (parts[0] != parts[1] || parts[2] != parts[3])
                return value.replace(this.match, function () { return parts[(5 - i++) % 4]; });
          }
        return value;
      },
      "action": function (prop, value) {
        var parts = value.split("/");
        for (var x = 0; x < parts.length; x++)
          parts[x] = this.flip(parts[x]);
        return { 'prop': prop, 'value': parts.join("/") };
      }
    },
    {
      "name": "shadow",
      "expr": /shadow/ig,
      "replace": /(\-?(\d*?\.\d+|\d+))/i,
      "other": /hsl(a?)\(.*?\)|rgb(a?)\(.*?\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp/ig, function () { return self.others.shift(); });
      },
      "action": function (prop, value) {
        var parts = this.saveOthers(value).split(",");
        for (var x = 0; x < parts.length; x++)
          parts[x] = util.negate(parts[x]);
        return { 'prop': prop, 'value': this.restoreOthers(parts.join(",")) };
      }
    },
    {
      "name": "transform origin",
      "expr": /transform-origin/ig,
      "percent": /%/,
      "xKeyword": /(left|right)/i,
      "yKeyword": /(center|top|bottom)/i,
      "match": /(\-?(\d*?\.\d+|\d+)%)|(\-?(\d*?\.\d+|\d+))(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?/g,
      "flip": function (value) {
        if (value == "0")
          return "100%";
        else if (value.match(this.percent))
          return util.complement(value);
        return value;
      },
      "action": function (prop, value) {
        var newValue = value;
        if (value.match(this.xKeyword))
          newValue = util.swapLeftRight(value);
        else {
          var parts = value.match(this.match);
          if (parts && parts.length > 0) {
            parts[0] = this.flip(parts[0]);
            newValue = value.replace(this.match, function () { return parts.shift(); })
          }
        }
        return { 'prop': prop, 'value': newValue };
      }
    },
    {
      "name": "transform",
      "expr": /^(?!text\-).*?transform$/ig,
      "match": /((translate)(x|3d)?|skew(x|y)?|rotate(z|3d)?|matrix(3d)?)\((.|\s)*?\)/ig,
      "matrix": /matrix\(/i,
      "flipMatrix": function (value) {
        var i = 0;
        return value.replace(/(\-?(\d*?\.\d+|\d+))/ig, function (num) {
          if (++i == 2 || i == 3 || i == 5)
            return parseFloat(num, 10) * -1;
          return num
        });
      },
      "matrix3D": /matrix3d\(/i,
      "flipMatrix3D": function(value){
        var i = 0;
        return value.replace(/(\-?(\d*?\.\d+|\d+))(?!d\()/ig, function (num) {
          if (++i == 2 || i == 4 || i == 5 || i == 13)
            return parseFloat(num, 10) * -1;
          return num
        });
      },
      "rotate3D": /rotate3d\(/i,
      "flipRotate3D": function (value) {
        var i = 0;
        return value.replace(/(\-?(\d*?\.\d+|\d+))(?!d\()/ig, function (num) {
          if (++i == 2 || i == 4)
            return parseFloat(num, 10) * -1;
          return num
        });
      },
      "skewXY": /skew(x|y)?/i,
      "action": function (prop, value) {
        var parts = value.match(this.match);
        for (var x = 0; parts && x < parts.length; x++) {
          if (parts[x].match(this.matrix3D))
            parts[x] = this.flipMatrix3D(parts[x]);
          else if (parts[x].match(this.matrix))
            parts[x] = this.flipMatrix(parts[x]);
          else if (parts[x].match(this.rotate3D))
            parts[x] = this.flipRotate3D(parts[x]);
          else if (parts[x].match(this.skewXY))
            parts[x] = util.negateAll(parts[x]);
          else
            parts[x] = util.negate(parts[x]);
        }
        return { 'prop': prop, 'value': value.replace(this.match, function () { return parts.shift(); }) };
      }
    },
    {
      "name": "transition",
      "expr": /transition(-property)?$/i,
      "action": function (prop, value) {
        return { 'prop': prop, 'value':  util.swapLeftRight(value)};
      }
    },
    {
      "name": "background",
      "expr": /background(-position(-x)?|-image)?$/i,
      "match": /left|center|right|top|bottom|(?:\-?(?:\d*?\.\d+|\d+)%)|(?:\-?(?:\d*?\.\d+|\d+))(?:ex|ch|r?em|vh|vw|vmin|vmax|px|mm|cm|in|pt|pc)?/i,
      "percent": /%/,
      "other": /url\([^]*?\)|#[0-9a-f]{3,6}|hsl(a?)\([^]*?\)|rgb(a?)\([^]*?\)|color-stop\([^]*?\)|\b.*?gradient\([^]*\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp/ig, function () {
          var item = self.others.shift();
          if (item.match(/.*?gradient/)) {
            item = util.swapLeftRight(item);
            if (item.match(/\d+(deg|g?rad|turn)/i))
              item = util.negate(item);
          }
          else if (item.match(/^url/i)) {
            item = util.applyStringMap(item, false, true);
          }

          return item;
        });
      },
      "flip": function (value) {
        var parts = value.match(this.match);
        if (parts && parts.length > 0) {
          parts[0] = parts[0] == "0" ? "100%" : (parts[0].match(this.percent) ? util.complement(parts[0]) : util.swapLeftRight(parts[0]));
          return value.replace(this.match, function () { return parts.shift(); });
        }
        return value;
      },
      "action": function (prop, value) {
        var newValue = this.saveOthers(value);
        var parts = newValue.split(",");
        if (prop.toLowerCase() != "background-image")
          for (var x = 0; x < parts.length; x++)
            parts[x] = this.flip(parts[x]);
        newValue = this.restoreOthers(parts.join(","));
        return { 'prop': prop, 'value': newValue };
      }
    },
    {
      "name": "keyword",
      "expr": /float|clear|text-align/i,
      "action": function (prop, value) {
        return { 'prop': prop, 'value': util.swapLeftRight(value) };
      }
    },
    {
      "name": "cursor",
      "expr": /cursor/i,
      "replace": /\b([news]{1,4})-resize/ig,
      "other": /url\(.*?\)/ig,
      "others": [],
      "saveOthers": function (value) {
        var self = this;
        return value.replace(this.other, function (m) { self.others.push(m); return "temp" });
      },
      "restoreOthers": function (value) {
        var self = this;
        return value.replace(/temp/ig, function () {

          var item = self.others.shift();

          if (item.match(/^url/i)) {
            item = util.applyStringMap(item, false, true);
          }

          return item;
        });
      },
      "flip": function (value) {
        return value.replace(this.replace, function (s, m) { return s.replace(m, m.replace(/e/i, "*").replace(/w/i, "e").replace(/\*/i, "w")); });
      },
      "action": function (prop, value) {
        var newValue = this.saveOthers(value);
        var parts = newValue.split(",");
        for (var x = 0; x < parts.length; x++)
          parts[x] = this.flip(parts[x]);
        newValue = this.restoreOthers(parts.join(","));
        return { 'prop': prop, 'value': newValue };
      }
    }
  ];
  return properties;
}
module.exports.configure = main;
<|endoftext|>


<commit_before>/*
This file gives functions to the CIF setup page.
*/

var lineupForm = "https://cdn.rawgit.com/ginshmastc/Volleyball-Bookkeeper/master/HTML/Lineups6p1l.html";

function onStart()
{

}

function lineups()
{
    var saved = [];
    saved[0] = document.getElementById('teamA').value + "";
    saved[1] = document.getElementById('teamB').value + "";
    saved[2] = document.getElementById('sets').value + "";
    saved[3] = document.getElementById('playTo').value + "";
    saved[4] = document.getElementById('cap').value + "";

    if(Android != null)
    {
        Android.addData(saved);
        loadURL(lineupForm);
    }
}

<commit_msg>Update CIF_Setup1.6.js<commit_after>/*
This file gives functions to the CIF setup page.
*/

var lineupForm = "https://cdn.rawgit.com/ginshmastc/Volleyball-Bookkeeper/master/HTML/Lineups6p1l.html";

function onStart()
{
    test("onstart");
}

function lineups()
{
    var saved = [];
    saved[0] = document.getElementById('teamA').value + "";
    saved[1] = document.getElementById('teamB').value + "";
    saved[2] = document.getElementById('sets').value + "";
    saved[3] = document.getElementById('playTo').value + "";
    saved[4] = document.getElementById('cap').value + "";

    if(Android != null)
    {
        Android.addData(saved);
        loadURL(lineupForm);
    }
}

<|endoftext|>


<commit_before>// filter for use with Connect
var exports = module.exports = function(){
    return function(req, res, next){
        exports.update(res);
        next();
    };
};

exports.update = function(res){

    ///// default response settings /////
    res._quip_headers = {'Content-Type': 'text/html'};
    res._quip_status = 200;

    ///// private helper methods /////
    var withStatus = function(code){
        return function(data){
            return data ? res.status(code).send(data):
                          res.status(code);
        };
    };
    var redirection = function(code, message){
        return function(loc){
            res._quip_headers.Location = loc;
            return res.status(code).send(
                '' +
                    '' +
                        '<title>' + code + ' ' + message + '</title>' +
                    '' +
                    '' +
                        '
' +
                            message + ': ' +
                            '' + loc + '' +
                        '
' +
                    '' +
                ''
            );
        };
    }
    var withType = function(type){
        return function(data){
            res.headers({'Content-Type': type});
            return data ? res.send(data): res;
        }
    };

    ///// exported methods /////
    res.status = function(code){
        res._quip_status = code;
        return res;
    };
    res.headers = function(headers){
        for(var k in headers) res._quip_headers[k] = headers[k];
        return res;
    };

    // success
    res.ok = withStatus(200);
    res.created = withStatus(201);
    res.accepted = withStatus(202);

    // redirection
    res.moved = redirection(301, 'Moved Permanently');
    res.redirect = redirection(302, 'Found');
    res.found = res.redirect;
    res.notModified = function(){res.status(304).send();};

    // client error
    res.badRequest = withStatus(400);
    res.unauthorized = withStatus(401);
    res.forbidden = withStatus(403);
    res.notFound = withStatus(404);
    res.notAllowed = withStatus(405);
    res.conflict = withStatus(409);
    res.gone = withStatus(410);

    // server error
    res.error = withStatus(500, 'error');

    // mime types
    res.text = withType('text/plain');
    res.plain = res.text;
    res.html = withType('text/html');
    res.xhtml = withType('application/xhtml+xml');
    res.css = withType('text/css');
    res.xml = withType('text/xml');
    res.atom = withType('application/atom+xml');
    res.rss = withType('application/rss+xml');
    res.javascript = withType('text/javascript');
    res.json = withType('application/json');

    // JSONP is a special case that should always respond with a 200,
    // there is no reliable way to reveive a JSONP result on the
    // client-side if the HTTP status-code is not 200!
    res.jsonp = function(callback, data){
        if(typeof data == 'object') data = JSON.stringify(data);
        data = callback + '(' + data + ');';
        return res.ok().javascript(data);
    };

    // respond with given data using current header and status code
    res.send = function(data){
        if(res._quip_headers['Content-Type'] == 'application/json'){
            if(typeof data == 'object') data = JSON.stringify(data);
        }
        res.writeHead(res._quip_status, res._quip_headers);
        if(data) res.write(data);
        res.end();
        return null;
    };

    return res;

};
<commit_msg>Added Content-Length header<commit_after>// filter for use with Connect
var exports = module.exports = function(){
    return function(req, res, next){
        exports.update(res);
        next();
    };
};

exports.update = function(res){

    ///// default response settings /////
    res._quip_headers = {'Content-Type': 'text/html'};
    res._quip_status = 200;

    ///// private helper methods /////
    var withStatus = function(code){
        return function(data){
            return data ? res.status(code).send(data):
                          res.status(code);
        };
    };
    var redirection = function(code, message){
        return function(loc){
            res._quip_headers.Location = loc;
            return res.status(code).send(
                '' +
                    '' +
                        '<title>' + code + ' ' + message + '</title>' +
                    '' +
                    '' +
                        '
' +
                            message + ': ' +
                            '' + loc + '' +
                        '
' +
                    '' +
                ''
            );
        };
    }
    var withType = function(type){
        return function(data){
            res.headers({'Content-Type': type});
            return data ? res.send(data): res;
        }
    };

    ///// exported methods /////
    res.status = function(code){
        res._quip_status = code;
        return res;
    };
    res.headers = function(headers){
        for(var k in headers) res._quip_headers[k] = headers[k];
        return res;
    };

    // success
    res.ok = withStatus(200);
    res.created = withStatus(201);
    res.accepted = withStatus(202);

    // redirection
    res.moved = redirection(301, 'Moved Permanently');
    res.redirect = redirection(302, 'Found');
    res.found = res.redirect;
    res.notModified = function(){res.status(304).send();};

    // client error
    res.badRequest = withStatus(400);
    res.unauthorized = withStatus(401);
    res.forbidden = withStatus(403);
    res.notFound = withStatus(404);
    res.notAllowed = withStatus(405);
    res.conflict = withStatus(409);
    res.gone = withStatus(410);

    // server error
    res.error = withStatus(500, 'error');

    // mime types
    res.text = withType('text/plain');
    res.plain = res.text;
    res.html = withType('text/html');
    res.xhtml = withType('application/xhtml+xml');
    res.css = withType('text/css');
    res.xml = withType('text/xml');
    res.atom = withType('application/atom+xml');
    res.rss = withType('application/rss+xml');
    res.javascript = withType('text/javascript');
    res.json = withType('application/json');

    // JSONP is a special case that should always respond with a 200,
    // there is no reliable way to reveive a JSONP result on the
    // client-side if the HTTP status-code is not 200!
    res.jsonp = function(callback, data){
        if(typeof data == 'object') data = JSON.stringify(data);
        data = callback + '(' + data + ');';
        return res.ok().javascript(data);
    };

    // respond with given data using current header and status code
    res.send = function(data){
        if(res._quip_headers['Content-Type'] == 'application/json'){
            if(typeof data == 'object') data = JSON.stringify(data);
        }
        if(data) {
            res._quip_headers['Content-Length'] = Buffer.byteLength(data);
        }
        res.writeHead(res._quip_status, res._quip_headers);
        if(data) res.write(data);
        res.end();
        return null;
    };

    return res;

};
<|endoftext|>


<commit_before>const configStreamingService = config => speeech => () => {
  const speechService = require("@google-cloud/speech").v1(config.auth);
  const recognizeStream = speechService.streamingRecognize(config.streaming);

  recognizeStream.on("data", data => {
    if (data.results && data.results[0] && data.results[0].isFinal === true) {
      const result = data.results[0].alternatives[0].transcript;
      speeech.mic.unpipe(recognizeStream);
      speeech.emit("result", result);
    }
  });

  speeech.mic.pipe(recognizeStream);
};

module.exports = configStreamingService;
<commit_msg>fix google service for 65 sec error<commit_after>const configStreamingService = config => speeech => () => {
  const speechService = require("@google-cloud/speech").v1(config.auth);
  const recognizeStream = speechService.streamingRecognize(config.streaming);

  recognizeStream.on("data", data => {
    if (data.results[0] && data.results[0].isFinal === true) {
      const result = data.results[0].alternatives[0].transcript;
      speeech.mic.unpipe(recognizeStream);
      speeech.emit("result", result);
      recognizeStream.end();
    }
  });

  speeech.mic.pipe(recognizeStream);
};

module.exports = configStreamingService;
<|endoftext|>


<commit_before>(function(DOM, location, history) {
    "use strict";

    var I18N_ERROR_TIMEOUT = "ajaxify-timeout",
        I18N_ERROR_UNKNOWN = "ajaxify-unknown",
        // internal data structures
        containers = DOM.findAll("[data-ajaxify=on]"),
        containersCache = {},
        // helpers
        switchContent = (function() {
            var currentLocation = location.href.split("#")[0];

            return function(url, title, data) {
                var cacheEntry = {};

                containers.each(function(el, index) {
                    var id = el.get("id"),
                        value = data[id];

                    if (typeof value === "string") {
                        value = el.clone().set(value);
                    }

                    cacheEntry[id] = el.replace(value);
                    // update value in the internal collection
                    containers[index] = value;
                });
                // update old containers to their latest state
                containersCache[currentLocation] = cacheEntry;
                // update current location variable
                currentLocation = url;
                // update page title
                DOM.setTitle(title);
            };
        }()),
        loadContent = (function() {
            // lock element to prevent double clicks
            var lockedEl, xhr, timerId;

            return function(sender, url, data) {
                if (lockedEl !== sender) {
                    lockedEl = sender;

                    if (xhr) {
                        xhr.abort(); // abort previous request if it's still in progress

                        clearTimeout(timerId);
                    }

                    xhr = new XMLHttpRequest();

                    timerId = setTimeout(function() {
                        xhr.abort();

                        sender.fire("ajaxify:error", I18N_ERROR_TIMEOUT);
                    }, 15000);

                    xhr.onerror = function() {
                        sender.fire("ajaxify:error", I18N_ERROR_UNKNOWN);
                    };

                    xhr.onreadystatechange = function() {
                        if (xhr.readyState === 4) {
                            var status = xhr.status,
                                response = xhr.responseText;

                            sender.fire("ajaxify:loadend", xhr);

                            if (status > 0) {
                                // try to parse response
                                try {
                                    response = JSON.parse(response);
                                    response.url = response.url || url;
                                } catch(err) {
                                    // response is a text content
                                }
                            }

                            if (status >= 200 && status < 300 || status === 304) {
                                sender.fire("ajaxify:success", response);
                            } else {
                                sender.fire("ajaxify:error", response);
                            }

                            clearTimeout(timerId);

                            xhr = null; // memory cleanup
                        }
                    };

                    xhr.open(data ? "POST" : "GET", data ? url : (url + (~url.indexOf("?") ? "&" : "?") + new Date().getTime()), true);
                    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

                    if (data) xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

                    sender.fire("ajaxify:loadstart", xhr);

                    xhr.send(data);
                }
            };
        }()),
        makePair = function(name, value) {
            return encodeURIComponent(name) + "=" + encodeURIComponent(value);
        };

    if (containers.some(function(el) { return !el.get("id") })) {
        throw "Each [data-ajaxify=on] element must have unique id attribute";
    }

    // use mousedown/touchstart for faster ajax request
    DOM.on((DOM.supports("ontouchstart") ? "touchstart": "click") + " a", function(link, cancel) {
        if (!link.matches("a")) link = link.parent("a");

        if (!cancel && !link.get("target")) {
            var url = link.get("href");

            if (!url) return;

            url = url.split("#")[0];

            if (url !== location.href.split("#")[0]) {
                loadContent(link, url);
                // prevent default behavior for links
                return false;
            }
        }
    });

    DOM.on("submit", function(form, cancel) {
        if (!cancel && !form.get("target")) {
            var url = form.get("action"),
                queryString = form.toQueryString();

            if (form.get("method") === "get") {
                url += (~url.indexOf("?") ? "&" : "?") + queryString;
                queryString = null;
            }

            loadContent(form, url, queryString);

            return false;
        }
    });

    DOM.on("ajaxify:success", ["detail"], function(response) {
        if (typeof response === "object") {
            switchContent(response.url, response.title, response.html);
            // update browser url
            if (response.url !== location.pathname) {
                history.pushState({title: DOM.getTitle()}, DOM.getTitle(), response.url);
            } else if (history.replaceState) {
                history.replaceState({title: DOM.getTitle()}, DOM.getTitle());
            }
        }
    });

    if (history.pushState) {
        window.addEventListener("popstate", function(e) {
            var url = location.href.split("#")[0],
                state = e.state;

            if (!state) return;

            if (url in containersCache) {
                switchContent(url, state.title, containersCache[url]);
            } else {
                // TODO: need to trigger partial reload?
                location.reload();
            }
        }, false);
        // update initial state
        history.replaceState({title: DOM.getTitle()}, DOM.getTitle());
    } else {
        // when url should be changed don't start request in old browsers
        DOM.on("ajaxify:loadstart", ["target", "defaultPrevented"], function(sender, defaultPrevented) {
            if (!defaultPrevented && sender.get("method") !== "post") {
                // load a new page in legacy browsers
                if (sender.matches("form")) {
                    sender.fire("submit");
                } else {
                    location.href = sender.get("href");
                }
            }
        });
    }

    DOM.extend("input,select,textarea", {
        toQueryString: function() {
            var name = this.get("name"),
                result = [];

            if (name) { // don't include form fields without names
                switch(this.get("type")) {
                case "select-one":
                case "select-multiple":
                    this.get("options").each(function(option) {
                        if (option.get("selected")) {
                            result.push(makePair(name, option.get()));
                        }
                    });
                    break;

                case "file": // file input
                case "submit": // submit button
                case "reset": // reset button
                case "button": // custom button
                    break;

                case "radio": // radio button
                case "checkbox": // checkbox
                    if (!this.get("checked")) break;
                    /* falls through */
                default:
                    result.push(makePair(name, this.get()));
                }
            }

            return result.join("&").replace(/%20/g, "+");
        }
    });

    DOM.extend("form,fieldset", {
        toQueryString: function() {
            return this.get("elements").reduce(function(memo, el) {
                if (el.toQueryString && !el.matches("fieldset")) {
                    var str = el.toQueryString();

                    if (str) memo += (memo ? "&" : "") + str;
                }

                return memo;
            }, "");
        }
    });

    if (typeof define === "function" && define.amd) {
        define("better-ajaxify", ["better-dom"], function() {});
    }
}(window.DOM, location, history));
<commit_msg>introduce ajaxify:abort, drop error constants, improve ajaxify:error<commit_after>(function(DOM, location, history) {
    "use strict";

    var // internal data structures
        containers = DOM.findAll("[data-ajaxify=on]"),
        containersCache = {},
        // helpers
        switchContent = (function() {
            var currentLocation = location.href.split("#")[0];

            return function(url, title, data) {
                var cacheEntry = {};

                containers.each(function(el, index) {
                    var id = el.get("id"),
                        value = data[id];

                    if (typeof value === "string") {
                        value = el.clone().set(value);
                    }

                    cacheEntry[id] = el.replace(value);
                    // update value in the internal collection
                    containers[index] = value;
                });
                // update old containers to their latest state
                containersCache[currentLocation] = cacheEntry;
                // update current location variable
                currentLocation = url;
                // update page title
                DOM.setTitle(title);
            };
        }()),
        loadContent = (function() {
            // lock element to prevent double clicks
            var lockedEl, xhr, timerId;

            return function(sender, url, data) {
                if (lockedEl !== sender) {
                    lockedEl = sender;

                    if (xhr) {
                        xhr.abort(); // abort previous request if it's still in progress

                        clearTimeout(timerId);
                    }

                    xhr = new XMLHttpRequest();

                    timerId = setTimeout(function() {
                        xhr.abort();

                        sender.fire("ajaxify:abort", xhr);
                    }, 15000);

                    xhr.onerror = function() {
                        sender.fire("ajaxify:error", xhr);
                    };

                    xhr.onreadystatechange = function() {
                        if (xhr.readyState === 4) {
                            var status = xhr.status,
                                response = xhr.responseText;

                            sender.fire("ajaxify:loadend", xhr);

                            if (status >= 200 && status < 300 || status === 304) {
                                try {
                                    response = JSON.parse(response);
                                    response.url = response.url || url;
                                } catch(err) {
                                    // response is a text content
                                } finally {
                                    sender.fire("ajaxify:success", response);
                                }
                            } else {
                                sender.fire("ajaxify:error", xhr);
                            }

                            clearTimeout(timerId);

                            xhr = null; // memory cleanup
                        }
                    };

                    xhr.open(data ? "POST" : "GET", data ? url : (url + (~url.indexOf("?") ? "&" : "?") + new Date().getTime()), true);
                    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

                    if (data) xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

                    sender.fire("ajaxify:loadstart", xhr);

                    xhr.send(data);
                }
            };
        }()),
        makePair = function(name, value) {
            return encodeURIComponent(name) + "=" + encodeURIComponent(value);
        };

    if (containers.some(function(el) { return !el.get("id") })) {
        throw "Each [data-ajaxify=on] element must have unique id attribute";
    }

    // use mousedown/touchstart for faster ajax request
    DOM.on((DOM.supports("ontouchstart") ? "touchstart": "click") + " a", function(link, cancel) {
        if (!link.matches("a")) link = link.parent("a");

        if (!cancel && !link.get("target")) {
            var url = link.get("href");

            if (!url) return;

            url = url.split("#")[0];

            if (url !== location.href.split("#")[0]) {
                loadContent(link, url);
                // prevent default behavior for links
                return false;
            }
        }
    });

    DOM.on("submit", function(form, cancel) {
        if (!cancel && !form.get("target")) {
            var url = form.get("action"),
                queryString = form.toQueryString();

            if (form.get("method") === "get") {
                url += (~url.indexOf("?") ? "&" : "?") + queryString;
                queryString = null;
            }

            loadContent(form, url, queryString);

            return false;
        }
    });

    DOM.on("ajaxify:success", ["detail"], function(response) {
        if (typeof response === "object") {
            switchContent(response.url, response.title, response.html);
            // update browser url
            if (response.url !== location.pathname) {
                history.pushState({title: DOM.getTitle()}, DOM.getTitle(), response.url);
            } else if (history.replaceState) {
                history.replaceState({title: DOM.getTitle()}, DOM.getTitle());
            }
        }
    });

    if (history.pushState) {
        window.addEventListener("popstate", function(e) {
            var url = location.href.split("#")[0],
                state = e.state;

            if (!state) return;

            if (url in containersCache) {
                switchContent(url, state.title, containersCache[url]);
            } else {
                // TODO: need to trigger partial reload?
                location.reload();
            }
        }, false);
        // update initial state
        history.replaceState({title: DOM.getTitle()}, DOM.getTitle());
    } else {
        // when url should be changed don't start request in old browsers
        DOM.on("ajaxify:loadstart", ["target", "defaultPrevented"], function(sender, defaultPrevented) {
            if (!defaultPrevented && sender.get("method") !== "post") {
                // load a new page in legacy browsers
                if (sender.matches("form")) {
                    sender.fire("submit");
                } else {
                    location.href = sender.get("href");
                }
            }
        });
    }

    DOM.extend("input,select,textarea", {
        toQueryString: function() {
            var name = this.get("name"),
                result = [];

            if (name) { // don't include form fields without names
                switch(this.get("type")) {
                case "select-one":
                case "select-multiple":
                    this.get("options").each(function(option) {
                        if (option.get("selected")) {
                            result.push(makePair(name, option.get()));
                        }
                    });
                    break;

                case "file": // file input
                case "submit": // submit button
                case "reset": // reset button
                case "button": // custom button
                    break;

                case "radio": // radio button
                case "checkbox": // checkbox
                    if (!this.get("checked")) break;
                    /* falls through */
                default:
                    result.push(makePair(name, this.get()));
                }
            }

            return result.join("&").replace(/%20/g, "+");
        }
    });

    DOM.extend("form,fieldset", {
        toQueryString: function() {
            return this.get("elements").reduce(function(memo, el) {
                if (el.toQueryString && !el.matches("fieldset")) {
                    var str = el.toQueryString();

                    if (str) memo += (memo ? "&" : "") + str;
                }

                return memo;
            }, "");
        }
    });

    if (typeof define === "function" && define.amd) {
        define("better-ajaxify", ["better-dom"], function() {});
    }
}(window.DOM, location, history));
<|endoftext|>


<commit_before>'use strict';
const database = require(__dirname + '/database.js');

const readAll = (collection, options) => {
  let limit, sort, filter = {}, single = false;
  if(options) {
    limit = options.limit; // TODO should only accept numbers
    sort = options.sort;
    filter = options.filter ? options.filter : {};
    single = options.single ? options.single : false;
  }
  return new Promise((resolve, reject) => {
    database.connect()
      .then((db) => {
        return db.collection(collection).find(filter);
      })
      .then((cursor) => {
        return limit ? cursor.limit(limit) : cursor;
      })
      .then((cursor) => {
        return sort ? cursor.sort(sort) : cursor;
      })
      .then((cursor) => {
        return cursor.toArray();
      })
      .then((data) => {
        if(!single) {
          resolve(data);
        }
        else {
          if(data.length === 0) {
            reject(new Error("not found"))
          }
          else {
            resolve(data[0]);
          }
        }

      })
      .catch((err) => {
        reject(err);
      });
  });
};

const readOne = (collection, options) => {
  if(!options)
    options = {};
  options.limit = 1;
  options.single = true;
  return readAll(collection, options);
};

const readOneById = (collection, id) => {
  const options = {
    limit : 1,
    filter: {_id:id}
  }
  return readAll(collection, options);
}

// exports
module.exports.readAll = readAll;
module.exports.readOne = readOne;
module.exports.readOneById = readOneById;

<commit_msg>code clean-up<commit_after>'use strict'
const database = require(__dirname + '/database.js')

const readAll = (collection, options) => {
  let limit, sort, filter = {}, single = false
  if(options) {
    limit = options.limit; // TODO should only accept numbers
    sort = options.sort;
    filter = options.filter ? options.filter : {};
    single = options.single ? options.single : false;
  }
  return new Promise((resolve, reject) => {
    database.connect()
      .then((db) => {
        return db.collection(collection).find(filter)
      })
      .then((cursor) => {
        return limit ? cursor.limit(limit) : cursor
      })
      .then((cursor) => {
        return sort ? cursor.sort(sort) : cursor
      })
      .then((cursor) => {
        return cursor.toArray()
      })
      .then((data) => {
        if(!single) {
          resolve(data)
        }
        else {
          if(data.length === 0) {
            reject(new Error("not found"))
          }
          else {
            resolve(data[0])
          }
        }

      })
      .catch((err) => {
        reject(err)
      })
  })
}

const readOne = (collection, options) => {
  if(!options)
    options = {}
  options.limit = 1
  options.single = true
  return readAll(collection, options)
}

const readOneById = (collection, id) => {
  const options = {
    limit : 1,
    filter: {_id:id}
  }
  return readAll(collection, options)
}

// exports
module.exports.readAll = readAll;
module.exports.readOne = readOne;
module.exports.readOneById = readOneById;

<|endoftext|>


<commit_before>var _ = require('underscore');
var buffer = require('buffer');
var JuttleMoment = require('juttle/lib/moment').JuttleMoment;
var net = require('net');
/* global -Promise */
var Promise = require('bluebird');
var url = require('url');
var Juttle = require('juttle/lib/runtime').Juttle;

/* globals global */
global.Promise = Promise;
var fetch = require('isomorphic-fetch');

var Read = function(config) {
    return Juttle.proc.source.extend({
        procName: 'read-graphite',

        initialize: function(options, params, pname, location, program, juttle) {
            var allowed_options = ['from', 'to'];
            var unknown = _.difference(_.keys(options), allowed_options);
            if (unknown.length > 0) {
                throw this.compile_error('RT-UNKNOWN-OPTION-ERROR', {
                    proc: 'read graphite',
                    option: unknown[0]
                });
            }

            this.from = options.from;
            this.to = options.to;

            if (!this.from) {
                throw this.compile_error('RT-REQUIRED-OPTION-ERROR', {
                    proc: 'read graphite',
                    option: '-from'
                });
            }

            var from = Math.round(new JuttleMoment(this.from).milliseconds()/1000);
            var to;

            if (this.to) {
                to = Math.round(new JuttleMoment(this.to).milliseconds()/1000);
            }

            var auth = new buffer.Buffer(config.webapp.username + ':' + config.webapp.password).toString('base64');
            this.headers = {
                'Authorization': 'Basic ' + auth.toString('base64')
            };

            this.filter = null;
            var name = null;
            if (params.filter_ast) {
                var compiler = new Juttle.FilterJSCompiler();
                var source = compiler.compile(params.filter_ast);

                var expression =  params.filter_ast.expression;
                if (expression.type === 'BinaryExpression' &&
                    (expression.operator === '==' || expression.operator === '=~')) {
                    var left = expression.left;
                    var right = expression.right;
                    if (left && right) {
                        if (left.value === 'name' && right.type === 'StringLiteral') {
                            name = right.value;
                        }
                    }
                }

                if (name) {
                    /* jshint evil: true */
                    this.filter = eval(source);
                }
            }

            // when no name was set then the filter expression is either missing
            // or wrong
            if (!name) {
                throw Error('Error: filter expression must match: name="XXX"/name~"X.*"');
            }

            this.url = url.format({
                protocol: 'http',
                hostname: config.webapp.host,
                port: config.webapp.port,
                pathname: '/render',
                query: {
                    target: name,
                    from: from,
                    until: to,
                    format: 'json'
                }
            });
        },

        start: function() {
            var self = this;

            return fetch(this.url, { headers: self.headers })
            .then(function(res) {
                if (res.status > 200) {
                    throw self.runtime_error('RT-INTERNAL-ERROR', {
                        error: res.status + ': ' + res.statusText
                    });
                }
                return res.json();
            })
            .then(function(payload) {
                _.each(payload, function(data) {
                    var points = [];
                    var name = data.target;
                    _.each(data.datapoints, function(value){
                        // always check the first element of the data point list
                        // since graphite likes to send back nulls
                        if (value[0]) {
                            var time = new JuttleMoment();
                            time.parseDate(value[1]);

                            var point = {
                                name: name,
                                value: value[0],
                                time: time
                            };
                            points.push(point);
                        }
                    });

                    if (self.filter !== null) {
                        points = points.filter(self.filter);
                    }

                    if (points.length !== 0 ) {
                        self.emit(points);
                    }
                });
                self.emit_eof();
            })
            .catch(function(err) {
                self.trigger('error', self.runtime_error('RT-INTERNAL-ERROR', { error: err.toString() }));
                self.emit_eof();
            });
        }
    });
};

module.exports = Read;
<commit_msg>remove unnecessary node based filtering from read<commit_after>var _ = require('underscore');
var buffer = require('buffer');
var JuttleMoment = require('juttle/lib/moment').JuttleMoment;
var net = require('net');
/* global -Promise */
var Promise = require('bluebird');
var url = require('url');
var Juttle = require('juttle/lib/runtime').Juttle;

/* globals global */
global.Promise = Promise;
var fetch = require('isomorphic-fetch');

var Read = function(config) {
    return Juttle.proc.source.extend({
        procName: 'read-graphite',

        initialize: function(options, params, pname, location, program, juttle) {
            var allowed_options = ['from', 'to'];
            var unknown = _.difference(_.keys(options), allowed_options);
            if (unknown.length > 0) {
                throw this.compile_error('RT-UNKNOWN-OPTION-ERROR', {
                    proc: 'read graphite',
                    option: unknown[0]
                });
            }

            this.from = options.from;
            this.to = options.to;

            if (!this.from) {
                throw this.compile_error('RT-REQUIRED-OPTION-ERROR', {
                    proc: 'read graphite',
                    option: '-from'
                });
            }

            var from = Math.round(new JuttleMoment(this.from).milliseconds()/1000);
            var to;

            if (this.to) {
                to = Math.round(new JuttleMoment(this.to).milliseconds()/1000);
            }

            var auth = new buffer.Buffer(config.webapp.username + ':' + config.webapp.password).toString('base64');
            this.headers = {
                'Authorization': 'Basic ' + auth.toString('base64')
            };

            var name = null;
            if (params.filter_ast) {
                var expression =  params.filter_ast.expression;
                if (expression.type === 'BinaryExpression' &&
                    (expression.operator === '==' || expression.operator === '=~')) {
                    var left = expression.left;
                    var right = expression.right;
                    if (left && right) {
                        if (left.value === 'name' && right.type === 'StringLiteral') {
                            name = right.value;
                        }
                    }
                }
            }

            // when no name was set then the filter expression is either missing
            // or wrong
            if (!name) {
                throw Error('Error: filter expression must match: name="XXX"/name~"X.*"');
            }

            this.url = url.format({
                protocol: 'http',
                hostname: config.webapp.host,
                port: config.webapp.port,
                pathname: '/render',
                query: {
                    target: name,
                    from: from,
                    until: to,
                    format: 'json'
                }
            });
        },

        start: function() {
            var self = this;

            return fetch(this.url, { headers: self.headers })
            .then(function(res) {
                if (res.status > 200) {
                    throw self.runtime_error('RT-INTERNAL-ERROR', {
                        error: res.status + ': ' + res.statusText
                    });
                }
                return res.json();
            })
            .then(function(payload) {
                _.each(payload, function(data) {
                    var points = [];
                    var name = data.target;
                    _.each(data.datapoints, function(value){
                        // always check the first element of the data point list
                        // since graphite likes to send back nulls
                        if (value[0]) {
                            var time = new JuttleMoment();
                            time.parseDate(value[1]);

                            var point = {
                                name: name,
                                value: value[0],
                                time: time
                            };
                            points.push(point);
                        }
                    });

                    if (points.length !== 0 ) {
                        self.emit(points);
                    }
                });
                self.emit_eof();
            })
            .catch(function(err) {
                self.trigger('error', self.runtime_error('RT-INTERNAL-ERROR', { error: err.toString() }));
                self.emit_eof();
            });
        }
    });
};

module.exports = Read;
<|endoftext|>


<commit_before>//// NPM
const simpleGit = require('simple-git/promise')
//// CORE
const path = require('path')
//// LOCAL
const { confirm, input } = require('../lib/api')
const { format, log } = require('../lib/log')
const { words } = require('../lib/store')
const { name } = require('../lib/viewer')

const { appRepo } = require('../package.json')
const config = require('../config/config.json')

const git = simpleGit(process.cwd())

module.exports = repo = {
  commit: async (comment) => {
    if (!await git.checkIsRepo()) {
      log('error', `${name()} git repository not found.` )
      return
    }
    const status = await git.status()
    for (const key of Object.keys(status)) {
      if (Array.isArray(status[key]) && status[key].length>0) {
        log('log', status)
        break
      }
    }
    if (await confirm(`Commit changes to ${name()} repo now?`)) {
      return git.add('.')
      .then( async () => {
        const comment = await input('Commit comment', `CLI source file changes detected at startup`)
        return git.commit(comment)
      })
      .then( () => {
        return log('confirm', 'Commit complete')
      })
      .catch( err => log('error', `(commitChanges) error\n${format(err)}`))
    }
  },
  git,
  push: async (user, phrase, origin) => {
    try {
      const remote = `https://${user}:${phrase}@${origin}`;
      if (origin && (await git.status()).ahead>0) {
        if (await confirm(`Push changes to '${origin}' now?`)) {
          if (await git.listRemote()) {
            await git.push(remote, 'master')
          }
          log('log', `tracked changes pushed`)
        }
      }
    }
    catch(err) {
      log('error', `(push) error \n${format(err)}`)
    }
  }
}
<commit_msg>CLI source file changes detected at startup<commit_after>//// NPM
const simpleGit = require('simple-git/promise')
//// CORE
const path = require('path')
//// LOCAL
const { confirm, input } = require('../lib/api')
const { format, log } = require('../lib/log')
const { words } = require('../lib/store')
const { name } = require('../lib/viewer')

const { appRepo } = require('../package.json')
const config = require('../config/config.json')

const git = simpleGit(process.cwd())

module.exports = repo = {
  commit: async (comment) => {
    return new Promise( async (resolve, reject) => {
      try {
        if (!await git.checkIsRepo()) {
          resolve(log('error', `${name()} git repository not found.` ))
        }
        const status = await git.status()
        for (const key of Object.keys(status)) {
          if (Array.isArray(status[key]) && status[key].length>0) {
            log('log', status)
            break
          }
        }
        if (await confirm(`Commit changes to ${name()} repo now?`)) {
          return git.add('.')
          .then( async () => {
            const comment = await input('Commit comment', `CLI source file changes detected at startup`)
            resolve(git.commit(comment))
          })
          .catch( err => resolve(log('error', `(commitChanges) error\n${format(err)}`)))
        }
      }
      catch(err) {
        resolve(log('error', `(commitChanges) error\n${format(err)}`))
      }
    })
  },
  git,
  push: async (user, phrase, origin) => {
    try {
      const remote = `https://${user}:${phrase}@${origin}`;
      if (origin && (await git.status()).ahead>0) {
        if (await confirm(`Push changes to '${origin}' now?`)) {
          if (await git.listRemote()) {
            await git.push(remote, 'master')
          }
          log('log', `tracked changes pushed`)
        }
      }
    }
    catch(err) {
      log('error', `(push) error \n${format(err)}`)
    }
  }
}
<|endoftext|>


<commit_before>/*!
 * Chris O'Hara
 * Copyright(c) 2011 Chris O'Hara <cohara87@gmail.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var models = require('./models')
  , lingo = require('lingo').en;

/**
 * The MongoDB ID format.
 */

var id_format = exports.id_format = /^[0-9a-f]{24}$/;

/**
 * Autoload resources when they're part of a route, e.g. /posts/:post
 * or any other route with the ":post" param will automatically load
 * the resource.
 *
 * @param {HTTPServer} app
 * @param {object} config (optional)
 * @api public
 */

exports.autoloadResources = function (app, config, ignore) {
    config = config || {};
    ignore = ignore || [];

    models.getTopLevel().forEach(function (resource) {
        if (ignore.indexOf(resource) !== -1) return;

        autoloadTopLevelResource(app, resource, config);

        models.getChildren(resource).forEach(function (embedded) {
            if (ignore.indexOf(resource) !== -1) return;

            autoloadEmbeddedResource(app, resource,
                embedded.resource, embedded.attribute, config);
        });
    });

    app.dynamicHelpers({resource: function (request, response) {
        return request.resource;
    }});
}

/**
 * Autoload a resource when a route contains it as a parameter, e.g.
 * /posts/:post will automatically load the requested post, where :post
 * is either an ID or unique slug, e.g. /posts/my-test-post or /posts/23
 *
 * @param {HTTPServer} app
 * @param {string} resource
 * @param {object} config (optional)
 * @api private
 */

function autoloadTopLevelResource (app, resource, config) {
    var model = models.mongoose.model(resource)
      , singular = lingo.singularize(resource);

    app.param(singular, function (request, response, next) {
        var id = request.params[singular];

        function handleResource (err, obj) {
            if (err) {
                return next(new Error(err));
            } else if (null == obj) {
                if (request.xhr || request.format) {
                    response.send(404);
                } else {
                    request.flash('error', 'The %s could not be found.', singular);
                    response.redirect('back');
                }
            } else {
                request.resource(singular, obj);
                next();
            }
        }

        //Is there a unique slug attribute we can lookup by? If not, lookup by ID
        if (model.schema.tree.slug && !id_format.test(id)) {
            model.findOne({slug: id}, handleResource);
        } else {
            model.findById(id, handleResource);
        }
    });
}

/**
 * Autoload an embedded resource when a route contains it as a parameter, e.g.
 * /posts/:post/commments/:comment will automatically load the requested
 * comment (assuming the post has already been loaded).
 *
 * @param {HTTPServer} app
 * @param {string} parent
 * @param {string} resource
 * @param {string} attribute - the attribute name of the embedded resource
 * @param {object} config (optional)
 * @api private
 */

function autoloadEmbeddedResource (app, parent, resource, attribute, config) {
    var model = models.mongoose.model(resource)
      , singular = lingo.singularize(resource)
      , parent_singular = lingo.singularize(parent);

    app.param(singular, function (request, response, next) {
        var parent = request.resource(parent_singular)
          , id = request.params[singular];
        if (parent && attribute in parent) {
            parent[attribute].forEach(function (child) {
                if (child.get('id') == id) {
                    request.resource(singular, child);
                    return next();
                }
            });
        } else if (request.xhr || request.format) {
            response.send([]);
        } else {
            request.flash('error', 'The %s could not be found.', singular);
            response.redirect('back');
        }
    });
}

/**
 * Add RESTful routes.
 *
 * @param {HTTPServer} app
 * @param {object} routes
 * @param {string} prefix
 * @param {string} singular
 * @api private
 */

function addRoutes (app, routes, prefix, singular) {
    app.get    ( prefix + '.:format?'                   , routes.index  );
    app.post   ( prefix                                 , routes.create );
    app.get    ( prefix + '/:' + singular + '.:format?' , routes.read   );
    app.put    ( prefix + '/:' + singular               , routes.update );
    app.delete ( prefix + '/:' + singular               , routes.destroy);
}

/**
 * Create resource-based, RESTful routes for top-level mongoose models.
 * All models must be defined before calling this method.
 *
 * @param {HTTPServer} app
 * @param {object} config (optional)
 * @api public
 */

exports.create = function (app, config, ignore) {
    config = config || {};
    ignore = ignore || [];

    //Set config defaults
    config.default_limit = config.default_limit || 20
    config.max_limit = config.max_limit || 100;

    //Add routes for each top level model
    models.getTopLevel().forEach(function (resource) {
        if (ignore.indexOf(resource) !== -1) return;

        var singular = lingo.singularize(resource)
          , plural = lingo.pluralize(resource)
          , top_prefix = (config.path || '/') + plural
          , routes;

        //Add RESTful routes
        routes = topLevelRoutes(app, top_prefix, resource, config);
        addRoutes(app, routes, top_prefix, singular);
    });
}

/**
 * Create resource-based, RESTful routes for embedded mongoose models.
 * All models must be defined before calling this method.
 *
 * @param {HTTPServer} app
 * @param {object} config (optional)
 * @api public
 */

exports.createEmbedded = function (app, config, ignore) {
    config = config || {};
    ignore = ignore || [];

    //Set config defaults
    config.default_limit = config.default_limit || 20
    config.max_limit = config.max_limit || 100;

    //Add routes for each top level model
    models.getTopLevel().forEach(function (resource) {
        if (ignore.indexOf(resource) !== -1) return;

        var singular = lingo.singularize(resource)
          , plural = lingo.pluralize(resource)
          , top_prefix = (config.path || '/') + plural
          , routes;

        //Add routes for embedded documents
        models.getChildren(resource).forEach(function (embedded) {
            if (ignore.indexOf(resource) !== -1) return;

            var prefix = top_prefix + '/:' + singular;

            routes = embeddedRoutes(app, prefix, resource, embedded.resource,
                                        embedded.attribute);

            addRoutes(app, routes, prefix + '/' + embedded.plural, embedded.singular);
        });

    });
}

/**
 * Generate routes for top level models.
 *
 * @param {HTTPServer} app
 * @param {string} resource
 * @param {object} config (optional)
 * @return {object} routes
 * @api private
 */

function topLevelRoutes (app, prefix, resource, config) {

    var model = models.mongoose.model(resource)
      , singular = lingo.singularize(resource)
      , plural = lingo.pluralize(resource)
      , routes = {};

    //GET /<resource>
    routes.index = function (request, response, next) {
        var page = parseInt(request.query.page) || 1
          , limit = Math.min(config.max_limit, request.query.limit
                                                   || config.default_limit)
          , offset = (page - 1) * limit
          , locals = {}
          , query;

        function doQuery(query) {
            query.skip(offset).limit(limit).run(function (err, results) {
                if (err) {
                    return next(new Error(err));
                } else if (request.xhr || request.format === 'json') {
                    return response.send(results || []);
                }
                var locals = {
                    limit  : limit
                  , page   : page
                  , offset : offset
                  , query  : request.query
                }
                locals[plural] = results || [];
                response.locals(locals);
                request.resource(plural, results);
                next();
            });
        }

        //Use Model.search() if it's defined
        if (model.search) {
            model.search(request.query, request.user, function (err, query) {
                if (err) {
                    return next(new Error(err));
                }
                doQuery(query);
            });
        } else {
            query = model.find();
            if (request.query.order) {
                query = query.sort([[
                    request.query.order, request.query.desc ? 'descending'
                                                            : 'ascending'
                ]]);
            }
            doQuery(query);
        }
    }

    //POST /<resource>
    routes.create = function (request, response, next) {
        var attr, instance = new model();
        for (attr in request.body) {
            if (!(attr in model.schema.tree)) {
                delete request.body[attr];
            }
        }
        for (attr in request.body) {
            instance[attr] = request.body[attr];
        }
        instance.save(function (err) {
            var id = model.schema.tree.slug ? instance.get('slug') : instance.get('id');
            if (err) {
                return next(new Error(err));
            } else if (request.xhr || request.format === 'json') {
                response.header('location', '/' + plural + '/' + id);
                return response.send(201);
            }
            request.flash('info', 'The %s was created successfully', singular);
            var redirect = request.redirect
                         ? request.redirect
                         : '/' + plural + '/' + id;
            response.redirect(redirect);
        });
    }

    //GET /<resource>/:id
    routes.read = function (request, response, next) {
        if (request.xhr || request.format === 'json') {
            return response.send(request.resource(singular).toJSON());
        }
        response.local('instance', request.resource(singular));
        next();
    }

    //PUT /<resource>/:id
    routes.update = function (request, response, next) {
        var attr, instance = request.resource(singular);
        for (attr in request.body) {
            if (!(attr in model.schema.tree)) {
                delete request.body[attr];
            }
        }
        for (attr in request.body) {
            instance[attr] = request.body[attr];
        }
        instance.save(function (err) {
            if (err) {
                return next(new Error(err));
            } else if (request.xhr || request.format === 'json') {
                return response.send(instance);
            }
            request.flash('success', 'The %s was updated successfully', singular);
            var redirect = request.redirect
                         ? request.redirect
                         : '/' + plural + '/' + request.params[singular];
            response.redirect(redirect);
        });
    }

    //DELETE /<resource>/:id
    routes.destroy = function (request, response, next) {
        request.resource(singular).remove(function (err) {
            if (err) {
                return next(new Error(err));
            } else if (request.xhr || request.format === 'json') {
                return response.send(200);
            }
            request.flash('success', 'The %s was removed successfully', singular);
            var redirect = request.redirect
                         ? request.redirect
                         : '/' + plural;
            response.redirect(redirect);
        });
    }

    //If there's a static acl() method, patch each action to route through it
    if (model.acl) {
        for (var action in routes) {
            (function (action, handle) {
                routes[action] = function (request, response, next) {
                    var user = request.user || null
                      , obj = request.resource(singular) || request.body;
                    model.acl(user, action, obj, function (ok) {
                        if (ok) {
                            return handle(request, response, next);
                        } else if (request.xhr || request.format) {
                            return response.send(403);
                        }
                        next(new Error('auth'));
                    });
                }
            })(action, routes[action]);
        }
    }

    return routes;
}

/**
 * Generate routes for embedded documents.
 *
 * @param {HTTPServer} app
 * @param {string} prefix
 * @param {string} parent
 * @param {string} resource
 * @param {string} attribute
 * @param {object} config (optional)
 * @return {object} routes
 * @api private
 */

function embeddedRoutes (app, prefix, parent_resource, resource, attribute) {

    var model = models.mongoose.model(resource)
      , plural = lingo.pluralize(resource)
      , singular = lingo.singularize(resource)
      , parent_model = models.mongoose.model(parent_resource)
      , parent_plural = lingo.pluralize(parent_resource)
      , parent_singular = lingo.singularize(parent_resource)
      , routes = {};

    prefix += '/' + plural;

    //GET /<parent_resource>/:parent_id/<resource>
    routes.index = function (request, response, next) {
        var parent = request.resource(parent_singular)
          , children = [];

        if (parent[attribute] && parent[attribute].length) {
            parent[attribute].forEach(function (child) {
                //Convert each child to a JSON string
                var obj = child.toJSON();
                obj.id = obj._id;
                delete obj._id;
                children.push(obj);
            });
        }
        return response.send(children);
    }

    //POST /<parent_resource>/:parent_id/<resource>/:id
    routes.create = function (request, response, next) {
        var parent = request.resource(parent_singular)
          , child = new model();
        if (!parent[attribute]) {
            parent[attribute] = [];
        }
        for (attr in request.body) {
            if (attr in model.schema.tree) {
                child[attr] = request.body[attr];
            }
        }
        parent[attribute].push(child);
        parent.save(function (err) {
            if (err) {
                return next(new Error(err));
            }
            response.send(child.toJSON());
        });
    }

    //GET /<parent_resource>/:parent_id/<resource>/:id
    routes.read = function (request, response, next) {
        var instance = request.resource(singular);
        response.send(instance);
    }

    //PUT /<parent_resource>/:parent_id/<resource>/:id
    routes.update = function (request, response, next) {
        var instance = request.resource(singular)
          , parent = request.resource(parent_singular);
        for (attr in request.body) {
            if (attr in model.schema.tree) {
                instance[attr] = request.body[attr];
            }
        }
        parent.save(function (err) {
            if (err) {
                return next(new Error(err));
            }
            response.send(200);
        });
    }

    //DELETE /<parent_resource>/:parent_id/<resource>/:id
    routes.destroy = function (request, response, next) {
        var instance = request.resource(singular)
          , parent = request.resource(parent_singular);
        instance.remove();
        parent.save(function (err) {
            if (err) {
                return next(new Error(err));
            }
            response.send(200);
        });
    }

    //Run each embedded document route through the parent's acl() method
    if (parent_model.acl) {
        for (var action in routes) {
            (function (action, handle) {
                routes[action] = function (request, response, next) {
                    var user = request.user || null
                      , obj = request.resource(singular) || request.body;
                    parent_model.acl(user, action, obj, function (ok) {
                        if (ok) {
                            return handle(request, response, next);
                        } else if (request.xhr || request.format) {
                            return response.send(403);
                        }
                        next(new Error('auth'));
                    });
                }
            })(action, routes[action]);
        }
    }

    return routes;
}

<commit_msg>Exclude routes<commit_after>/*!
 * Chris O'Hara
 * Copyright(c) 2011 Chris O'Hara <cohara87@gmail.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var models = require('./models')
  , lingo = require('lingo').en;

/**
 * The MongoDB ID format.
 */

var id_format = exports.id_format = /^[0-9a-f]{24}$/;

/**
 * Autoload resources when they're part of a route, e.g. /posts/:post
 * or any other route with the ":post" param will automatically load
 * the resource.
 *
 * @param {HTTPServer} app
 * @param {object} config (optional)
 * @api public
 */

exports.autoloadResources = function (app, config, ignore) {
    config = config || {};
    ignore = ignore || [];

    models.getTopLevel().forEach(function (resource) {
        if (ignore.indexOf(resource) !== -1) return;

        autoloadTopLevelResource(app, resource, config);

        models.getChildren(resource).forEach(function (embedded) {
            if (ignore.indexOf(resource) !== -1) return;

            autoloadEmbeddedResource(app, resource,
                embedded.resource, embedded.attribute, config);
        });
    });

    app.dynamicHelpers({resource: function (request, response) {
        return request.resource;
    }});
}

/**
 * Autoload a resource when a route contains it as a parameter, e.g.
 * /posts/:post will automatically load the requested post, where :post
 * is either an ID or unique slug, e.g. /posts/my-test-post or /posts/23
 *
 * @param {HTTPServer} app
 * @param {string} resource
 * @param {object} config (optional)
 * @api private
 */

function autoloadTopLevelResource (app, resource, config) {
    var model = models.mongoose.model(resource)
      , singular = lingo.singularize(resource);

    app.param(singular, function (request, response, next) {
        var id = request.params[singular];

        function handleResource (err, obj) {
            if (err) {
                return next(new Error(err));
            } else if (null == obj) {
                if (request.xhr || request.format) {
                    response.send(404);
                } else {
                    request.flash('error', 'The %s could not be found.', singular);
                    response.redirect('back');
                }
            } else {
                request.resource(singular, obj);
                next();
            }
        }

        //Is there a unique slug attribute we can lookup by? If not, lookup by ID
        if (model.schema.tree.slug && !id_format.test(id)) {
            model.findOne({slug: id}, handleResource);
        } else {
            model.findById(id, handleResource);
        }
    });
}

/**
 * Autoload an embedded resource when a route contains it as a parameter, e.g.
 * /posts/:post/commments/:comment will automatically load the requested
 * comment (assuming the post has already been loaded).
 *
 * @param {HTTPServer} app
 * @param {string} parent
 * @param {string} resource
 * @param {string} attribute - the attribute name of the embedded resource
 * @param {object} config (optional)
 * @api private
 */

function autoloadEmbeddedResource (app, parent, resource, attribute, config) {
    var model = models.mongoose.model(resource)
      , singular = lingo.singularize(resource)
      , parent_singular = lingo.singularize(parent);

    app.param(singular, function (request, response, next) {
        var parent = request.resource(parent_singular)
          , id = request.params[singular];
        if (parent && attribute in parent) {
            parent[attribute].forEach(function (child) {
                if (child.get('id') == id) {
                    request.resource(singular, child);
                    return next();
                }
            });
        } else if (request.xhr || request.format) {
            response.send([]);
        } else {
            request.flash('error', 'The %s could not be found.', singular);
            response.redirect('back');
        }
    });
}

/**
 * Add RESTful routes.
 *
 * @param {HTTPServer} app
 * @param {object} routes
 * @param {string} prefix
 * @param {string} singular
 * @api private
 */

function addRoutes (app, routes, prefix, singular) {
    if ('index' in routes)
        app.get(prefix + '.:format?', routes.index);

    if ('create' in routes)
        app.post(prefix, routes.create);

    if ('read' in routes)
        app.get(prefix + '/:' + singular + '.:format?', routes.read);

    if ('update' in routes)
        app.put(prefix + '/:' + singular, routes.update);

    if ('destroy' in routes)
        app.delete(prefix + '/:' + singular, routes.destroy);
}

/**
 * Create resource-based, RESTful routes for top-level mongoose models.
 * All models must be defined before calling this method.
 *
 * @param {HTTPServer} app
 * @param {object} config (optional)
 * @api public
 */

exports.create = function (app, config, include_routes, ignore) {
    config = config || {};
    ignore = ignore || [];

    //Set config defaults
    config.default_limit = config.default_limit || 20
    config.max_limit = config.max_limit || 100;

    //Add routes for each top level model
    models.getTopLevel().forEach(function (resource) {
        if (ignore.indexOf(resource) !== -1) return;

        var singular = lingo.singularize(resource)
          , plural = lingo.pluralize(resource)
          , top_prefix = (config.path || '/') + plural
          , routes;

        //Add RESTful routes
        routes = topLevelRoutes(app, top_prefix, resource, config);

        //Only include some routes?
        if (include_routes) {
            for (var type in routes) {
                if (!~include_routes.indexOf(type)
                        && !~include_routes.indexOf(singular + '.' + type)) {
                    delete routes[type]
                }
            }
        }

        addRoutes(app, routes, top_prefix, singular);
    });
}

/**
 * Create resource-based, RESTful routes for embedded mongoose models.
 * All models must be defined before calling this method.
 *
 * @param {HTTPServer} app
 * @param {object} config (optional)
 * @api public
 */

exports.createEmbedded = function (app, config, include_routes, ignore) {
    config = config || {};
    ignore = ignore || [];

    //Set config defaults
    config.default_limit = config.default_limit || 20
    config.max_limit = config.max_limit || 100;

    //Add routes for each top level model
    models.getTopLevel().forEach(function (resource) {
        if (ignore.indexOf(resource) !== -1) return;

        var singular = lingo.singularize(resource)
          , plural = lingo.pluralize(resource)
          , top_prefix = (config.path || '/') + plural
          , routes;

        //Add routes for embedded documents
        models.getChildren(resource).forEach(function (embedded) {
            if (ignore.indexOf(resource) !== -1) return;

            var prefix = top_prefix + '/:' + singular;

            routes = embeddedRoutes(app, prefix, resource, embedded.resource,
                                        embedded.attribute);

            //Only include some routes?
            if (include_routes) {
                for (var type in routes) {
                    if (!~include_routes.indexOf(type) &&
                            !~include_routes.indexOf(embedded.singular + '.' + type)) {
                        delete routes[type]
                    }
                }
            }

            addRoutes(app, routes, prefix + '/' + embedded.plural, embedded.singular);
        });

    });
}

/**
 * Generate routes for top level models.
 *
 * @param {HTTPServer} app
 * @param {string} resource
 * @param {object} config (optional)
 * @return {object} routes
 * @api private
 */

function topLevelRoutes (app, prefix, resource, config) {

    var model = models.mongoose.model(resource)
      , singular = lingo.singularize(resource)
      , plural = lingo.pluralize(resource)
      , routes = {};

    //GET /<resource>
    routes.index = function (request, response, next) {
        var page = parseInt(request.query.page) || 1
          , limit = Math.min(config.max_limit, request.query.limit
                                                   || config.default_limit)
          , offset = (page - 1) * limit
          , locals = {}
          , query;

        function doQuery(query) {
            query.skip(offset).limit(limit).run(function (err, results) {
                if (err) {
                    return next(new Error(err));
                } else if (request.xhr || request.format === 'json') {
                    return response.send(results || []);
                }
                var locals = {
                    limit  : limit
                  , page   : page
                  , offset : offset
                  , query  : request.query
                }
                locals[plural] = results || [];
                response.locals(locals);
                request.resource(plural, results);
                next();
            });
        }

        //Use Model.search() if it's defined
        if (model.search) {
            model.search(request.query, request.user, function (err, query) {
                if (err) {
                    return next(new Error(err));
                }
                doQuery(query);
            });
        } else {
            query = model.find();
            if (request.query.order) {
                query = query.sort([[
                    request.query.order, request.query.desc ? 'descending'
                                                            : 'ascending'
                ]]);
            }
            doQuery(query);
        }
    }

    //POST /<resource>
    routes.create = function (request, response, next) {
        var attr, instance = new model();
        for (attr in request.body) {
            if (!(attr in model.schema.tree)) {
                delete request.body[attr];
            }
        }
        for (attr in request.body) {
            instance[attr] = request.body[attr];
        }
        instance.save(function (err) {
            var id = model.schema.tree.slug ? instance.get('slug') : instance.get('id');
            if (err) {
                return next(new Error(err));
            } else if (request.xhr || request.format === 'json') {
                response.header('location', '/' + plural + '/' + id);
                return response.send(201);
            }
            request.flash('success', 'The %s was created successfully.', singular);
            var redirect = request.redirect
                         ? request.redirect
                         : '/' + plural + '/' + id;
            response.redirect(redirect);
        });
    }

    //GET /<resource>/:id
    routes.read = function (request, response, next) {
        if (request.xhr || request.format === 'json') {
            return response.send(request.resource(singular).toJSON());
        }
        response.local('instance', request.resource(singular));
        next();
    }

    //PUT /<resource>/:id
    routes.update = function (request, response, next) {
        var attr, instance = request.resource(singular);
        for (attr in request.body) {
            if (!(attr in model.schema.tree)) {
                delete request.body[attr];
            }
        }
        for (attr in request.body) {
            instance[attr] = request.body[attr];
        }
        instance.save(function (err) {
            if (err) {
                return next(new Error(err));
            } else if (request.xhr || request.format === 'json') {
                return response.send(instance);
            }
            request.flash('success', 'The %s was updated successfully.', singular);
            var redirect = request.redirect
                         ? request.redirect
                         : '/' + plural + '/' + request.params[singular];
            response.redirect(redirect);
        });
    }

    //DELETE /<resource>/:id
    routes.destroy = function (request, response, next) {
        request.resource(singular).remove(function (err) {
            if (err) {
                return next(new Error(err));
            } else if (request.xhr || request.format === 'json') {
                return response.send(200);
            }
            request.flash('success', 'The %s was removed successfully.', singular);
            var redirect = request.redirect
                         ? request.redirect
                         : '/' + plural;
            response.redirect(redirect);
        });
    }

    //If there's a static acl() method, patch each action to route through it
    if (model.acl) {
        for (var action in routes) {
            (function (action, handle) {
                routes[action] = function (request, response, next) {
                    var user = request.user || null
                      , obj = request.resource(singular) || request.body;
                    model.acl(user, action, obj, function (ok) {
                        if (ok) {
                            return handle(request, response, next);
                        } else if (request.xhr || request.format) {
                            return response.send(403);
                        }
                        next(new Error('auth'));
                    });
                }
            })(action, routes[action]);
        }
    }

    return routes;
}

/**
 * Generate routes for embedded documents.
 *
 * @param {HTTPServer} app
 * @param {string} prefix
 * @param {string} parent
 * @param {string} resource
 * @param {string} attribute
 * @param {object} config (optional)
 * @return {object} routes
 * @api private
 */

function embeddedRoutes (app, prefix, parent_resource, resource, attribute) {

    var model = models.mongoose.model(resource)
      , plural = lingo.pluralize(resource)
      , singular = lingo.singularize(resource)
      , parent_model = models.mongoose.model(parent_resource)
      , parent_plural = lingo.pluralize(parent_resource)
      , parent_singular = lingo.singularize(parent_resource)
      , routes = {};

    prefix += '/' + plural;

    //GET /<parent_resource>/:parent_id/<resource>
    routes.index = function (request, response, next) {
        var parent = request.resource(parent_singular)
          , children = [];

        if (parent[attribute] && parent[attribute].length) {
            parent[attribute].forEach(function (child) {
                //Convert each child to a JSON string
                var obj = child.toJSON();
                obj.id = obj._id;
                delete obj._id;
                children.push(obj);
            });
        }
        return response.send(children);
    }

    //POST /<parent_resource>/:parent_id/<resource>/:id
    routes.create = function (request, response, next) {
        var parent = request.resource(parent_singular)
          , child = new model();
        if (!parent[attribute]) {
            parent[attribute] = [];
        }
        for (attr in request.body) {
            if (attr in model.schema.tree) {
                child[attr] = request.body[attr];
            }
        }
        parent[attribute].push(child);
        parent.save(function (err) {
            if (err) {
                return next(new Error(err));
            }
            response.send(child.toJSON());
        });
    }

    //GET /<parent_resource>/:parent_id/<resource>/:id
    routes.read = function (request, response, next) {
        var instance = request.resource(singular);
        response.send(instance);
    }

    //PUT /<parent_resource>/:parent_id/<resource>/:id
    routes.update = function (request, response, next) {
        var instance = request.resource(singular)
          , parent = request.resource(parent_singular);
        for (attr in request.body) {
            if (attr in model.schema.tree) {
                instance[attr] = request.body[attr];
            }
        }
        parent.save(function (err) {
            if (err) {
                return next(new Error(err));
            }
            response.send(200);
        });
    }

    //DELETE /<parent_resource>/:parent_id/<resource>/:id
    routes.destroy = function (request, response, next) {
        var instance = request.resource(singular)
          , parent = request.resource(parent_singular);
        instance.remove();
        parent.save(function (err) {
            if (err) {
                return next(new Error(err));
            }
            response.send(200);
        });
    }

    //Run each embedded document route through the parent's acl() method
    if (parent_model.acl) {
        for (var action in routes) {
            (function (action, handle) {
                routes[action] = function (request, response, next) {
                    var user = request.user || null
                      , obj = request.resource(singular) || request.body;
                    parent_model.acl(user, action, obj, function (ok) {
                        if (ok) {
                            return handle(request, response, next);
                        } else if (request.xhr || request.format) {
                            return response.send(403);
                        }
                        next(new Error('auth'));
                    });
                }
            })(action, routes[action]);
        }
    }

    return routes;
}

<|endoftext|>