UNPKG

@slowvoid.dev/express

Version:

node decorators - decorators for express library

168 lines 20.3 kB
"use strict"; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHByZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFDQUF3RztBQUd4RywyQ0FBd0M7QUFDeEMsaUNBQW1HO0FBQ25HLDZDQUE2RjtBQUU3Rjs7R0FFRztBQUNJLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxHQUFxQixFQUFFLFdBQW1CO0lBQ2hGLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFnQixFQUFFLEVBQUUsQ0FDcEQsa0JBQWtCLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FDbkQsQ0FBQztJQUVGLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUU1QiwyREFBMkQ7SUFDM0QsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFBLG1DQUFzQixHQUFFLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBVEQsOENBU0M7QUFFRDs7R0FFRztBQUNJLEtBQUssVUFBVSx5QkFBeUIsQ0FBQyxHQUFxQixFQUFFLFdBQWlDO0lBQ3RHLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFnQyxFQUFFLEVBQUUsQ0FDcEUsa0JBQWtCLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQXFCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUNsRSxDQUFDO0lBRUYsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTVCLDJEQUEyRDtJQUMzRCxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUEsbUNBQXNCLEdBQUUsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFURCw4REFTQztBQUVEOztHQUVHO0FBQ0gsS0FBSyxVQUFVLGtCQUFrQixDQUMvQixHQUF5QixFQUN6QixVQUFxQyxFQUNyQyxpQkFBcUc7SUFFckcsTUFBTSxVQUFVLEdBQUcsTUFB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SyxFQUFFLEVBQUU7UUFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDckM7U0FBTSxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7S0FDaEU7QUFDSCxDQUFDO0FBUEQsNENBT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXF1ZXN0SGFuZGxlciwgQXBwbGljYXRpb24sIFJvdXRlciwgRXhwcmVzcywgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuXG5pbXBvcnQgeyBUeXBlIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBDb250YWluZXIgfSBmcm9tICcuL2NvbnRhaW5lcic7XG5pbXBvcnQgeyBnZXRNZXRhLCBQYXJhbWV0ZXJUeXBlLCBFeHByZXNzQ2xhc3MsIFBhcmFtZXRlckNvbmZpZ3VyYXRpb24sIEV4cHJlc3NNZXRhIH0gZnJvbSAnLi9tZXRhJztcbmltcG9ydCB7IG1pZGRsZXdhcmVIYW5kbGVyLCBlcnJvck1pZGRsZXdhcmVIYW5kbGVyLCBNaWRkbGV3YXJlRnVuY3Rpb24gfSBmcm9tICcuL21pZGRsZXdhcmUnO1xuXG4vKipcbiAqIEF0dGFjaCBjb250cm9sbGVycyB0byBleHByZXNzIGFwcGxpY2F0aW9uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhdHRhY2hDb250cm9sbGVycyhhcHA6IEV4cHJlc3MgfCBSb3V0ZXIsIGNvbnRyb2xsZXJzOiBUeXBlW10pIHtcbiAgY29uc3QgcHJvbWlzZXMgPSBjb250cm9sbGVycy5tYXAoKGNvbnRyb2xsZXI6IFR5cGUpID0+XG4gICAgcmVnaXN0ZXJDb250cm9sbGVyKGFwcCwgY29udHJvbGxlciwgZ2V0Q29udHJvbGxlciksXG4gICk7XG5cbiAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXG4gIC8vIGVycm9yIG1pZGRsZXdhcmUgbXVzdCBiZSByZWdpc3RlcmVkIGFzIHRoZSB2ZXJ5IGxhc3Qgb25lXG4gIGFwcC51c2UoZXJyb3JNaWRkbGV3YXJlSGFuZGxlcigpKTtcbn1cblxuLyoqXG4gKiBBdHRhY2ggY29udHJvbGxlciBpbnN0YW5jZXMgdG8gZXhwcmVzcyBhcHBsaWNhdGlvblxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXR0YWNoQ29udHJvbGxlckluc3RhbmNlcyhhcHA6IEV4cHJlc3MgfCBSb3V0ZXIsIGNvbnRyb2xsZXJzOiBJbnN0YW5jZVR5cGU8VHlwZT5bXSkge1xuICBjb25zdCBwcm9taXNlcyA9IGNvbnRyb2xsZXJzLm1hcCgoY29udHJvbGxlcjogSW5zdGFuY2VUeXBlPFR5cGU+W10pID0+XG4gICAgcmVnaXN0ZXJDb250cm9sbGVyKGFwcCwgY29udHJvbGxlciwgKGM6IEluc3RhbmNlVHlwZTxUeXBlPikgPT4gYyksXG4gICk7XG5cbiAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXG4gIC8vIGVycm9yIG1pZGRsZXdhcmUgbXVzdCBiZSByZWdpc3RlcmVkIGFzIHRoZSB2ZXJ5IGxhc3Qgb25lXG4gIGFwcC51c2UoZXJyb3JNaWRkbGV3YXJlSGFuZGxlcigpKTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciBjb250cm9sbGVyIHZpYSByZWdpc3RlcmluZyBuZXcgUm91dGVyXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlZ2lzdGVyQ29udHJvbGxlcihcbiAgYXBwOiBBcHBsaWNhdGlvbiB8IFJvdXRlcixcbiAgQ29udHJvbGxlcjogVHlwZSB8IEluc3RhbmNlVHlwZTxUeXBlPixcbiAgZXh0cmFjdENvbnRyb2xsZXI6IChjOiBUeXBlIHwgSW5zdGFuY2VUeXBlPFR5cGU+KSA9PiBQcm9taXNlPEluc3RhbmNlVHlwZTxUeXBlPj4gfCBJbnN0YW5jZVR5cGU8VHlwZT4sXG4pIHtcbiAgY29uc3QgY29udHJvbGxlciA9IGF3YWl0IGV4dHJhY3RDb250cm9sbGVyKENvbnRyb2xsZXIpO1xuICBjb25zdCBtZXRhID0gZ2V0TWV0YShjb250cm9sbGVyKTtcbiAgY29uc3Qgcm91dGVyID0gUm91dGVyKG1ldGEucm91dGVyT3B0aW9ucyk7XG5cbiAgLyoqXG4gICAqIFdyYXAgYWxsIHJlZ2lzdGVyZWQgbWlkZGxld2FyZSB3aXRoIGhlbHBlciBmdW5jdGlvblxuICAgKiB0aGF0IGNhbiBpbnN0YW50aWF0ZSBvciBnZXQgZnJvbSB0aGUgY29udGFpbmVyIGluc3RhbmNlIG9mIHRoZSBjbGFzc1xuICAgKiBvciBleGVjdXRlIGdpdmVuIG1pZGRsZXdhcmUgZnVuY3Rpb25cbiAgICovXG4gIGNvbnN0IHJvdXRlck1pZGRsZXdhcmU6IFJlcXVlc3RIYW5kbGVyW10gPSAobWV0YS5taWRkbGV3YXJlIHx8IFtdKVxuICAgIC5tYXAobWlkZGxld2FyZSA9PiBtaWRkbGV3YXJlSGFuZGxlcihtaWRkbGV3YXJlKSk7XG5cbiAgLyoqXG4gICAqIEFwcGx5IHJvdXRlciBtaWRkbGV3YXJlXG4gICAqL1xuICBpZiAocm91dGVyTWlkZGxld2FyZS5sZW5ndGgpIHtcbiAgICByb3V0ZXIudXNlKC4uLnJvdXRlck1pZGRsZXdhcmUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5aW5nIHJlZ2lzdGVyZWQgcm91dGVzXG4gICAqL1xuICBmb3IgKGNvbnN0IFttZXRob2ROYW1lLCBtZXRob2RNZXRhXSBvZiBPYmplY3QuZW50cmllcyhtZXRhLnJvdXRlcykpIHtcbiAgICBtZXRob2RNZXRhLnJvdXRlcy5mb3JFYWNoKHJvdXRlID0+IHtcbiAgICAgIGNvbnN0IHJvdXRlTWlkZGxld2FyZTogUmVxdWVzdEhhbmRsZXJbXSA9IChyb3V0ZS5taWRkbGV3YXJlIHx8IFtdKVxuICAgICAgICAubWFwKG1pZGRsZXdhcmUgPT4gbWlkZGxld2FyZUhhbmRsZXIobWlkZGxld2FyZSkpO1xuICAgICAgY29uc3QgaGFuZGxlciA9IHJvdXRlSGFuZGxlcihjb250cm9sbGVyLCBtZXRob2ROYW1lLCBtZXRhLnBhcmFtc1ttZXRob2ROYW1lXSwgbWV0aG9kTWV0YS5zdGF0dXMpO1xuXG4gICAgICByb3V0ZXJbcm91dGUubWV0aG9kXS5hcHBseShyb3V0ZXIsIFtcbiAgICAgICAgcm91dGUudXJsLCAuLi5yb3V0ZU1pZGRsZXdhcmUsIGhhbmRsZXIsXG4gICAgICBdKTtcbiAgICB9KTtcbiAgfVxuXG4gIChhcHAgYXMgUm91dGVyKS51c2UobWV0YS51cmwsIHJvdXRlcik7XG5cbiAgcmV0dXJuIGFwcDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGZ1bmN0aW9uIHRoYXQgd2lsbCBjYWxsIG9yaWdpbmFsIHJvdXRlIGhhbmRsZXIgYW5kIHdyYXAgcmV0dXJuIG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gcm91dGVIYW5kbGVyKGNvbnRyb2xsZXI6IEV4cHJlc3NDbGFzcywgbWV0aG9kTmFtZTogc3RyaW5nLCBwYXJhbXM6IFBhcmFtZXRlckNvbmZpZ3VyYXRpb25bXSwgc3RhdHVzOiBudW1iZXIpIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIGNvbnN0IGFyZ3MgPSBleHRyYWN0UGFyYW1ldGVycyhyZXEsIHJlcywgbmV4dCwgcGFyYW1zKTtcbiAgICBjb25zdCByZXN1bHQgPSBjb250cm9sbGVyW21ldGhvZE5hbWVdLmNhbGwoY29udHJvbGxlciwgLi4uYXJncyk7XG5cbiAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgcmVzdWx0LnRoZW4oKHI6IGFueSkgPT4ge1xuICAgICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCAmJiB0eXBlb2YgciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZiAoc3RhdHVzKSB7XG4gICAgICAgICAgICByZXMuc3RhdHVzKHN0YXR1cyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlcy5zZW5kKHIpO1xuICAgICAgICB9XG4gICAgICB9KS5jYXRjaChuZXh0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiByZXN1bHQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICBpZiAoc3RhdHVzKSB7XG4gICAgICAgICAgcmVzLnN0YXR1cyhzdGF0dXMpO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zZW5kKHJlc3VsdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0IHBhcmFtZXRlcnMgZm9yIGhhbmRsZXJzXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RQYXJhbWV0ZXJzKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uLCBwYXJhbXM6IFBhcmFtZXRlckNvbmZpZ3VyYXRpb25bXSA9IFtdKTogYW55W10ge1xuICBjb25zdCBhcmdzID0gW107XG5cbiAgZm9yIChjb25zdCB7IG5hbWUsIGluZGV4LCB0eXBlIH0gb2YgcGFyYW1zKSB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFBhcmFtZXRlclR5cGUuUkVTUE9OU0U6XG4gICAgICAgIGFyZ3NbaW5kZXhdID0gcmVzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyYW1ldGVyVHlwZS5SRVFVRVNUOlxuICAgICAgICBhcmdzW2luZGV4XSA9IGdldFBhcmFtKHJlcSwgbnVsbCwgbmFtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQYXJhbWV0ZXJUeXBlLk5FWFQ6XG4gICAgICAgIGFyZ3NbaW5kZXhdID0gbmV4dDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBhcmFtZXRlclR5cGUuUEFSQU1TOlxuICAgICAgICBhcmdzW2luZGV4XSA9IGdldFBhcmFtKHJlcSwgJ3BhcmFtcycsIG5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyYW1ldGVyVHlwZS5RVUVSWTpcbiAgICAgICAgYXJnc1tpbmRleF0gPSBnZXRQYXJhbShyZXEsICdxdWVyeScsIG5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyYW1ldGVyVHlwZS5CT0RZOlxuICAgICAgICBhcmdzW2luZGV4XSA9IGdldFBhcmFtKHJlcSwgJ2JvZHknLCBuYW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBhcmFtZXRlclR5cGUuSEVBREVSUzpcbiAgICAgICAgYXJnc1tpbmRleF0gPSBnZXRQYXJhbShyZXEsICdoZWFkZXJzJywgbmFtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQYXJhbWV0ZXJUeXBlLkNPT0tJRVM6XG4gICAgICAgIGFyZ3NbaW5kZXhdID0gZ2V0UGFyYW0ocmVxLCAnY29va2llcycsIG5hbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBHZXQgY29udHJvbGxlciBpbnN0YW5jZSBmcm9tIGNvbnRhaW5lciBvciBpbnN0YW50aWF0ZSBvbmVcbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0Q29udHJvbGxlcihDb250cm9sbGVyOiBUeXBlKTogUHJvbWlzZTxFeHByZXNzQ2xhc3M+IHtcbiAgdHJ5IHtcbiAgICBpZiAoIUNvbnRhaW5lci5oYXMoQ29udHJvbGxlcikpIHtcbiAgICAgIENvbnRhaW5lci5wcm92aWRlKFt7XG4gICAgICAgIHByb3ZpZGU6IENvbnRyb2xsZXIsXG4gICAgICAgIHVzZUNsYXNzOiBDb250cm9sbGVyLFxuICAgICAgfV0pO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBDb250YWluZXIuZ2V0KENvbnRyb2xsZXIpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbmV3IENvbnRyb2xsZXIoKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCBwYXJhbWV0ZXIgdmFsdWUgZnJvbSB0aGUgc291cmNlIG9iamVjdFxuICovXG5mdW5jdGlvbiBnZXRQYXJhbShzb3VyY2U6IGFueSwgcGFyYW1UeXBlOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IGFueSB7XG4gIGNvbnN0IHBhcmFtID0gc291cmNlW3BhcmFtVHlwZV0gfHwgc291cmNlO1xuXG4gIHJldHVybiBuYW1lID8gcGFyYW1bbmFtZV0gOiBwYXJhbTtcbn1cblxuXG5cbi8qKlxuICogQXR0YWNoIG1pZGRsZXdhcmUgdG8gY29udHJvbGxlciBtZXRhZGF0YVxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gdW5zaGlmdCBpZiBzZXQgdG8gZmFsc2UgYWxsIHRoZSBjdXN0b20gZGVjb3JhdG9yIG1pZGRsZXdhcmVzIHdpbGwgYmUgZXhlY3R1dGVkIGFmdGVyIHRoZSBtaWRkbGV3YXJlcyBhdHRhY2hlZCB0aHJvdWdoIGNvbnRyb2xsZXJcbiAqXG4gKiBOb3RlLSBQbGVhc2UgdXNlIGN1c3RvbSBkZWNvcmF0b3JzIGJlZm9yZSBleHByZXNzIG1ldGhvZCBkZWNvcmF0b3JzIEdldCBQb3N0IGV0Yy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaE1pZGRsZXdhcmUodGFyZ2V0OiBhbnksIHByb3BlcnR5OiBzdHJpbmcsIG1pZGRsZXdhcmU6IE1pZGRsZXdhcmVGdW5jdGlvbikge1xuICBjb25zdCBtZXRhOiBFeHByZXNzTWV0YSA9IGdldE1ldGEodGFyZ2V0IGFzIEV4cHJlc3NDbGFzcyk7XG4gIGlmIChtZXRhLnVybCAhPT0gJycpIHtcbiAgICBtZXRhLm1pZGRsZXdhcmUudW5zaGlmdChtaWRkbGV3YXJlKTtcbiAgfSBlbHNlIGlmIChwcm9wZXJ0eSBpbiBtZXRhLnJvdXRlcykge1xuICAgIG1ldGEucm91dGVzW3Byb3BlcnR5XS5yb3V0ZXNbMF0ubWlkZGxld2FyZS51bnNoaWZ0KG1pZGRsZXdhcmUpO1xuICB9XG59XG4iXX0=