@tsclean/core
Version:
Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.
135 lines • 23.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketsController = void 0;
const rxjs_1 = require("rxjs");
const services_1 = require("../services");
const gateway_metadata_explorer_1 = require("./gateway-metadata-explorer");
const app_1 = require("../app");
const helpers_1 = require("../helpers");
const invalid_socket_port_exception_1 = require("./errors/invalid-socket-port.exception");
const compare_element_util_1 = require("./utils/compare-element.util");
class WebSocketsController {
constructor(socketServerProvider, config, contextCreator, graphInspector, appOptions = {}) {
this.socketServerProvider = socketServerProvider;
this.config = config;
this.contextCreator = contextCreator;
this.graphInspector = graphInspector;
this.appOptions = appOptions;
this.logger = new services_1.Logger(WebSocketsController.name, {
timestamp: true
});
this.metadataExplorer = new gateway_metadata_explorer_1.GatewayMetadataExplorer(new app_1.MetadataScanner());
}
connectGatewayToServer(instance, metatype, moduleKey, instanceWrapperId) {
const options = Reflect.getMetadata(helpers_1.GATEWAY_OPTIONS, metatype) || {};
const port = Reflect.getMetadata(helpers_1.PORT_METADATA, metatype) || 0;
if (!Number.isInteger(port)) {
throw new invalid_socket_port_exception_1.InvalidSocketPortException(port, metatype);
}
this.subscribeToServerEvents(instance, options, port, moduleKey, instanceWrapperId);
}
subscribeToServerEvents(instance, options, port, moduleKey, instanceWrapperId) {
const nativeMessageHandlers = this.metadataExplorer.explore(instance);
const messageHandlers = nativeMessageHandlers.map(({ callback, message, methodName }) => ({
message,
methodName,
callback: this.contextCreator.create(instance, callback, moduleKey, methodName)
}));
this.inspectEntrypointDefinitions(instance, port, messageHandlers, instanceWrapperId);
if (this.appOptions.preview) {
return;
}
const observableServer = this.socketServerProvider.scanForSocketServer(options, port);
this.assignServerToProperties(instance, observableServer.server);
this.subscribeEvents(instance, messageHandlers, observableServer);
}
subscribeEvents(instance, subscribersMap, observableServer) {
const { init, disconnect, connection, server } = observableServer;
const adapter = this.config.getIoAdapter();
this.subscribeInitEvent(instance, init);
this.subscribeConnectionEvent(instance, connection);
this.subscribeDisconnectEvent(instance, disconnect);
const handler = this.getConnectionHandler(this, instance, subscribersMap, disconnect, connection);
adapter.bindClientConnect(server, handler);
this.printSubscriptionLogs(instance, subscribersMap);
}
getConnectionHandler(context, instance, subscribersMap, disconnect, connection) {
const adapter = this.config.getIoAdapter();
return (...args) => {
const [client] = args;
connection.next(args);
context.subscribeMessages(subscribersMap, client, instance);
const disconnectHook = adapter.bindClientDisconnect;
disconnectHook &&
disconnectHook.call(adapter, client, () => disconnect.next(client));
};
}
subscribeInitEvent(instance, event) {
if (instance.afterInit) {
event.subscribe(instance.afterInit.bind(instance));
}
}
subscribeConnectionEvent(instance, event) {
if (instance.handleConnection) {
event
.pipe((0, rxjs_1.distinctUntilChanged)((prev, curr) => (0, compare_element_util_1.compareElementAt)(prev, curr, 0)))
.subscribe((args) => instance.handleConnection(...args));
}
}
subscribeDisconnectEvent(instance, event) {
if (instance.handleDisconnect) {
event
.pipe((0, rxjs_1.distinctUntilChanged)())
.subscribe(instance.handleDisconnect.bind(instance));
}
}
subscribeMessages(subscribersMap, client, instance) {
const adapter = this.config.getIoAdapter();
const handlers = subscribersMap.map(({ callback, message }) => ({
message,
callback: callback.bind(instance, client)
}));
adapter.bindMessageHandlers(client, handlers, data => (0, rxjs_1.from)(this.pickResult(data)).pipe((0, rxjs_1.mergeAll)()));
}
async pickResult(deferredResult) {
const result = await deferredResult;
if ((0, rxjs_1.isObservable)(result)) {
return result;
}
if (result instanceof Promise) {
return (0, rxjs_1.from)(result);
}
return (0, rxjs_1.of)(result);
}
inspectEntrypointDefinitions(instance, port, messageHandlers, instanceWrapperId) {
messageHandlers.forEach(handler => {
var _a;
this.graphInspector.insertEntrypointDefinition({
type: 'websocket',
methodName: handler.methodName,
className: (_a = instance.constructor) === null || _a === void 0 ? void 0 : _a.name,
classNodeId: instanceWrapperId,
metadata: {
port,
key: handler.message,
message: handler.message
}
}, instanceWrapperId);
});
}
assignServerToProperties(instance, server) {
for (const propertyKey of this.metadataExplorer.scanForServerHooks(instance)) {
Reflect.set(instance, propertyKey, server);
}
}
printSubscriptionLogs(instance, subscribersMap) {
var _a;
const gatewayClassName = (_a = instance === null || instance === void 0 ? void 0 : instance.constructor) === null || _a === void 0 ? void 0 : _a.name;
if (!gatewayClassName) {
return;
}
subscribersMap.forEach(({ message }) => this.logger.log(`${gatewayClassName} subscribed to the "${message}" message`));
}
}
exports.WebSocketsController = WebSocketsController;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLXNvY2tldHMtY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93ZWJzb2NrZXRzL3dlYi1zb2NrZXRzLWNvbnRyb2xsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0JBUWE7QUFDYiwwQ0FBb0M7QUFDcEMsMkVBR29DO0FBQ3BDLGdDQUEyRDtBQVEzRCx3Q0FBMkQ7QUFDM0QsMEZBQW1GO0FBR25GLHVFQUErRDtBQUkvRCxNQUFhLG9CQUFvQjtJQVEvQixZQUNtQixvQkFBMEMsRUFDMUMsTUFBeUIsRUFDekIsY0FBZ0MsRUFDaEMsY0FBOEIsRUFDOUIsYUFBaUQsRUFBRTtRQUpuRCx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBQzFDLFdBQU0sR0FBTixNQUFNLENBQW1CO1FBQ3pCLG1CQUFjLEdBQWQsY0FBYyxDQUFrQjtRQUNoQyxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsZUFBVSxHQUFWLFVBQVUsQ0FBeUM7UUFackQsV0FBTSxHQUFHLElBQUksaUJBQU0sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUU7WUFDOUQsU0FBUyxFQUFFLElBQUk7U0FDaEIsQ0FBQyxDQUFBO1FBQ2UscUJBQWdCLEdBQUcsSUFBSSxtREFBdUIsQ0FDN0QsSUFBSSxxQkFBZSxFQUFFLENBQ3RCLENBQUE7SUFRRSxDQUFDO0lBRUcsc0JBQXNCLENBQzNCLFFBQXNCLEVBQ3RCLFFBQWtDLEVBQ2xDLFNBQWlCLEVBQ2pCLGlCQUF5QjtRQUV6QixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLHlCQUFlLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQ3BFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsdUJBQWEsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7UUFFOUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUs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LDBDQUFFLElBQUk7Z0JBQ3JDLFdBQVcsRUFBRSxpQkFBaUI7Z0JBQzlCLFFBQVEsRUFBRTtvQkFDUixJQUFJO29CQUNKLEdBQUcsRUFBRSxPQUFPLENBQUMsT0FBTztvQkFDcEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO2lCQUN6QjthQUNGLEVBQ0QsaUJBQWlCLENBQ2xCLENBQUE7UUFDSCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFTyx3QkFBd0IsQ0FDOUIsUUFBc0IsRUFDdEIsTUFBYztRQUVkLEtBQUssTUFBTSxXQUFXLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixDQUNoRSxRQUFRLENBQ1QsRUFBRSxDQUFDO1lBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQzVDLENBQUM7SUFDSCxDQUFDO0lBRU8scUJBQXFCLENBQzNCLFFBQXNCLEVBQ3RCLGNBQTBDOztRQUUxQyxNQUFNLGdCQUFnQixHQUFHLE1BQUMsUUFBbUIsYUFBbkIsUUFBUSx1QkFBUixRQUFRLENBQWEsV0FBVywwQ0FBRSxJQUFJLENBQUE7UUFDaEUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDdEIsT0FBTTtRQUNSLENBQUM7UUFDRCxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNiLEdBQUcsZ0JBQWdCLHVCQUF1QixPQUFPLFdBQVcsQ0FDN0QsQ0FDRixDQUFBO0lBQ0gsQ0FBQztDQUNGO0FBM05ELG9EQTJOQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICBpc09ic2VydmFibGUsXG4gIG1lcmdlQWxsLFxuICBPYnNlcnZhYmxlLFxuICBvZixcbiAgU3ViamVjdCxcbiAgZnJvbSBhcyBmcm9tUHJvbWlzZVxufSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vc2VydmljZXMnXG5pbXBvcnQge1xuICBHYXRld2F5TWV0YWRhdGFFeHBsb3JlcixcbiAgTWVzc2FnZU1hcHBpbmdQcm9wZXJ0aWVzXG59IGZyb20gJy4vZ2F0ZXdheS1tZXRhZGF0YS1leHBsb3JlcidcbmltcG9ydCB7IEFwcGxpY2F0aW9uQ29uZmlnLCBNZXRhZGF0YVNjYW5uZXIgfSBmcm9tICcuLi9hcHAnXG5pbXBvcnQgeyBTb2NrZXRTZXJ2ZXJQcm92aWRlciB9IGZyb20gJy4vc29ja2V0LXNlcnZlci1wcm92aWRlcidcbmltcG9ydCB7IFdzQ29udGV4dENyZWF0b3IgfSBmcm9tICcuL2NvbnRleHQvd3MtY29udGV4dC1jcmVhdG9yJ1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25Db250ZXh0T3B0aW9uc0ludGVyZmFjZSxcbiAgQ2xlYW5HYXRld2F5LFxuICBUeXBlXG59IGZyb20gJy4uL2NvbnRyYWN0cydcbmltcG9ydCB7IEdBVEVXQVlfT1BUSU9OUywgUE9SVF9NRVRBREFUQSB9IGZyb20gJy4uL2hlbHBlcnMnXG5pbXBvcnQgeyBJbnZhbGlkU29ja2V0UG9ydEV4Y2VwdGlvbiB9IGZyb20gJy4vZXJyb3JzL2ludmFsaWQtc29ja2V0LXBvcnQuZXhjZXB0aW9uJ1xuaW1wb3J0IHsgR2F0ZXdheU1ldGFkYXRhIH0gZnJvbSAnLi4vY29udHJhY3RzL2dhdGV3YXktbWV0YWRhdGEnXG5pbXBvcnQgeyBTZXJ2ZXJBbmRFdmVudFN0cmVhbXNIb3N0IH0gZnJvbSAnLi4vY29udHJhY3RzL3NlcnZlci1hbmQtZXZlbnQtc3RyZWFtcy1ob3N0J1xuaW1wb3J0IHsgY29tcGFyZUVsZW1lbnRBdCB9IGZyb20gJy4vdXRpbHMvY29tcGFyZS1lbGVtZW50LnV0aWwnXG5pbXBvcnQgeyBXZWJzb2NrZXRFbnRyeXBvaW50TWV0YWRhdGEgfSBmcm9tICcuLi9jb250cmFjdHMvd2Vic29ja2V0cy1lbnRyeXBvaW50LW1ldGFkYXRhJ1xuaW1wb3J0IHsgR3JhcGhJbnNwZWN0b3IgfSBmcm9tICcuLi9pbnNwZWN0b3IvZ3JhcGgtaW5zcGVjdG9yJ1xuXG5leHBvcnQgY2xhc3MgV2ViU29ja2V0c0NvbnRyb2xsZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlciA9IG5ldyBMb2dnZXIoV2ViU29ja2V0c0NvbnRyb2xsZXIubmFtZSwge1xuICAgIHRpbWVzdGFtcDogdHJ1ZVxuICB9KVxuICBwcml2YXRlIHJlYWRvbmx5IG1ldGFkYXRhRXhwbG9yZXIgPSBuZXcgR2F0ZXdheU1ldGFkYXRhRXhwbG9yZXIoXG4gICAgbmV3IE1ldGFkYXRhU2Nhbm5lcigpXG4gIClcblxuICBjb25zdHJ1Y3RvciAoXG4gICAgcHJpdmF0ZSByZWFkb25seSBzb2NrZXRTZXJ2ZXJQcm92aWRlcjogU29ja2V0U2VydmVyUHJvdmlkZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWc6IEFwcGxpY2F0aW9uQ29uZmlnLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY29udGV4dENyZWF0b3I6IFdzQ29udGV4dENyZWF0b3IsXG4gICAgcHJpdmF0ZSByZWFkb25seSBncmFwaEluc3BlY3RvcjogR3JhcGhJbnNwZWN0b3IsXG4gICAgcHJpdmF0ZSByZWFkb25seSBhcHBPcHRpb25zOiBBcHBsaWNhdGlvbkNvbnRleHRPcHRpb25zSW50ZXJmYWNlID0ge31cbiAgKSB7fVxuXG4gIHB1YmxpYyBjb25uZWN0R2F0ZXdheVRvU2VydmVyIChcbiAgICBpbnN0YW5jZTogQ2xlYW5HYXRld2F5LFxuICAgIG1ldGF0eXBlOiBUeXBlPHVua25vd24+IHwgRnVuY3Rpb24sXG4gICAgbW9kdWxlS2V5OiBzdHJpbmcsXG4gICAgaW5zdGFuY2VXcmFwcGVySWQ6IHN0cmluZ1xuICApIHtcbiAgICBjb25zdCBvcHRpb25zID0gUmVmbGVjdC5nZXRNZXRhZGF0YShHQVRFV0FZX09QVElPTlMsIG1ldGF0eXBlKSB8fCB7fVxuICAgIGNvbnN0IHBvcnQgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFBPUlRfTUVUQURBVEEsIG1ldGF0eXBlKSB8fCAwXG5cbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIocG9ydCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkU29ja2V0UG9ydEV4Y2VwdGlvbihwb3J0LCBtZXRhdHlwZSlcbiAgICB9XG4gICAgdGhpcy5zdWJzY3JpYmVUb1NlcnZlckV2ZW50cyhcbiAgICAgIGluc3RhbmNlLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHBvcnQsXG4gICAgICBtb2R1bGVLZXksXG4gICAgICBpbnN0YW5jZVdyYXBwZXJJZFxuICAgIClcbiAgfVxuXG4gIHB1YmxpYyBzdWJzY3JpYmVUb1NlcnZlckV2ZW50czxUIGV4dGVuZHMgR2F0ZXdheU1ldGFkYXRhPiAoXG4gICAgaW5zdGFuY2U6IENsZWFuR2F0ZXdheSxcbiAgICBvcHRpb25zOiBULFxuICAgIHBvcnQ6IG51bWJlcixcbiAgICBtb2R1bGVLZXk6IHN0cmluZyxcbiAgICBpbnN0YW5jZVdyYXBwZXJJZDogc3RyaW5nXG4gICkge1xuICAgIGNvbnN0IG5hdGl2ZU1lc3NhZ2VIYW5kbGVycyA9IHRoaXMubWV0YWRhdGFFeHBsb3Jlci5leHBsb3JlKGluc3RhbmNlKVxuICAgIGNvbnN0IG1lc3NhZ2VIYW5kbGVycyA9IG5hdGl2ZU1lc3NhZ2VIYW5kbGVycy5tYXAoXG4gICAgICAoeyBjYWxsYmFjaywgbWVzc2FnZSwgbWV0aG9kTmFtZSB9KSA9PiAoe1xuICAgICAgICBtZXNzYWdlLFxuICAgICAgICBtZXRob2ROYW1lLFxuICAgICAgICBjYWxsYmFjazogdGhpcy5jb250ZXh0Q3JlYXRvci5jcmVhdGUoXG4gICAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgbW9kdWxlS2V5LFxuICAgICAgICAgIG1ldGhvZE5hbWVcbiAgICAgICAgKVxuICAgICAgfSlcbiAgICApXG5cbiAgICB0aGlzLmluc3BlY3RFbnRyeXBvaW50RGVmaW5pdGlvbnMoXG4gICAgICBpbnN0YW5jZSxcbiAgICAgIHBvcnQsXG4gICAgICBtZXNzYWdlSGFuZGxlcnMsXG4gICAgICBpbnN0YW5jZVdyYXBwZXJJZFxuICAgIClcblxuICAgIGlmICh0aGlzLmFwcE9wdGlvbnMucHJldmlldykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGNvbnN0IG9ic2VydmFibGVTZXJ2ZXIgPSB0aGlzLnNvY2tldFNlcnZlclByb3ZpZGVyLnNjYW5Gb3JTb2NrZXRTZXJ2ZXI8VD4oXG4gICAgICBvcHRpb25zLFxuICAgICAgcG9ydFxuICAgIClcbiAgICB0aGlzLmFzc2lnblNlcnZlclRvUHJvcGVydGllcyhpbnN0YW5jZSwgb2JzZXJ2YWJsZVNlcnZlci5zZXJ2ZXIpXG4gICAgdGhpcy5zdWJzY3JpYmVFdmVudHMoaW5zdGFuY2UsIG1lc3NhZ2VIYW5kbGVycywgb2JzZXJ2YWJsZVNlcnZlcilcbiAgfVxuXG4gIHB1YmxpYyBzdWJzY3JpYmVFdmVudHMgKFxuICAgIGluc3RhbmNlOiBDbGVhbkdhdGV3YXksXG4gICAgc3Vic2NyaWJlcnNNYXA6IE1lc3NhZ2VNYXBwaW5nUHJvcGVydGllc1tdLFxuICAgIG9ic2VydmFibGVTZXJ2ZXI6IFNlcnZlckFuZEV2ZW50U3RyZWFtc0hvc3RcbiAgKSB7XG4gICAgY29uc3QgeyBpbml0LCBkaXNjb25uZWN0LCBjb25uZWN0aW9uLCBzZXJ2ZXIgfSA9IG9ic2VydmFibGVTZXJ2ZXJcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5jb25maWcuZ2V0SW9BZGFwdGVyKClcblxuICAgIHRoaXMuc3Vic2NyaWJlSW5pdEV2ZW50KGluc3RhbmNlLCBpbml0KVxuICAgIHRoaXMuc3Vic2NyaWJlQ29ubmVjdGlvbkV2ZW50KGluc3RhbmNlLCBjb25uZWN0aW9uKVxuICAgIHRoaXMuc3Vic2NyaWJlRGlzY29ubmVjdEV2ZW50KGluc3RhbmNlLCBkaXNjb25uZWN0KVxuXG4gICAgY29uc3QgaGFuZGxlciA9IHRoaXMuZ2V0Q29ubmVjdGlvbkhhbmRsZXIoXG4gICAgICB0aGlzLFxuICAgICAgaW5zdGFuY2UsXG4gICAgICBzdWJzY3JpYmVyc01hcCxcbiAgICAgIGRpc2Nvbm5lY3QsXG4gICAgICBjb25uZWN0aW9uXG4gICAgKVxuICAgIGFkYXB0ZXIuYmluZENsaWVudENvbm5lY3Qoc2VydmVyLCBoYW5kbGVyKVxuICAgIHRoaXMucHJpbnRTdWJzY3JpcHRpb25Mb2dzKGluc3RhbmNlLCBzdWJzY3JpYmVyc01hcClcbiAgfVxuXG4gIHB1YmxpYyBnZXRDb25uZWN0aW9uSGFuZGxlciAoXG4gICAgY29udGV4dDogV2ViU29ja2V0c0NvbnRyb2xsZXIsXG4gICAgaW5zdGFuY2U6IENsZWFuR2F0ZXdheSxcbiAgICBzdWJzY3JpYmVyc01hcDogTWVzc2FnZU1hcHBpbmdQcm9wZXJ0aWVzW10sXG4gICAgZGlzY29ubmVjdDogU3ViamVjdDxhbnk+LFxuICAgIGNvbm5lY3Rpb246IFN1YmplY3Q8YW55PlxuICApIHtcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5jb25maWcuZ2V0SW9BZGFwdGVyKClcbiAgICByZXR1cm4gKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgY29uc3QgW2NsaWVudF0gPSBhcmdzXG4gICAgICBjb25uZWN0aW9uLm5leHQoYXJncylcbiAgICAgIGNvbnRleHQuc3Vic2NyaWJlTWVzc2FnZXMoc3Vic2NyaWJlcnNNYXAsIGNsaWVudCwgaW5zdGFuY2UpXG5cbiAgICAgIGNvbnN0IGRpc2Nvbm5lY3RIb29rID0gYWRhcHRlci5iaW5kQ2xpZW50RGlzY29ubmVjdFxuICAgICAgZGlzY29ubmVjdEhvb2sgJiZcbiAgICAgICAgZGlzY29ubmVjdEhvb2suY2FsbChhZGFwdGVyLCBjbGllbnQsICgpID0+IGRpc2Nvbm5lY3QubmV4dChjbGllbnQpKVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdWJzY3JpYmVJbml0RXZlbnQgKGluc3RhbmNlOiBDbGVhbkdhdGV3YXksIGV2ZW50OiBTdWJqZWN0PGFueT4pIHtcbiAgICBpZiAoaW5zdGFuY2UuYWZ0ZXJJbml0KSB7XG4gICAgICBldmVudC5zdWJzY3JpYmUoaW5zdGFuY2UuYWZ0ZXJJbml0LmJpbmQoaW5zdGFuY2UpKVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdWJzY3JpYmVDb25uZWN0aW9uRXZlbnQgKGluc3RhbmNlOiBDbGVhbkdhdGV3YXksIGV2ZW50OiBTdWJqZWN0PGFueT4pIHtcbiAgICBpZiAoaW5zdGFuY2UuaGFuZGxlQ29ubmVjdGlvbikge1xuICAgICAgZXZlbnRcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKHByZXYsIGN1cnIpID0+IGNvbXBhcmVFbGVtZW50QXQocHJldiwgY3VyciwgMCkpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgoYXJnczogdW5rbm93bltdKSA9PiBpbnN0YW5jZS5oYW5kbGVDb25uZWN0aW9uKC4uLmFyZ3MpKVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdWJzY3JpYmVEaXNjb25uZWN0RXZlbnQgKGluc3RhbmNlOiBDbGVhbkdhdGV3YXksIGV2ZW50OiBTdWJqZWN0PGFueT4pIHtcbiAgICBpZiAoaW5zdGFuY2UuaGFuZGxlRGlzY29ubmVjdCkge1xuICAgICAgZXZlbnRcbiAgICAgICAgLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSlcbiAgICAgICAgLnN1YnNjcmliZShpbnN0YW5jZS5oYW5kbGVEaXNjb25uZWN0LmJpbmQoaW5zdGFuY2UpKVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdWJzY3JpYmVNZXNzYWdlczxUID0gYW55PiAoXG4gICAgc3Vic2NyaWJlcnNNYXA6IE1lc3NhZ2VNYXBwaW5nUHJvcGVydGllc1tdLFxuICAgIGNsaWVudDogVCxcbiAgICBpbnN0YW5jZTogQ2xlYW5HYXRld2F5XG4gICkge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLmNvbmZpZy5nZXRJb0FkYXB0ZXIoKVxuICAgIGNvbnN0IGhhbmRsZXJzID0gc3Vic2NyaWJlcnNNYXAubWFwKCh7IGNhbGxiYWNrLCBtZXNzYWdlIH0pID0+ICh7XG4gICAgICBtZXNzYWdlLFxuICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLmJpbmQoaW5zdGFuY2UsIGNsaWVudClcbiAgICB9KSlcbiAgICBhZGFwdGVyLmJpbmRNZXNzYWdlSGFuZGxlcnMoY2xpZW50LCBoYW5kbGVycywgZGF0YSA9PlxuICAgICAgZnJvbVByb21pc2UodGhpcy5waWNrUmVzdWx0KGRhdGEpKS5waXBlKG1lcmdlQWxsKCkpXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHBpY2tSZXN1bHQgKFxuICAgIGRlZmVycmVkUmVzdWx0OiBQcm9taXNlPGFueT5cbiAgKTogUHJvbWlzZTxPYnNlcnZhYmxlPGFueT4+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkZWZlcnJlZFJlc3VsdFxuICAgIGlmIChpc09ic2VydmFibGUocmVzdWx0KSkge1xuICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cbiAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKHJlc3VsdClcbiAgICB9XG4gICAgcmV0dXJuIG9mKHJlc3VsdClcbiAgfVxuXG4gIHB1YmxpYyBpbnNwZWN0RW50cnlwb2ludERlZmluaXRpb25zIChcbiAgICBpbnN0YW5jZTogQ2xlYW5HYXRld2F5LFxuICAgIHBvcnQ6IG51bWJlcixcbiAgICBtZXNzYWdlSGFuZGxlcnM6IE1lc3NhZ2VNYXBwaW5nUHJvcGVydGllc1tdLFxuICAgIGluc3RhbmNlV3JhcHBlcklkOiBzdHJpbmdcbiAgKSB7XG4gICAgbWVzc2FnZUhhbmRsZXJzLmZvckVhY2goaGFuZGxlciA9PiB7XG4gICAgICB0aGlzLmdyYXBoSW5zcGVjdG9yLmluc2VydEVudHJ5cG9pbnREZWZpbml0aW9uPFdlYnNvY2tldEVudHJ5cG9pbnRNZXRhZGF0YT4oXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnd2Vic29ja2V0JyxcbiAgICAgICAgICBtZXRob2ROYW1lOiBoYW5kbGVyLm1ldGhvZE5hbWUsXG4gICAgICAgICAgY2xhc3NOYW1lOiBpbnN0YW5jZS5jb25zdHJ1Y3Rvcj8ubmFtZSxcbiAgICAgICAgICBjbGFzc05vZGVJZDogaW5zdGFuY2VXcmFwcGVySWQsXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHBvcnQsXG4gICAgICAgICAgICBrZXk6IGhhbmRsZXIubWVzc2FnZSxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGhhbmRsZXIubWVzc2FnZVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgaW5zdGFuY2VXcmFwcGVySWRcbiAgICAgIClcbiAgICB9KVxuICB9XG5cbiAgcHJpdmF0ZSBhc3NpZ25TZXJ2ZXJUb1Byb3BlcnRpZXM8VCA9IGFueT4gKFxuICAgIGluc3RhbmNlOiBDbGVhbkdhdGV3YXksXG4gICAgc2VydmVyOiBvYmplY3RcbiAgKSB7XG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eUtleSBvZiB0aGlzLm1ldGFkYXRhRXhwbG9yZXIuc2NhbkZvclNlcnZlckhvb2tzKFxuICAgICAgaW5zdGFuY2VcbiAgICApKSB7XG4gICAgICBSZWZsZWN0LnNldChpbnN0YW5jZSwgcHJvcGVydHlLZXksIHNlcnZlcilcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByaW50U3Vic2NyaXB0aW9uTG9ncyAoXG4gICAgaW5zdGFuY2U6IENsZWFuR2F0ZXdheSxcbiAgICBzdWJzY3JpYmVyc01hcDogTWVzc2FnZU1hcHBpbmdQcm9wZXJ0aWVzW11cbiAgKSB7XG4gICAgY29uc3QgZ2F0ZXdheUNsYXNzTmFtZSA9IChpbnN0YW5jZSBhcyBPYmplY3QpPy5jb25zdHJ1Y3Rvcj8ubmFtZVxuICAgIGlmICghZ2F0ZXdheUNsYXNzTmFtZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHN1YnNjcmliZXJzTWFwLmZvckVhY2goKHsgbWVzc2FnZSB9KSA9PlxuICAgICAgdGhpcy5sb2dnZXIubG9nKFxuICAgICAgICBgJHtnYXRld2F5Q2xhc3NOYW1lfSBzdWJzY3JpYmVkIHRvIHRoZSBcIiR7bWVzc2FnZX1cIiBtZXNzYWdlYFxuICAgICAgKVxuICAgIClcbiAgfVxufVxuIl19