fusion-plugin-http-router
Version:
Registers http routes and handlers on the server.
321 lines (266 loc) • 12.3 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var fusionCore = require('fusion-core');
var pathToRegexp = require('path-to-regexp');
var bodyParser = _interopDefault(require('koa-body'));
var browserPlugin = null;
var HttpRouterToken = fusionCore.createToken('HttpRouter');
var HttpHandlersToken = fusionCore.createToken('HttpHandlersToken');
var BodyParserOptionsToken = fusionCore.createToken('BodyParserOptionsToken');
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function matchUri(url, patternedPath) {
var path = patternedPath.path,
keys = patternedPath.keys,
pattern = patternedPath.pattern;
var match = pattern.exec(url);
if (!match) {
return {
isExact: false,
params: {},
path: path
};
}
var values = match.slice(1);
var params = keys.reduce(function (final, name, index) {
var _objectSpread2;
return _objectSpread({}, final, (_objectSpread2 = {}, _objectSpread2[name] = values[index], _objectSpread2));
}, {});
return {
isExact: true,
params: params,
path: path
};
}
function matchPath(url, paths) {
if (!(paths instanceof Array)) {
return matchUri(url, paths);
}
return paths.reduce(function (final, path) {
var match = matchUri(url, path);
if (match.isExact && !final.isExact) {
return match;
}
return final;
}, {
isExact: false,
params: {},
path: ''
});
}
function getPatternedPaths(paths) {
return paths.map(function (path) {
var keys = [];
var pattern = pathToRegexp.pathToRegexp(path, keys);
return {
path: path,
pattern: pattern,
keys: keys.map(function (_ref) {
var name = _ref.name;
return name;
})
};
});
}
function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty$1(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty$1(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var methods = new Set(['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE']);
function dive(currentKey, into, target) {
Object.keys(into).forEach(function (key) {
if (methods.has(key.toUpperCase())) {
target[currentKey] = Object.keys(into).reduce(function (final, key) {
if (methods.has(key.toUpperCase())) {
var _objectSpread2;
return _objectSpread$1({}, final, (_objectSpread2 = {}, _objectSpread2[key.toUpperCase()] = into[key], _objectSpread2));
}
return final;
}, _objectSpread$1({}, target[currentKey]));
} else {
var newKey = key;
var newVal = into[key];
if (currentKey.length > 0) {
newKey = currentKey + key;
}
if (newVal instanceof Object) {
dive(newKey, newVal, target);
} else {
target[newKey] = newVal;
}
}
});
}
function flattenHandlers(handlers) {
var flatHandlers = {};
dive('', handlers, flatHandlers);
return flatHandlers;
}
function getHandler(ctx, paths, handlers) {
var match = matchPath(ctx.path, paths);
var handler = handlers[match.path] && handlers[match.path][ctx.method];
return match.isExact ? {
handler: handler,
match: match
} : {
match: {}
};
}
function findInvalidPath(handlers) {
function findInvalidMethod(path) {
return Object.keys(handlers[path]).find(function (method) {
return typeof handlers[path][method] !== 'function';
});
}
var paths = Object.keys(handlers);
var invalidPath = paths.find(function (path) {
if (handlers[path] instanceof Object) {
return findInvalidMethod(path);
}
return true;
});
if (invalidPath) {
var invalidMethod = findInvalidMethod(invalidPath);
return invalidMethod ? "method \"" + invalidMethod + "\" of path \"" + invalidPath + "\"" : "path \"" + invalidPath + "\"";
}
return '';
}
function ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$2(Object(source), true).forEach(function (key) { _defineProperty$2(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty$2(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
/* eslint-env node */
function comparator(a, b) {
var aLength = a.split(':').length;
var bLength = b.split(':').length;
return aLength < bLength ? -1 : 1;
}
var plugin = fusionCore.createPlugin({
deps: {
bodyParserOptions: BodyParserOptionsToken.optional,
handlers: HttpHandlersToken
},
provides: function provides(deps) {
var handlers = deps.handlers,
_deps$bodyParserOptio = deps.bodyParserOptions,
bodyParserOptions = _deps$bodyParserOptio === void 0 ? {} : _deps$bodyParserOptio;
if (!handlers || _typeof(handlers) !== 'object') {
throw new Error('Missing/incorrect handlers registered to HttpHandlersToken');
}
var flatHandlers = flattenHandlers(handlers);
var paths = Object.keys(flatHandlers).sort(comparator); // eslint-disable-next-line no-console
console.log('\x1b[36m\x1b[1m', 'Registered Paths:\x1b[0m');
paths.forEach(function (path, index) {
var methods = Object.keys(flatHandlers[path]).join(', '); // eslint-disable-next-line no-console
console.log('\x1b[36m', index + 1 + ". " + path + " -> { " + methods + " }", '\x1b[0m');
});
var invalidPath = findInvalidPath(flatHandlers);
if (invalidPath) {
throw new Error("Missing/incorrect handler registered against " + invalidPath + ".");
}
var parseBody = bodyParser(_objectSpread$2({}, bodyParserOptions, {
multipart: true
}));
var patternedPaths = getPatternedPaths(paths);
var from = fusionCore.memoize(function (ctx) {
return new Promise(function ($return, $error) {
var query, _getHandler, _handler, match, _ctx$request, body, _ctx$request$files, files;
query = ctx.query;
_getHandler = getHandler(ctx, patternedPaths, flatHandlers), _handler = _getHandler.handler, match = _getHandler.match;
if (typeof _handler !== 'function') {
return $return({
handler: null,
match: match
});
}
return Promise.resolve(parseBody(ctx, function () {
return Promise.resolve();
})).then(function ($await_3) {
try {
_ctx$request = ctx.request, body = _ctx$request.body, _ctx$request$files = _ctx$request.files, files = _ctx$request$files === void 0 ? {} : _ctx$request$files;
return $return({
handler: function handler() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _handler.apply(void 0, [{
params: match.params,
query: query,
body: body,
files: files
}].concat(args));
},
match: match
});
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
});
});
return {
from: from
};
},
middleware: function middleware(deps, service) {
return function (ctx, next) {
return new Promise(function ($return, $error) {
var _ref, handler;
var $Try_1_Post = function () {
try {
return $return(next());
} catch ($boundEx) {
return $error($boundEx);
}
};
var $Try_1_Catch = function (error) {
try {
ctx.body = {
status: 'failure',
data: {
code: error.code,
message: error.message,
stack: error.stack,
meta: error.meta
}
};
return $Try_1_Post();
} catch ($boundEx) {
return $error($boundEx);
}
};
try {
return Promise.resolve(service.from(ctx)).then(function ($await_4) {
try {
_ref = $await_4, handler = _ref.handler;
if (typeof handler === 'function') {
return Promise.resolve(handler(ctx)).then(function ($await_5) {
try {
ctx.body = $await_5;
return $If_2.call(this);
} catch ($boundEx) {
return $Try_1_Catch($boundEx);
}
}.bind(this), $Try_1_Catch);
}
function $If_2() {
return $Try_1_Post();
}
return $If_2.call(this);
} catch ($boundEx) {
return $Try_1_Catch($boundEx);
}
}.bind(this), $Try_1_Catch);
} catch (error) {
$Try_1_Catch(error);
}
});
};
}
});
var index = browserPlugin;
exports.default = index;
exports.BodyParserOptionsToken = BodyParserOptionsToken;
exports.HttpHandlersToken = HttpHandlersToken;
exports.HttpRouterToken = HttpRouterToken;