@slowvoid.dev/express
Version:
node decorators - decorators for express library
168 lines • 20.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.attachMiddleware = exports.attachControllerInstances = exports.attachControllers = void 0;
const express_1 = require("express");
const container_1 = require("./container");
const meta_1 = require("./meta");
const middleware_1 = require("./middleware");
/**
* Attach controllers to express application
*/
async function attachControllers(app, controllers) {
const promises = controllers.map((controller) => registerController(app, controller, getController));
await Promise.all(promises);
// error middleware must be registered as the very last one
app.use((0, middleware_1.errorMiddlewareHandler)());
}
exports.attachControllers = attachControllers;
/**
* Attach controller instances to express application
*/
async function attachControllerInstances(app, controllers) {
const promises = controllers.map((controller) => registerController(app, controller, (c) => c));
await Promise.all(promises);
// error middleware must be registered as the very last one
app.use((0, middleware_1.errorMiddlewareHandler)());
}
exports.attachControllerInstances = attachControllerInstances;
/**
* Register controller via registering new Router
*/
async function registerController(app, Controller, extractController) {
const controller = await extractController(Controller);
const meta = (0, meta_1.getMeta)(controller);
const router = (0, express_1.Router)(meta.routerOptions);
/**
* Wrap all registered middleware with helper function
* that can instantiate or get from the container instance of the class
* or execute given middleware function
*/
const routerMiddleware = (meta.middleware || [])
.map(middleware => (0, middleware_1.middlewareHandler)(middleware));
/**
* Apply router middleware
*/
if (routerMiddleware.length) {
router.use(...routerMiddleware);
}
/**
* Applying registered routes
*/
for (const [methodName, methodMeta] of Object.entries(meta.routes)) {
methodMeta.routes.forEach(route => {
const routeMiddleware = (route.middleware || [])
.map(middleware => (0, middleware_1.middlewareHandler)(middleware));
const handler = routeHandler(controller, methodName, meta.params[methodName], methodMeta.status);
router[route.method].apply(router, [
route.url, ...routeMiddleware, handler,
]);
});
}
app.use(meta.url, router);
return app;
}
/**
* Returns function that will call original route handler and wrap return options
*/
function routeHandler(controller, methodName, params, status) {
return (req, res, next) => {
const args = extractParameters(req, res, next, params);
const result = controller[methodName].call(controller, ...args);
if (result instanceof Promise) {
result.then((r) => {
if (!res.headersSent && typeof r !== 'undefined') {
if (status) {
res.status(status);
}
res.send(r);
}
}).catch(next);
}
else if (typeof result !== 'undefined') {
if (!res.headersSent) {
if (status) {
res.status(status);
}
res.send(result);
}
}
return result;
};
}
/**
* Extract parameters for handlers
*/
function extractParameters(req, res, next, params = []) {
const args = [];
for (const { name, index, type } of params) {
switch (type) {
case meta_1.ParameterType.RESPONSE:
args[index] = res;
break;
case meta_1.ParameterType.REQUEST:
args[index] = getParam(req, null, name);
break;
case meta_1.ParameterType.NEXT:
args[index] = next;
break;
case meta_1.ParameterType.PARAMS:
args[index] = getParam(req, 'params', name);
break;
case meta_1.ParameterType.QUERY:
args[index] = getParam(req, 'query', name);
break;
case meta_1.ParameterType.BODY:
args[index] = getParam(req, 'body', name);
break;
case meta_1.ParameterType.HEADERS:
args[index] = getParam(req, 'headers', name);
break;
case meta_1.ParameterType.COOKIES:
args[index] = getParam(req, 'cookies', name);
break;
}
}
return args;
}
/**
* Get controller instance from container or instantiate one
*/
async function getController(Controller) {
try {
if (!container_1.Container.has(Controller)) {
container_1.Container.provide([{
provide: Controller,
useClass: Controller,
}]);
}
return await container_1.Container.get(Controller);
}
catch (_a) {
return new Controller();
}
}
/**
* Get parameter value from the source object
*/
function getParam(source, paramType, name) {
const param = source[paramType] || source;
return name ? param[name] : param;
}
/**
* Attach middleware to controller metadata
*
* @param {boolean} unshift if set to false all the custom decorator middlewares will be exectuted after the middlewares attached through controller
*
* Note- Please use custom decorators before express method decorators Get Post etc.
*/
function attachMiddleware(target, property, middleware) {
const meta = (0, meta_1.getMeta)(target);
if (meta.url !== '') {
meta.middleware.unshift(middleware);
}
else if (property in meta.routes) {
meta.routes[property].routes[0].middleware.unshift(middleware);
}
}
exports.attachMiddleware = attachMiddleware;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHByZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFDQUF3RztBQUd4RywyQ0FBd0M7QUFDeEMsaUNBQW1HO0FBQ25HLDZDQUE2RjtBQUU3Rjs7R0FFRztBQUNJLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxHQUFxQixFQUFFLFdBQW1CO0lBQ2hGLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFnQixFQUFFLEVBQUUsQ0FDcEQsa0JBQWtCLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FDbkQsQ0FBQztJQUVGLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUU1QiwyREFBMkQ7SUFDM0QsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFBLG1DQUFzQixHQUFFLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBVEQsOENBU0M7QUFFRDs7R0FFRztBQUNJLEtBQUssVUFBVSx5QkFBeUIsQ0FBQyxHQUFxQixFQUFFLFdBQWlDO0lBQ3RHLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFnQyxFQUFFLEVBQUUsQ0FDcEUsa0JBQWtCLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQXFCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUNsRSxDQUFDO0lBRUYsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTVCLDJEQUEyRDtJQUMzRCxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUEsbUNBQXNCLEdBQUUsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFURCw4REFTQztBQUVEOztHQUVHO0FBQ0gsS0FBSyxVQUFVLGtCQUFrQixDQUMvQixHQUF5QixFQUN6QixVQUFxQyxFQUNyQyxpQkFBcUc7SUFFckcsTUFBTSxVQUFVLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN2RCxNQUFNLElBQUksR0FBRyxJQUFBLGNBQU8sRUFBQyxVQUFVLENBQUMsQ0FBQztJQUNqQyxNQUFNLE1BQU0sR0FBRyxJQUFBLGdCQUFNLEVBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRTFDOzs7O09BSUc7SUFDSCxNQUFNLGdCQUFnQixHQUFxQixDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDO1NBQy9ELEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUEsOEJBQWlCLEVBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUVwRDs7T0FFRztJQUNILElBQUksZ0JBQWdCLENBQUMsTUFBTSxFQUFFO1FBQzNCLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQ2pDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLE1BQU0sQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDbEUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDaEMsTUFBTSxlQUFlLEdBQXFCLENBQUMsS0FBSyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7aUJBQy9ELEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUEsOEJBQWlCLEVBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUNwRCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUVqRyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUU7Z0JBQ2pDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRyxlQUFlLEVBQUUsT0FBTzthQUN2QyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztLQUNKO0lBRUEsR0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRXRDLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxZQUFZLENBQUMsVUFBd0IsRUFBRSxVQUFrQixFQUFFLE1BQWdDLEVBQUUsTUFBYztJQUNsSCxPQUFPLENBQUMsR0FBWSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFFLEVBQUU7UUFDekQsTUFBTSxJQUFJLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdkQsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUVoRSxJQUFJLE1BQU0sWUFBWSxPQUFPLEVBQUU7WUFDN0IsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFO2dCQUNyQixJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsS0FBSyxXQUFXLEVBQUU7b0JBQ2hELElBQUksTUFBTSxFQUFFO3dCQUNWLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7cUJBQ3BCO29CQUNELEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ2I7WUFDSCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDaEI7YUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRTtZQUN4QyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRTtnQkFDcEIsSUFBSSxNQUFNLEVBQUU7b0JBQ1YsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztpQkFDcEI7Z0JBQ0QsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUNsQjtTQUNGO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxHQUFZLEVBQUUsR0FBYSxFQUFFLElBQWtCLEVBQUUsU0FBbUMsRUFBRTtJQUMvRyxNQUFNLElBQUksR0FBRyxFQUFFLENBQUM7SUFFaEIsS0FBSyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxNQUFNLEVBQUU7UUFDMUMsUUFBUSxJQUFJLEVBQUU7WUFDWixLQUFLLG9CQUFhLENBQUMsUUFBUTtnQkFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQztnQkFDbEIsTUFBTTtZQUNSLEtBQUssb0JBQWEsQ0FBQyxPQUFPO2dCQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3hDLE1BQU07WUFDUixLQUFLLG9CQUFhLENBQUMsSUFBSTtnQkFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztnQkFDbkIsTUFBTTtZQUNSLEtBQUssb0JBQWEsQ0FBQyxNQUFNO2dCQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzVDLE1BQU07WUFDUixLQUFLLG9CQUFhLENBQUMsS0FBSztnQkFDdEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMzQyxNQUFNO1lBQ1IsS0FBSyxvQkFBYSxDQUFDLElBQUk7Z0JBQ3JCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDMUMsTUFBTTtZQUNSLEtBQUssb0JBQWEsQ0FBQyxPQUFPO2dCQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzdDLE1BQU07WUFDUixLQUFLLG9CQUFhLENBQUMsT0FBTztnQkFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUM3QyxNQUFNO1NBQ1Q7S0FDRjtJQUVELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOztHQUVHO0FBQ0gsS0FBSyxVQUFVLGFBQWEsQ0FBQyxVQUFnQjtJQUMzQyxJQUFJO1FBQ0YsSUFBSSxDQUFDLHFCQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQzlCLHFCQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ2pCLE9BQU8sRUFBRSxVQUFVO29CQUNuQixRQUFRLEVBQUUsVUFBVTtpQkFDckIsQ0FBQyxDQUFDLENBQUM7U0FDTDtRQUVELE9BQU8sTUFBTSxxQkFBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztLQUN4QztJQUFDLFdBQU07UUFDTixPQUFPLElBQUksVUFBVSxFQUFFLENBQUM7S0FDekI7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFFBQVEsQ0FBQyxNQUFXLEVBQUUsU0FBaUIsRUFBRSxJQUFZO0lBQzVELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxNQUFNLENBQUM7SUFFMUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ3BDLENBQUM7QUFJRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxNQUFXLEVBQUUsUUFBZ0IsRUFBRSxVQUE4QjtJQUM1RixNQUFNLElBQUksR0FBZ0IsSUFBQSxjQUFPLEVBQUMsTUFBc0IsQ0FBQyxDQUFDO0lBQzFELElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxFQUFFLEVBQUU7UUFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDckM7U0FBTSxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDaEU7QUFDSCxDQUFDO0FBUEQsNENBT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXF1ZXN0SGFuZGxlciwgQXBwbGljYXRpb24sIFJvdXRlciwgRXhwcmVzcywgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuXG5pbXBvcnQgeyBUeXBlIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBDb250YWluZXIgfSBmcm9tICcuL2NvbnRhaW5lcic7XG5pbXBvcnQgeyBnZXRNZXRhLCBQYXJhbWV0ZXJUeXBlLCBFeHByZXNzQ2xhc3MsIFBhcmFtZXRlckNvbmZpZ3VyYXRpb24sIEV4cHJlc3NNZXRhIH0gZnJvbSAnLi9tZXRhJztcbmltcG9ydCB7IG1pZGRsZXdhcmVIYW5kbGVyLCBlcnJvck1pZGRsZXdhcmVIYW5kbGVyLCBNaWRkbGV3YXJlRnVuY3Rpb24gfSBmcm9tICcuL21pZGRsZXdhcmUnO1xuXG4vKipcbiAqIEF0dGFjaCBjb250cm9sbGVycyB0byBleHByZXNzIGFwcGxpY2F0aW9uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhdHRhY2hDb250cm9sbGVycyhhcHA6IEV4cHJlc3MgfCBSb3V0ZXIsIGNvbnRyb2xsZXJzOiBUeXBlW10pIHtcbiAgY29uc3QgcHJvbWlzZXMgPSBjb250cm9sbGVycy5tYXAoKGNvbnRyb2xsZXI6IFR5cGUpID0+XG4gICAgcmVnaXN0ZXJDb250cm9sbGVyKGFwcCwgY29udHJvbGxlciwgZ2V0Q29udHJvbGxlciksXG4gICk7XG5cbiAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXG4gIC8vIGVycm9yIG1pZGRsZXdhcmUgbXVzdCBiZSByZWdpc3RlcmVkIGFzIHRoZSB2ZXJ5IGxhc3Qgb25lXG4gIGFwcC51c2UoZXJyb3JNaWRkbGV3YXJlSGFuZGxlcigpKTtcbn1cblxuLyoqXG4gKiBBdHRhY2ggY29udHJvbGxlciBpbnN0YW5jZXMgdG8gZXhwcmVzcyBhcHBsaWNhdGlvblxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXR0YWNoQ29udHJvbGxlckluc3RhbmNlcyhhcHA6IEV4cHJlc3MgfCBSb3V0ZXIsIGNvbnRyb2xsZXJzOiBJbnN0YW5jZVR5cGU8VHlwZT5bXSkge1xuICBjb25zdCBwcm9taXNlcyA9IGNvbnRyb2xsZXJzLm1hcCgoY29udHJvbGxlcjogSW5zdGFuY2VUeXBlPFR5cGU+W10pID0+XG4gICAgcmVnaXN0ZXJDb250cm9sbGVyKGFwcCwgY29udHJvbGxlciwgKGM6IEluc3RhbmNlVHlwZTxUeXBlPikgPT4gYyksXG4gICk7XG5cbiAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXG4gIC8vIGVycm9yIG1pZGRsZXdhcmUgbXVzdCBiZSByZWdpc3RlcmVkIGFzIHRoZSB2ZXJ5IGxhc3Qgb25lXG4gIGFwcC51c2UoZXJyb3JNaWRkbGV3YXJlSGFuZGxlcigpKTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciBjb250cm9sbGVyIHZpYSByZWdpc3RlcmluZyBuZXcgUm91dGVyXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlZ2lzdGVyQ29udHJvbGxlcihcbiAgYXBwOiBBcHBsaWNhdGlvbiB8IFJvdXRlcixcbiAgQ29udHJvbGxlcjogVHlwZSB8IEluc3RhbmNlVHlwZTxUeXBlPixcbiAgZXh0cmFjdENvbnRyb2xsZXI6IChjOiBUeXBlIHwgSW5zdGFuY2VUeXBlPFR5cGU+KSA9PiBQcm9taXNlPEluc3RhbmNlVHlwZTxUeXBlPj4gfCBJbnN0YW5jZVR5cGU8VHlwZT4sXG4pIHtcbiAgY29uc3QgY29udHJvbGxlciA9IGF3YWl0IGV4dHJhY3RDb250cm9sbGVyKENvbnRyb2xsZXIpO1xuICBjb25zdCBtZXRhID0gZ2V0TWV0YShjb250cm9sbGVyKTtcbiAgY29uc3Qgcm91dGVyID0gUm91dGVyKG1ldGEucm91dGVyT3B0aW9ucyk7XG5cbiAgLyoqXG4gICAqIFdyYXAgYWxsIHJlZ2lzdGVyZWQgbWlkZGxld2FyZSB3aXRoIGhlbHBlciBmdW5jdGlvblxuICAgKiB0aGF0IGNhbiBpbnN0YW50aWF0ZSBvciBnZXQgZnJvbSB0aGUgY29udGFpbmVyIGluc3RhbmNlIG9mIHRoZSBjbGFzc1xuICAgKiBvciBleGVjdXRlIGdpdmVuIG1pZGRsZXdhcmUgZnVuY3Rpb25cbiAgICovXG4gIGNvbnN0IHJvdXRlck1pZGRsZXdhcmU6IFJlcXVlc3RIYW5kbGVyW10gPSAobWV0YS5taWRkbGV3YXJlIHx8IFtdKVxuICAgIC5tYXAobWlkZGxld2FyZSA9PiBtaWRkbGV3YXJlSGFuZGxlcihtaWRkbGV3YXJlKSk7XG5cbiAgLyoqXG4gICAqIEFwcGx5IHJvdXRlciBtaWRkbGV3YXJlXG4gICAqL1xuICBpZiAocm91dGVyTWlkZGxld2FyZS5sZW5ndGgpIHtcbiAgICByb3V0ZXIudXNlKC4uLnJvdXRlck1pZGRsZXdhcmUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5aW5nIHJlZ2lzdGVyZWQgcm91dGVzXG4gICAqL1xuICBmb3IgKGNvbnN0IFttZXRob2ROYW1lLCBtZXRob2RNZXRhXSBvZiBPYmplY3QuZW50cmllcyhtZXRhLnJvdXRlcykpIHtcbiAgICBtZXRob2RNZXRhLnJvdXRlcy5mb3JFYWNoKHJvdXRlID0+IHtcbiAgICAgIGNvbnN0IHJvdXRlTWlkZGxld2FyZTogUmVxdWVzdEhhbmRsZXJbXSA9IChyb3V0ZS5taWRkbGV3YXJlIHx8IFtdKVxuICAgICAgICAubWFwKG1pZGRsZXdhcmUgPT4gbWlkZGxld2FyZUhhbmRsZXIobWlkZGxld2FyZSkpO1xuICAgICAgY29uc3QgaGFuZGxlciA9IHJvdXRlSGFuZGxlcihjb250cm9sbGVyLCBtZXRob2ROYW1lLCBtZXRhLnBhcmFtc1ttZXRob2ROYW1lXSwgbWV0aG9kTWV0YS5zdGF0dXMpO1xuXG4gICAgICByb3V0ZXJbcm91dGUubWV0aG9kXS5hcHBseShyb3V0ZXIsIFtcbiAgICAgICAgcm91dGUudXJsLCAuLi5yb3V0ZU1pZGRsZXdhcmUsIGhhbmRsZXIsXG4gICAgICBdKTtcbiAgICB9KTtcbiAgfVxuXG4gIChhcHAgYXMgUm91dGVyKS51c2UobWV0YS51cmwsIHJvdXRlcik7XG5cbiAgcmV0dXJuIGFwcDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGZ1bmN0aW9uIHRoYXQgd2lsbCBjYWxsIG9yaWdpbmFsIHJvdXRlIGhhbmRsZXIgYW5kIHdyYXAgcmV0dXJuIG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gcm91dGVIYW5kbGVyKGNvbnRyb2xsZXI6IEV4cHJlc3NDbGFzcywgbWV0aG9kTmFtZTogc3RyaW5nLCBwYXJhbXM6IFBhcmFtZXRlckNvbmZpZ3VyYXRpb25bXSwgc3RhdHVzOiBudW1iZXIpIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBleHRyYWN0UGFyYW1ldGVycyhyZXEsIHJlcywgbmV4dCwgcGFyYW1zKTtcbiAgICBjb25zdCByZXN1bHQgPSBjb250cm9sbGVyW21ldGhvZE5hbWVdLmNhbGwoY29udHJvbGxlciwgLi4uYXJncyk7XG5cbiAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgcmVzdWx0LnRoZW4oKHI6IGFueSkgPT4ge1xuICAgICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCAmJiB0eXBlb2YgciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZiAoc3RhdHVzKSB7XG4gICAgICAgICAgICByZXMuc3RhdHVzKHN0YXR1cyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlcy5zZW5kKHIpO1xuICAgICAgICB9XG4gICAgICB9KS5jYXRjaChuZXh0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiByZXN1bHQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICBpZiAoc3RhdHVzKSB7XG4gICAgICAgICAgcmVzLnN0YXR1cyhzdGF0dXMpO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zZW5kKHJlc3VsdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0IHBhcmFtZXRlcnMgZm9yIGhhbmRsZXJzXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RQYXJhbWV0ZXJzKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uLCBwYXJhbXM6IFBhcmFtZXRlckNvbmZpZ3VyYXRpb25bXSA9IFtdKTogYW55W10ge1xuICBjb25zdCBhcmdzID0gW107XG5cbiAgZm9yIChjb25zdCB7IG5hbWUsIGluZGV4LCB0eXBlIH0gb2YgcGFyYW1zKSB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFBhcmFtZXRlclR5cGUuUkVTUE9OU0U6XG4gICAgICAgIGFyZ3NbaW5kZXhdID0gcmVzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyYW1ldGVyVHlwZS5SRVFVRVNUOlxuICAgICAgICBhcmdzW2luZGV4XSA9IGdldFBhcmFtKHJlcSwgbnVsbCwgbmFtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQYXJhbWV0ZXJUeXBlLk5FWFQ6XG4gICAgICAgIGFyZ3NbaW5kZXhdID0gbmV4dDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBhcmFtZXRlclR5cGUuUEFSQU1TOlxuICAgICAgICBhcmdzW2luZGV4XSA9IGdldFBhcmFtKHJlcSwgJ3BhcmFtcycsIG5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyYW1ldGVyVHlwZS5RVUVSWTpcbiAgICAgICAgYXJnc1tpbmRleF0gPSBnZXRQYXJhbShyZXEsICdxdWVyeScsIG5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyYW1ldGVyVHlwZS5CT0RZOlxuICAgICAgICBhcmdzW2luZGV4XSA9IGdldFBhcmFtKHJlcSwgJ2JvZHknLCBuYW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBhcmFtZXRlclR5cGUuSEVBREVSUzpcbiAgICAgICAgYXJnc1tpbmRleF0gPSBnZXRQYXJhbShyZXEsICdoZWFkZXJzJywgbmFtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQYXJhbWV0ZXJUeXBlLkNPT0tJRVM6XG4gICAgICAgIGFyZ3NbaW5kZXhdID0gZ2V0UGFyYW0ocmVxLCAnY29va2llcycsIG5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBHZXQgY29udHJvbGxlciBpbnN0YW5jZSBmcm9tIGNvbnRhaW5lciBvciBpbnN0YW50aWF0ZSBvbmVcbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0Q29udHJvbGxlcihDb250cm9sbGVyOiBUeXBlKTogUHJvbWlzZTxFeHByZXNzQ2xhc3M+IHtcbiAgdHJ5IHtcbiAgICBpZiAoIUNvbnRhaW5lci5oYXMoQ29udHJvbGxlcikpIHtcbiAgICAgIENvbnRhaW5lci5wcm92aWRlKFt7XG4gICAgICAgIHByb3ZpZGU6IENvbnRyb2xsZXIsXG4gICAgICAgIHVzZUNsYXNzOiBDb250cm9sbGVyLFxuICAgICAgfV0pO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBDb250YWluZXIuZ2V0KENvbnRyb2xsZXIpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbmV3IENvbnRyb2xsZXIoKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCBwYXJhbWV0ZXIgdmFsdWUgZnJvbSB0aGUgc291cmNlIG9iamVjdFxuICovXG5mdW5jdGlvbiBnZXRQYXJhbShzb3VyY2U6IGFueSwgcGFyYW1UeXBlOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IGFueSB7XG4gIGNvbnN0IHBhcmFtID0gc291cmNlW3BhcmFtVHlwZV0gfHwgc291cmNlO1xuXG4gIHJldHVybiBuYW1lID8gcGFyYW1bbmFtZV0gOiBwYXJhbTtcbn1cblxuXG5cbi8qKlxuICogQXR0YWNoIG1pZGRsZXdhcmUgdG8gY29udHJvbGxlciBtZXRhZGF0YVxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gdW5zaGlmdCBpZiBzZXQgdG8gZmFsc2UgYWxsIHRoZSBjdXN0b20gZGVjb3JhdG9yIG1pZGRsZXdhcmVzIHdpbGwgYmUgZXhlY3R1dGVkIGFmdGVyIHRoZSBtaWRkbGV3YXJlcyBhdHRhY2hlZCB0aHJvdWdoIGNvbnRyb2xsZXJcbiAqXG4gKiBOb3RlLSBQbGVhc2UgdXNlIGN1c3RvbSBkZWNvcmF0b3JzIGJlZm9yZSBleHByZXNzIG1ldGhvZCBkZWNvcmF0b3JzIEdldCBQb3N0IGV0Yy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaE1pZGRsZXdhcmUodGFyZ2V0OiBhbnksIHByb3BlcnR5OiBzdHJpbmcsIG1pZGRsZXdhcmU6IE1pZGRsZXdhcmVGdW5jdGlvbikge1xuICBjb25zdCBtZXRhOiBFeHByZXNzTWV0YSA9IGdldE1ldGEodGFyZ2V0IGFzIEV4cHJlc3NDbGFzcyk7XG4gIGlmIChtZXRhLnVybCAhPT0gJycpIHtcbiAgICBtZXRhLm1pZGRsZXdhcmUudW5zaGlmdChtaWRkbGV3YXJlKTtcbiAgfSBlbHNlIGlmIChwcm9wZXJ0eSBpbiBtZXRhLnJvdXRlcykge1xuICAgIG1ldGEucm91dGVzW3Byb3BlcnR5XS5yb3V0ZXNbMF0ubWlkZGxld2FyZS51bnNoaWZ0KG1pZGRsZXdhcmUpO1xuICB9XG59XG4iXX0=