rest-methods
Version:
Declaratively publish functions for remote invocation.
193 lines (150 loc) • 5.62 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var _lodash = require("lodash");
var _lodash2 = _interopRequireDefault(_lodash);
var _fs = require("fs");
var _fs2 = _interopRequireDefault(_fs);
var _path = require("path");
var _path2 = _interopRequireDefault(_path);
var _url = require("url");
var _url2 = _interopRequireDefault(_url);
var _bodyParser = require("body-parser");
var _bodyParser2 = _interopRequireDefault(_bodyParser);
var _manifest = require("./manifest");
var _manifest2 = _interopRequireDefault(_manifest);
var _docs = require("../docs");
var _docs2 = _interopRequireDefault(_docs);
var _const = require("../const");
var _stylus = require("stylus");
var _stylus2 = _interopRequireDefault(_stylus);
var _nib = require("nib");
var _nib2 = _interopRequireDefault(_nib);
var jsonParser = _bodyParser2["default"].json();
var FAVICON = _fs2["default"].readFileSync(_path2["default"].join(__dirname, "../docs/favicon.ico"));
// Middleware.
var middleware = function middleware(server, req, res, next) {
var basePath = server.basePath.replace(/\/$/, "");
var url = _url2["default"].parse(req.url, true);
var cache = {};
var send = function send(content, contentType) {
res.setHeader("Content-Type", contentType);
res.end(content);
};
var getFile = function getFile(fileName) {
var path = _path2["default"].join(__dirname, fileName);
if (!cache[path]) {
// NB: Only load from file if not in the cache.
var text = _fs2["default"].readFileSync(path).toString();
cache[path] = { text: text, path: path };
}
return cache[path];
};
var sendJs = function sendJs(fileName) {
var js = getFile("../../.build/" + fileName).text;
send(js, "application/javascript");
};
var sendJson = function sendJson(obj) {
send(JSON.stringify(obj), "application/json");
};
var sendHtml = function sendHtml(html) {
send(html, "text/html");
};
var sendCss = function sendCss(css) {
send(css, "text/css");
};
var send404 = function send404(message) {
res.statusCode = 404;
send(message || "Not found", "text/plain");
};
var sendStylus = function sendStylus(fileName) {
var file = getFile(fileName);
(0, _stylus2["default"])(file.text).set("filename", file.path).include(_nib2["default"].path).render(function (err, css) {
if (err) {
throw err;
}
sendCss(css);
});
};
var sendDocsHtml = function sendDocsHtml() {
if (server.docs === true) {
var manifest = (0, _manifest2["default"])(server, { docs: true });
var pageProps = {
title: server.name + " (API)",
manifest: manifest,
faviconPath: basePath + "/favicon.ico",
stylePath: basePath + "/style.css",
scriptPath: basePath + "/docs.js",
bodyHtml: _docs2["default"].toHtml(_docs2["default"].Shell, { manifest: manifest })
};
sendHtml(_docs2["default"].pageHtml(pageProps));
} else {
send404();
}
};
// Match the route.
switch (url.pathname) {
// GET: An HTML representation of the API (docs).
case basePath:
sendDocsHtml();
break;
case basePath + "/":
sendDocsHtml();
break;
case basePath + "/style.css":
sendStylus("../docs/css/index.styl");
break;
case basePath + "/favicon.ico":
send(FAVICON, "image/x-icon");
break;
// GET: The manifest of methods.
case _const.MANIFEST_PATH:
var withDocs = url.query.docs === "true";
sendJson((0, _manifest2["default"])(server, { docs: withDocs }));
break;
// GET: Serve the client JS.
case basePath + "/browser.js":
sendJs("browser.js");
break;
case basePath + "/docs.js":
if (server.docs === true) {
sendJs("docs.js");
} else {
send404();
}
break;
default:
// Attempt to match the URL for a method.
var methodVerb = server.match(req.url, req.method);
if (methodVerb) {
// Invoke the method.
var args = req.body.args || req.body;
args = _lodash2["default"].isArray(args) ? args : [args];
server[_const.INVOKE](methodVerb, args, req.url).then(function (result) {
sendJson(result);
})["catch"](function (err) {
res.statusCode = err.status || 500;
sendJson(err);
});
} else {
// No match - continue to [next] middleware method.
next();
}
}
};
/**
* The connect middleware for managing API calls to the server.
* @param server: {Server} instance the middleware is handling.
* @return the connect middleware function.
*/
exports["default"] = function (server) {
return function (req, res, next) {
// Return the middleware passed through the JSON parser.
jsonParser(req, res, function () {
middleware(server, req, res, next);
});
};
};
module.exports = exports["default"];