"use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; var Promise = require("bluebird"); var pathToRegexp = require("path-to-regexp"); var url = require("url"); var xtend = require("xtend"); var defaultValue = require("default-value"); module.exports = function () { var routes = []; function addRoute(method, path, handler) { // Mutable arguments? WTF. var keys = []; var regex = pathToRegexp(path, keys); routes.push({ method: method, path: path, regex: regex, keys: keys, handler: handler }); } function getRoute(method, path) { var matches = void 0; var matchingRoute = routes.find(function (route) { return route.method === method && (matches = route.regex.exec(path)); }); if (matchingRoute == null) { throw new Error("No matching routes found"); } else { var _ret = function () { var params = {}; matchingRoute.keys.forEach(function (key, i) { params[key] = matches[i + 1]; }); return { v: { handler: matchingRoute.handler, params: params } }; }(); if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v; } } function handle(method, uri, data) { return Promise.try(function () { var _url$parse = url.parse(uri, true); var path = _url$parse.path; var query = _url$parse.query; var route = getRoute(method, path); var tasks = []; var req = { path: path, query: query, body: data, params: route.params, pass: function pass() { // FIXME: window.fetch passthrough var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; }, passRender: function passRender(viewName) { var _this = this; var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; return Promise.try(function () { return _this.pass(options); }).then(function (response) { var locals = defaultValue(options.locals, {}); var combinedLocals = xtend(locals, response.body); res.render(viewName, combinedLocals, options); }); } }; var res = { render: function render(viewName) { var locals = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; tasks.push({ type: "render", viewName: viewName, locals: locals, options: options }); }, open: function open(path) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; tasks.push({ type: "open", path: path, options: options }); }, close: function close() { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; tasks.push({ type: "close", options: options }); }, notify: function notify(message) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; tasks.push({ type: "notify", message: message, options: options }); }, error: function error(_error) { var context = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; tasks.push({ type: "error", error: _error, context: context }); } }; return Promise.try(function () { return route.handler(req, res); }).then(function (result) { return { result: result, actions: tasks }; }); }); } var api = { get: addRoute.bind(api, "get"), post: addRoute.bind(api, "post"), put: addRoute.bind(api, "put"), delete: addRoute.bind(api, "delete"), head: addRoute.bind(api, "head"), patch: addRoute.bind(api, "patch"), addRoute: addRoute, handle: handle }; return api; };