UNPKG

rest-methods

Version:

Declaratively publish functions for remote invocation.

192 lines (152 loc) 6.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 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 _lodash = require("lodash"); var _lodash2 = _interopRequireDefault(_lodash); var _manifest = require("./manifest"); var _manifest2 = _interopRequireDefault(_manifest); var _pageJs = require("../page-js"); var _pageJs2 = _interopRequireDefault(_pageJs); 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 FAVICON = _fs2["default"].readFileSync(_path2["default"].join(__dirname, "../docs/favicon.ico")); /** * Determines whether the given URL path matches any of * the method routes. * @param server: {Server} instance to examine. * @param url: {string} The URL path to match. * @param verb: {string} The HTTP verb to match (GET|PUT|POST|DELETE). * @return {ServerMethod} */ var matchMethodUrl = function matchMethodUrl(server, url, verb) { verb = verb.toLowerCase(); var context = new _pageJs2["default"].Context(url); var methods = server[_const.METHODS]; var methodNames = Object.keys(methods); if (!_lodash2["default"].isEmpty(methodNames)) { var methodName = _lodash2["default"].find(Object.keys(methods), function (key) { var methodVerb = methods[key][verb]; var isMatch = methodVerb && methodVerb.pathRoute.match(context.path, context.params); return isMatch; }); var method = methods[methodName]; } return method ? method[verb] : undefined; }; /** * The connect middleware for managing API calls to the server. * @param server: {Server} instance the middleware is handling. * @return the connect middleware function. */ exports.matchMethodUrl = matchMethodUrl; exports["default"] = function (server) { // Middleware. return function (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 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() { 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)); }; // 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": sendJs("docs.js"); break; default: // Attempt to match the URL for a method. var methodVerb = matchMethodUrl(server, req.url, req.method); if (methodVerb) { // Invoke the method. methodVerb.invoke(req.body.args, req.url).then(function (result) { sendJson(result); })["catch"](function (err) { res.statusCode = err.status || 500; res.end(JSON.stringify(err)); }); } else { // No match - continue to [next] middleware method. next(); } } }; };