Kaynağa Gözat

added EventEmitter for obfuscation events

sanex3339 8 yıl önce
ebeveyn
işleme
3276756073
30 değiştirilmiş dosya ile 318 ekleme ve 223 silme
  1. 114 93
      dist/index.js
  2. 18 31
      src/Obfuscator.ts
  3. 10 9
      src/custom-nodes/AbstractCustomNode.ts
  4. 21 9
      src/custom-nodes/AbstractCustomNodesFactory.ts
  5. 4 3
      src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts
  6. 12 5
      src/custom-nodes/console-output-nodes/factory/ConsoleOutputCustomNodesFactory.ts
  7. 4 3
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts
  8. 4 3
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode.ts
  9. 4 3
      src/custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts
  10. 4 3
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts
  11. 4 3
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts
  12. 4 3
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts
  13. 10 3
      src/custom-nodes/debug-protection-nodes/factory/DebugProtectionCustomNodesFactory.ts
  14. 4 3
      src/custom-nodes/domain-lock-nodes/DomainLockNode.ts
  15. 13 6
      src/custom-nodes/domain-lock-nodes/factory/DomainLockCustomNodesFactory.ts
  16. 5 4
      src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts
  17. 4 3
      src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts
  18. 18 9
      src/custom-nodes/self-defending-nodes/factory/SelfDefendingCustomNodesFactory.ts
  19. 4 3
      src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts
  20. 4 3
      src/custom-nodes/string-array-nodes/StringArrayNode.ts
  21. 4 3
      src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts
  22. 15 6
      src/custom-nodes/string-array-nodes/factory/StringArrayCustomNodesFactory.ts
  23. 0 4
      src/enums/AppendState.ts
  24. 11 0
      src/enums/ObfuscationEvents.ts
  25. 5 0
      src/event-emitters/ObfuscationEventEmitter.ts
  26. 4 1
      src/interfaces/ICustomNodesFactory.d.ts
  27. 8 0
      src/interfaces/IObfuscationEventEmitter.d.ts
  28. 4 5
      src/interfaces/custom-nodes/ICustomNode.d.ts
  29. 1 2
      src/types/TCustomNodesFactory.d.ts
  30. 1 0
      src/types/TObfuscationEvent.d.ts

+ 114 - 93
dist/index.js

@@ -347,19 +347,7 @@ Utils.randomGenerator = new chance_1.Chance();
 exports.Utils = Utils;
 
 /***/ },
-/* 1 */
-/***/ function(module, exports) {
-
-"use strict";
-"use strict";
-
-(function (AppendState) {
-    AppendState[AppendState["AfterObfuscation"] = 0] = "AfterObfuscation";
-    AppendState[AppendState["BeforeObfuscation"] = 1] = "BeforeObfuscation";
-})(exports.AppendState || (exports.AppendState = {}));
-var AppendState = exports.AppendState;
-
-/***/ },
+/* 1 */,
 /* 2 */
 /***/ function(module, exports, __webpack_require__) {
 
@@ -653,9 +641,9 @@ var AbstractCustomNode = function () {
     }
 
     _createClass(AbstractCustomNode, [{
-        key: "getAppendState",
-        value: function getAppendState() {
-            return this.appendState;
+        key: "getAppendEvent",
+        value: function getAppendEvent() {
+            return this.appendEvent;
         }
     }, {
         key: "getNode",
@@ -663,9 +651,9 @@ var AbstractCustomNode = function () {
             return this.getNodeStructure();
         }
     }, {
-        key: "setAppendState",
-        value: function setAppendState(appendState) {
-            this.appendState = appendState;
+        key: "setAppendEvent",
+        value: function setAppendEvent(appendEvent) {
+            this.appendEvent = appendEvent;
         }
     }, {
         key: "getNodeStructure",
@@ -953,24 +941,24 @@ var _createClass = (function () { function defineProperties(target, props) { for
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 
 var AbstractCustomNodesFactory = function () {
-    function AbstractCustomNodesFactory(stackTraceData, options) {
+    function AbstractCustomNodesFactory(options) {
         _classCallCheck(this, AbstractCustomNodesFactory);
 
-        this.appendState = AppendState_1.AppendState.BeforeObfuscation;
-        this.stackTraceData = stackTraceData;
+        this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         this.options = options;
     }
 
     _createClass(AbstractCustomNodesFactory, [{
         key: "syncCustomNodesWithNodesFactory",
-        value: function syncCustomNodesWithNodesFactory(customNodes) {
+        value: function syncCustomNodesWithNodesFactory(obfuscationEventEmitter, customNodes) {
             var _this = this;
 
             customNodes.forEach(function (node) {
-                node.setAppendState(_this.appendState);
+                node.setAppendEvent(_this.appendEvent);
+                obfuscationEventEmitter.on(node.getAppendEvent(), node.appendNode.bind(node));
             });
             return customNodes;
         }
@@ -1116,7 +1104,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var SingleNodeCallControllerTemplate_1 = __webpack_require__(80);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var AbstractCustomNode_1 = __webpack_require__(5);
@@ -1131,7 +1119,7 @@ var NodeCallsControllerFunctionNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (NodeCallsControllerFunctionNode.__proto__ || Object.getPrototypeOf(NodeCallsControllerFunctionNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         _this.stackTraceData = stackTraceData;
         _this.callsControllerFunctionName = callsControllerFunctionName;
         _this.randomStackTraceIndex = randomStackTraceIndex;
@@ -1152,7 +1140,7 @@ var NodeCallsControllerFunctionNode = function (_AbstractCustomNode_) {
     }, {
         key: 'getCode',
         value: function getCode() {
-            if (this.appendState === AppendState_1.AppendState.AfterObfuscation) {
+            if (this.appendEvent === ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation) {
                 return JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(format(SingleNodeCallControllerTemplate_1.SingleNodeCallControllerTemplate(), {
                     singleNodeCallControllerFunctionName: this.callsControllerFunctionName
                 }), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, {
@@ -1596,7 +1584,7 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 var estraverse = __webpack_require__(4);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var VisitorDirection_1 = __webpack_require__(51);
 var ConsoleOutputCustomNodesFactory_1 = __webpack_require__(35);
 var DebugProtectionCustomNodesFactory_1 = __webpack_require__(42);
@@ -1608,6 +1596,7 @@ var StringArrayCustomNodesFactory_1 = __webpack_require__(50);
 var Node_1 = __webpack_require__(2);
 var NodeUtils_1 = __webpack_require__(8);
 var StackTraceAnalyzer_1 = __webpack_require__(70);
+var ObfuscationEventEmitter_1 = __webpack_require__(108);
 
 var Obfuscator = function () {
     function Obfuscator(options) {
@@ -1623,41 +1612,25 @@ var Obfuscator = function () {
                 return astTree;
             }
             NodeUtils_1.NodeUtils.parentize(astTree);
-            this.initializeCustomNodes(new StackTraceAnalyzer_1.StackTraceAnalyzer().analyze(astTree.body));
-            this.beforeTransform(astTree);
+            var obfuscationEventEmitter = new ObfuscationEventEmitter_1.ObfuscationEventEmitter();
+            var stackTraceAnalyzer = new StackTraceAnalyzer_1.StackTraceAnalyzer();
+            this.initializeCustomNodes(obfuscationEventEmitter, stackTraceAnalyzer.analyze(astTree.body));
+            obfuscationEventEmitter.emit(ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation, astTree);
             if (this.options.controlFlowFlattening) {
                 this.transformAstTree(astTree, VisitorDirection_1.VisitorDirection.leave, new NodeControlFlowTransformersFactory_1.NodeControlFlowTransformersFactory(this.customNodes, this.options));
             }
             this.transformAstTree(astTree, VisitorDirection_1.VisitorDirection.enter, new NodeObfuscatorsFactory_1.NodeObfuscatorsFactory(this.customNodes, this.options));
-            this.afterTransform(astTree);
+            obfuscationEventEmitter.emit(ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation, astTree);
             return astTree;
         }
-    }, {
-        key: 'afterTransform',
-        value: function afterTransform(astTree) {
-            this.customNodes.forEach(function (customNode) {
-                if (customNode.getAppendState() === AppendState_1.AppendState.AfterObfuscation) {
-                    customNode.appendNode(astTree);
-                }
-            });
-        }
-    }, {
-        key: 'beforeTransform',
-        value: function beforeTransform(astTree) {
-            this.customNodes.forEach(function (customNode) {
-                if (customNode.getAppendState() === AppendState_1.AppendState.BeforeObfuscation) {
-                    customNode.appendNode(astTree);
-                }
-            });
-        }
     }, {
         key: 'initializeCustomNodes',
-        value: function initializeCustomNodes(stackTraceData) {
+        value: function initializeCustomNodes(obfuscationEventEmitter, stackTraceData) {
             var _this = this;
 
             var customNodes = [];
             Obfuscator.customNodesFactories.forEach(function (customNodesFactoryConstructor) {
-                var customNodesFactory = new customNodesFactoryConstructor(stackTraceData, _this.options).initializeCustomNodes();
+                var customNodesFactory = new customNodesFactoryConstructor(_this.options).initializeCustomNodes(obfuscationEventEmitter, stackTraceData);
                 if (!customNodesFactory) {
                     return;
                 }
@@ -1997,7 +1970,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(81);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2011,7 +1984,7 @@ var ConsoleOutputDisableExpressionNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (ConsoleOutputDisableExpressionNode.__proto__ || Object.getPrototypeOf(ConsoleOutputDisableExpressionNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         _this.stackTraceData = stackTraceData;
         _this.callsControllerFunctionName = callsControllerFunctionName;
         _this.randomStackTraceIndex = randomStackTraceIndex;
@@ -2070,13 +2043,13 @@ var ConsoleOutputCustomNodesFactory = function (_AbstractCustomNodesF) {
 
     _createClass(ConsoleOutputCustomNodesFactory, [{
         key: 'initializeCustomNodes',
-        value: function initializeCustomNodes() {
+        value: function initializeCustomNodes(obfuscationEventEmitter, stackTraceData) {
             if (!this.options.disableConsoleOutput) {
                 return;
             }
             var callsControllerFunctionName = Utils_1.Utils.getRandomVariableName();
-            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
-            return this.syncCustomNodesWithNodesFactory(new Map([['consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['ConsoleOutputNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
+            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(stackTraceData.length);
+            return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, new Map([['consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode(stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['ConsoleOutputNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
         }
     }]);
 
@@ -2101,7 +2074,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var BinaryExpressionFunctionTemplate_1 = __webpack_require__(82);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var Utils_1 = __webpack_require__(0);
@@ -2114,7 +2087,7 @@ var BinaryExpressionFunctionNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (BinaryExpressionFunctionNode.__proto__ || Object.getPrototypeOf(BinaryExpressionFunctionNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         _this.operator = operator;
         return _this;
     }
@@ -2153,7 +2126,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var ControlFlowStorageCallTemplate_1 = __webpack_require__(83);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2166,7 +2139,7 @@ var ControlFlowStorageCallNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (ControlFlowStorageCallNode.__proto__ || Object.getPrototypeOf(ControlFlowStorageCallNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         _this.controlFlowStorageName = controlFlowStorageName;
         _this.controlFlowStorageKey = controlFlowStorageKey;
         _this.leftValue = leftValue;
@@ -2212,7 +2185,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var ControlFlowStorageTemplate_1 = __webpack_require__(84);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2225,7 +2198,7 @@ var ControlFlowStorageNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (ControlFlowStorageNode.__proto__ || Object.getPrototypeOf(ControlFlowStorageNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         _this.controlFlowStorage = controlFlowStorage;
         _this.controlFlowStorageName = controlFlowStorageName;
         return _this;
@@ -2267,7 +2240,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(85);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2280,7 +2253,7 @@ var DebugProtectionFunctionCallNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionCallNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionCallNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         _this.debugProtectionFunctionName = debugProtectionFunctionName;
         return _this;
     }
@@ -2320,7 +2293,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(86);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2333,7 +2306,7 @@ var DebugProtectionFunctionIntervalNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionIntervalNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionIntervalNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         _this.debugProtectionFunctionName = debugProtectionFunctionName;
         return _this;
     }
@@ -2373,7 +2346,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var DebugProtectionFunctionTemplate_1 = __webpack_require__(87);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2387,7 +2360,7 @@ var DebugProtectionFunctionNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         _this.debugProtectionFunctionName = debugProtectionFunctionName;
         return _this;
     }
@@ -2445,7 +2418,7 @@ var DebugProtectionCustomNodesFactory = function (_AbstractCustomNodesF) {
 
     _createClass(DebugProtectionCustomNodesFactory, [{
         key: 'initializeCustomNodes',
-        value: function initializeCustomNodes() {
+        value: function initializeCustomNodes(obfuscationEventEmitter, stackTraceData) {
             if (!this.options.debugProtection) {
                 return;
             }
@@ -2454,7 +2427,7 @@ var DebugProtectionCustomNodesFactory = function (_AbstractCustomNodesF) {
             if (this.options.debugProtectionInterval) {
                 customNodes.set('debugProtectionFunctionIntervalNode', new DebugProtectionFunctionIntervalNode_1.DebugProtectionFunctionIntervalNode(debugProtectionFunctionName, this.options));
             }
-            return this.syncCustomNodesWithNodesFactory(customNodes);
+            return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, customNodes);
         }
     }]);
 
@@ -2481,7 +2454,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var DomainLockNodeTemplate_1 = __webpack_require__(88);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2495,7 +2468,7 @@ var DomainLockNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (DomainLockNode.__proto__ || Object.getPrototypeOf(DomainLockNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.BeforeObfuscation;
         _this.stackTraceData = stackTraceData;
         _this.callsControllerFunctionName = callsControllerFunctionName;
         _this.randomStackTraceIndex = randomStackTraceIndex;
@@ -2561,13 +2534,13 @@ var DomainLockCustomNodesFactory = function (_AbstractCustomNodesF) {
 
     _createClass(DomainLockCustomNodesFactory, [{
         key: 'initializeCustomNodes',
-        value: function initializeCustomNodes() {
+        value: function initializeCustomNodes(obfuscationEventEmitter, stackTraceData) {
             if (!this.options.domainLock.length) {
                 return;
             }
             var callsControllerFunctionName = Utils_1.Utils.getRandomVariableName();
-            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
-            return this.syncCustomNodesWithNodesFactory(new Map([['DomainLockNode', new DomainLockNode_1.DomainLockNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['DomainLockNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
+            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(stackTraceData.length);
+            return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, new Map([['DomainLockNode', new DomainLockNode_1.DomainLockNode(stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['DomainLockNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
         }
     }]);
 
@@ -2592,7 +2565,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var SelfDefendingTemplate_1 = __webpack_require__(89);
 var AbstractCustomNode_1 = __webpack_require__(5);
@@ -2608,7 +2581,7 @@ var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (SelfDefendingUnicodeNode.__proto__ || Object.getPrototypeOf(SelfDefendingUnicodeNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         _this.stackTraceData = stackTraceData;
         _this.callsControllerFunctionName = callsControllerFunctionName;
         _this.randomStackTraceIndex = randomStackTraceIndex;
@@ -2652,7 +2625,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var NodeCallsControllerFunctionNode_1 = __webpack_require__(17);
 var SelfDefendingUnicodeNode_1 = __webpack_require__(45);
 var AbstractCustomNodesFactory_1 = __webpack_require__(12);
@@ -2667,19 +2640,19 @@ var SelfDefendingCustomNodesFactory = function (_AbstractCustomNodesF) {
 
         var _this = _possibleConstructorReturn(this, (SelfDefendingCustomNodesFactory.__proto__ || Object.getPrototypeOf(SelfDefendingCustomNodesFactory)).apply(this, arguments));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         return _this;
     }
 
     _createClass(SelfDefendingCustomNodesFactory, [{
         key: 'initializeCustomNodes',
-        value: function initializeCustomNodes() {
+        value: function initializeCustomNodes(obfuscationEventEmitter, stackTraceData) {
             if (!this.options.selfDefending) {
                 return;
             }
             var callsControllerFunctionName = Utils_1.Utils.getRandomVariableName();
-            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
-            return this.syncCustomNodesWithNodesFactory(new Map([['selfDefendingUnicodeNode', new SelfDefendingUnicodeNode_1.SelfDefendingUnicodeNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['SelfDefendingNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(this.stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
+            var randomStackTraceIndex = NodeAppender_1.NodeAppender.getRandomStackTraceIndex(stackTraceData.length);
+            return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, new Map([['selfDefendingUnicodeNode', new SelfDefendingUnicodeNode_1.SelfDefendingUnicodeNode(stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)], ['SelfDefendingNodeCallsControllerFunctionNode', new NodeCallsControllerFunctionNode_1.NodeCallsControllerFunctionNode(stackTraceData, callsControllerFunctionName, randomStackTraceIndex, this.options)]]));
         }
     }]);
 
@@ -2706,7 +2679,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var StringArrayEncoding_1 = __webpack_require__(18);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var AtobTemplate_1 = __webpack_require__(78);
@@ -2727,7 +2700,7 @@ var StringArrayCallsWrapper = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (StringArrayCallsWrapper.__proto__ || Object.getPrototypeOf(StringArrayCallsWrapper)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         _this.stringArrayCallsWrapperName = stringArrayCallsWrapperName;
         _this.stringArrayName = stringArrayName;
         _this.stringArray = stringArray;
@@ -2819,7 +2792,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var StringArrayTemplate_1 = __webpack_require__(94);
 var AbstractCustomNode_1 = __webpack_require__(5);
 var NodeAppender_1 = __webpack_require__(3);
@@ -2835,7 +2808,7 @@ var StringArrayNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (StringArrayNode.__proto__ || Object.getPrototypeOf(StringArrayNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         _this.stringArray = stringArray;
         _this.stringArrayName = stringArrayName;
         _this.stringArrayRotateValue = stringArrayRotateValue;
@@ -2893,7 +2866,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var format = __webpack_require__(7);
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var SelfDefendingTemplate_1 = __webpack_require__(95);
 var StringArrayRotateFunctionTemplate_1 = __webpack_require__(96);
@@ -2910,7 +2883,7 @@ var StringArrayRotateFunctionNode = function (_AbstractCustomNode_) {
 
         var _this = _possibleConstructorReturn(this, (StringArrayRotateFunctionNode.__proto__ || Object.getPrototypeOf(StringArrayRotateFunctionNode)).call(this, options));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         _this.stringArrayName = stringArrayName;
         _this.stringArray = stringArray;
         _this.stringArrayRotateValue = stringArrayRotateValue;
@@ -2971,7 +2944,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
-var AppendState_1 = __webpack_require__(1);
+var ObfuscationEvents_1 = __webpack_require__(107);
 var StringArrayCallsWrapper_1 = __webpack_require__(47);
 var StringArrayNode_1 = __webpack_require__(48);
 var StringArrayRotateFunctionNode_1 = __webpack_require__(49);
@@ -2987,7 +2960,7 @@ var StringArrayCustomNodesFactory = function (_AbstractCustomNodesF) {
 
         var _this = _possibleConstructorReturn(this, (StringArrayCustomNodesFactory.__proto__ || Object.getPrototypeOf(StringArrayCustomNodesFactory)).apply(this, arguments));
 
-        _this.appendState = AppendState_1.AppendState.AfterObfuscation;
+        _this.appendEvent = ObfuscationEvents_1.ObfuscationEvents.AfterObfuscation;
         _this.stringArrayName = Utils_1.Utils.getRandomVariableName(StringArrayNode_1.StringArrayNode.ARRAY_RANDOM_LENGTH);
         _this.stringArrayCallsWrapper = Utils_1.Utils.getRandomVariableName(StringArrayNode_1.StringArrayNode.ARRAY_RANDOM_LENGTH);
         return _this;
@@ -2995,7 +2968,7 @@ var StringArrayCustomNodesFactory = function (_AbstractCustomNodesF) {
 
     _createClass(StringArrayCustomNodesFactory, [{
         key: 'initializeCustomNodes',
-        value: function initializeCustomNodes() {
+        value: function initializeCustomNodes(obfuscationEventEmitter, stackTraceData) {
             if (!this.options.stringArray) {
                 return;
             }
@@ -3010,7 +2983,7 @@ var StringArrayCustomNodesFactory = function (_AbstractCustomNodesF) {
             if (this.options.rotateStringArray) {
                 customNodes.set('stringArrayRotateFunctionNode', new StringArrayRotateFunctionNode_1.StringArrayRotateFunctionNode(this.stringArrayName, stringArray, this.stringArrayRotateValue, this.options));
             }
-            return this.syncCustomNodesWithNodesFactory(customNodes);
+            return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, customNodes);
         }
     }]);
 
@@ -5129,6 +5102,54 @@ if (!global._babelPolyfill) {
 }
 module.exports = JavaScriptObfuscator_1.JavaScriptObfuscator;
 
+/***/ },
+/* 106 */
+/***/ function(module, exports) {
+
+module.exports = require("events");
+
+/***/ },
+/* 107 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+"use strict";
+
+var Utils_1 = __webpack_require__(0);
+exports.ObfuscationEvents = Utils_1.Utils.strEnumify({
+    AfterObfuscation: 'afterObfuscation',
+    BeforeObfuscation: 'beforeObfuscation'
+});
+
+/***/ },
+/* 108 */
+/***/ function(module, exports, __webpack_require__) {
+
+"use strict";
+"use strict";
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var events_1 = __webpack_require__(106);
+
+var ObfuscationEventEmitter = function (_events_1$EventEmitte) {
+  _inherits(ObfuscationEventEmitter, _events_1$EventEmitte);
+
+  function ObfuscationEventEmitter() {
+    _classCallCheck(this, ObfuscationEventEmitter);
+
+    return _possibleConstructorReturn(this, (ObfuscationEventEmitter.__proto__ || Object.getPrototypeOf(ObfuscationEventEmitter)).apply(this, arguments));
+  }
+
+  return ObfuscationEventEmitter;
+}(events_1.EventEmitter);
+
+exports.ObfuscationEventEmitter = ObfuscationEventEmitter;
+
 /***/ }
 /******/ ]);
 //# sourceMappingURL=index.js.map

+ 18 - 31
src/Obfuscator.ts

@@ -5,13 +5,15 @@ import { TCustomNodesFactory } from './types/TCustomNodesFactory';
 import { TVisitorDirection } from './types/TVisitorDirection';
 
 import { ICustomNode } from './interfaces/custom-nodes/ICustomNode';
+import { IObfuscationEventEmitter } from './interfaces/IObfuscationEventEmitter';
 import { IObfuscator } from './interfaces/IObfuscator';
 import { IOptions } from './interfaces/IOptions';
 import { INodeTransformer } from './interfaces/INodeTransformer';
 import { INodeTransformersFactory } from './interfaces/INodeTransformersFactory';
+import { IStackTraceAnalyzer } from './interfaces/stack-trace-analyzer/IStackTraceAnalyzer';
 import { IStackTraceData } from './interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from './enums/AppendState';
+import { ObfuscationEvents } from './enums/ObfuscationEvents';
 import { VisitorDirection } from './enums/VisitorDirection';
 
 import { ConsoleOutputCustomNodesFactory } from './custom-nodes/console-output-nodes/factory/ConsoleOutputCustomNodesFactory';
@@ -25,6 +27,7 @@ import { StringArrayCustomNodesFactory } from './custom-nodes/string-array-nodes
 import { Node } from './node/Node';
 import { NodeUtils } from './node/NodeUtils';
 import { StackTraceAnalyzer } from './stack-trace-analyzer/StackTraceAnalyzer';
+import { ObfuscationEventEmitter } from './event-emitters/ObfuscationEventEmitter';
 
 export class Obfuscator implements IObfuscator {
     /**
@@ -65,10 +68,13 @@ export class Obfuscator implements IObfuscator {
         }
 
         NodeUtils.parentize(astTree);
-        this.initializeCustomNodes(new StackTraceAnalyzer().analyze(astTree.body));
 
-        // tasks before nodes transformation
-        this.beforeTransform(astTree);
+        const obfuscationEventEmitter: IObfuscationEventEmitter = new ObfuscationEventEmitter();
+        const stackTraceAnalyzer: IStackTraceAnalyzer = new StackTraceAnalyzer();
+
+        this.initializeCustomNodes(obfuscationEventEmitter, stackTraceAnalyzer.analyze(astTree.body));
+
+        obfuscationEventEmitter.emit(ObfuscationEvents.BeforeObfuscation, astTree);
 
         // first pass: control flow flattening
         if (this.options.controlFlowFlattening) {
@@ -84,44 +90,25 @@ export class Obfuscator implements IObfuscator {
             this.options
         ));
 
-        // tasks after nodes transformation
-        this.afterTransform(astTree);
+        obfuscationEventEmitter.emit(ObfuscationEvents.AfterObfuscation, astTree);
 
         return astTree;
     }
 
     /**
-     * @param astTree
-     */
-    private afterTransform (astTree: ESTree.Program): void {
-        this.customNodes.forEach((customNode: ICustomNode) => {
-            if (customNode.getAppendState() === AppendState.AfterObfuscation) {
-                customNode.appendNode(astTree);
-            }
-        });
-    }
-
-    /**
-     * @param astTree
-     */
-    private beforeTransform (astTree: ESTree.Program): void {
-        this.customNodes.forEach((customNode: ICustomNode) => {
-            if (customNode.getAppendState() === AppendState.BeforeObfuscation) {
-                customNode.appendNode(astTree);
-            }
-        });
-    };
-
-    /**
+     * @param obfuscationEventEmitter
      * @param stackTraceData
      */
-    private initializeCustomNodes (stackTraceData: IStackTraceData[]): void {
+    private initializeCustomNodes (obfuscationEventEmitter: IObfuscationEventEmitter, stackTraceData: IStackTraceData[]): void {
         const customNodes: [string, ICustomNode][] = [];
 
         Obfuscator.customNodesFactories.forEach((customNodesFactoryConstructor: TCustomNodesFactory) => {
             const customNodesFactory: Map <string, ICustomNode> | undefined = new customNodesFactoryConstructor(
-                stackTraceData, this.options
-            ).initializeCustomNodes();
+                this.options
+            ).initializeCustomNodes(
+                obfuscationEventEmitter,
+                stackTraceData
+            );
 
             if (!customNodesFactory) {
                 return;

+ 10 - 9
src/custom-nodes/AbstractCustomNode.ts

@@ -1,17 +1,18 @@
 import * as ESTree from 'estree';
 
+import { TObfuscationEvent } from '../types/TObfuscationEvent';
+
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../interfaces/IOptions';
 import { TStatement } from '../types/TStatement';
 
-import { AppendState } from '../enums/AppendState';
 import { NodeUtils } from '../node/NodeUtils';
 
 export abstract class AbstractCustomNode implements ICustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected abstract appendState: AppendState;
+    protected abstract appendEvent: TObfuscationEvent;
 
     /**
      * @type {IOptions}
@@ -31,10 +32,10 @@ export abstract class AbstractCustomNode implements ICustomNode {
     public abstract appendNode (astTree: ESTree.Node): void;
 
     /**
-     * @returns {AppendState}
+     * @returns {TObfuscationEvent}
      */
-    public getAppendState (): AppendState {
-        return this.appendState;
+    public getAppendEvent (): TObfuscationEvent {
+        return this.appendEvent;
     }
 
     /**
@@ -50,10 +51,10 @@ export abstract class AbstractCustomNode implements ICustomNode {
     }
 
     /**
-     * @param appendState
+     * @param appendEvent
      */
-    public setAppendState (appendState: AppendState): void {
-        this.appendState = appendState;
+    public setAppendEvent (appendEvent: TObfuscationEvent): void {
+        this.appendEvent = appendEvent;
     }
 
     /**

+ 21 - 9
src/custom-nodes/AbstractCustomNodesFactory.ts

@@ -1,15 +1,18 @@
+import { TObfuscationEvent } from '../types/TObfuscationEvent';
+
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 import { ICustomNodesFactory } from '../interfaces/ICustomNodesFactory';
+import { IObfuscationEventEmitter } from '../interfaces/IObfuscationEventEmitter';
 import { IOptions } from '../interfaces/IOptions';
 import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from '../enums/AppendState';
+import { ObfuscationEvents } from '../enums/ObfuscationEvents';
 
 export abstract class AbstractCustomNodesFactory implements ICustomNodesFactory {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected readonly appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {IStackTraceData[]}
@@ -22,26 +25,35 @@ export abstract class AbstractCustomNodesFactory implements ICustomNodesFactory
     protected readonly options: IOptions;
 
     /**
-     * @param stackTraceData
      * @param options
      */
-    constructor (stackTraceData: IStackTraceData[], options: IOptions) {
-        this.stackTraceData = stackTraceData;
+    constructor (options: IOptions) {
         this.options = options;
     }
 
     /**
+     * @param obfuscationEventEmitter
+     * @param stackTraceData
      * @returns {Map<string, ICustomNode> | undefined}
      */
-    public abstract initializeCustomNodes (): Map <string, ICustomNode> | undefined;
+    public abstract initializeCustomNodes (
+        obfuscationEventEmitter: IObfuscationEventEmitter,
+        stackTraceData: IStackTraceData[]
+    ): Map <string, ICustomNode> | undefined;
 
     /**
+     * @param obfuscationEventEmitter
      * @param customNodes
      * @returns {Map<string, ICustomNode>}
      */
-    protected syncCustomNodesWithNodesFactory (customNodes: Map <string, ICustomNode>): Map <string, ICustomNode> {
+    protected syncCustomNodesWithNodesFactory (
+        obfuscationEventEmitter: IObfuscationEventEmitter,
+        customNodes: Map <string, ICustomNode>
+    ): Map <string, ICustomNode> {
         customNodes.forEach((node: ICustomNode) => {
-            node.setAppendState(this.appendState);
+            node.setAppendEvent(this.appendEvent);
+
+            obfuscationEventEmitter.on(node.getAppendEvent(), node.appendNode.bind(node));
         });
 
         return customNodes;

+ 4 - 3
src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts

@@ -1,11 +1,12 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-nodes/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate';
 
@@ -15,9 +16,9 @@ import { Utils } from '../../Utils';
 
 export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {string}

+ 12 - 5
src/custom-nodes/console-output-nodes/factory/ConsoleOutputCustomNodesFactory.ts

@@ -1,4 +1,6 @@
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IObfuscationEventEmitter } from '../../../interfaces/IObfuscationEventEmitter';
+import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData';
 
 import { ConsoleOutputDisableExpressionNode } from '../ConsoleOutputDisableExpressionNode';
 import { NodeCallsControllerFunctionNode } from '../../node-calls-controller-nodes/NodeCallsControllerFunctionNode';
@@ -9,21 +11,26 @@ import { Utils } from '../../../Utils';
 
 export class ConsoleOutputCustomNodesFactory extends AbstractCustomNodesFactory {
     /**
+     * @param obfuscationEventEmitter
+     * @param stackTraceData
      * @returns {Map<string, ICustomNode>}
      */
-    public initializeCustomNodes (): Map <string, ICustomNode> | undefined {
+    public initializeCustomNodes (
+        obfuscationEventEmitter: IObfuscationEventEmitter,
+        stackTraceData: IStackTraceData[]
+    ): Map <string, ICustomNode> | undefined {
         if (!this.options.disableConsoleOutput) {
             return;
         }
 
         const callsControllerFunctionName: string = Utils.getRandomVariableName();
-        const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
+        const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(stackTraceData.length);
 
-        return this.syncCustomNodesWithNodesFactory(new Map <string, ICustomNode> ([
+        return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, new Map <string, ICustomNode> ([
             [
                 'consoleOutputDisableExpressionNode',
                 new ConsoleOutputDisableExpressionNode(
-                    this.stackTraceData,
+                    stackTraceData,
                     callsControllerFunctionName,
                     randomStackTraceIndex,
                     this.options
@@ -32,7 +39,7 @@ export class ConsoleOutputCustomNodesFactory extends AbstractCustomNodesFactory
             [
                 'ConsoleOutputNodeCallsControllerFunctionNode',
                 new NodeCallsControllerFunctionNode(
-                    this.stackTraceData,
+                    stackTraceData,
                     callsControllerFunctionName,
                     randomStackTraceIndex,
                     this.options

+ 4 - 3
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts

@@ -1,10 +1,11 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../../types/TObfuscationEvent';
 
 import { IOptions } from '../../../interfaces/IOptions';
 
-import { AppendState } from '../../../enums/AppendState';
+import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { BinaryExpressionFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate';
 
@@ -13,9 +14,9 @@ import { Utils } from '../../../Utils';
 
 export class BinaryExpressionFunctionNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {string}

+ 4 - 3
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode.ts

@@ -1,10 +1,11 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../../types/TObfuscationEvent';
 
 import { IOptions } from '../../../interfaces/IOptions';
 
-import { AppendState } from '../../../enums/AppendState';
+import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { ControlFlowStorageCallTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallTemplate';
 
@@ -13,9 +14,9 @@ import { NodeAppender } from '../../../node/NodeAppender';
 
 export class ControlFlowStorageCallNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
      * @type {string}

+ 4 - 3
src/custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts

@@ -1,12 +1,13 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
 import { IStorage } from '../../interfaces/IStorage';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { ControlFlowStorageTemplate } from '../../templates/custom-nodes/control-flow-storage-nodes/ControlFlowStorageTemplate';
 
@@ -15,9 +16,9 @@ import { NodeAppender } from '../../node/NodeAppender';
 
 export class ControlFlowStorageNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
      * @type {IStorage <ICustomNode>}

+ 4 - 3
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts

@@ -1,10 +1,11 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { DebugProtectionFunctionCallTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate';
 
@@ -13,9 +14,9 @@ import { NodeAppender } from '../../node/NodeAppender';
 
 export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {string}

+ 4 - 3
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts

@@ -1,10 +1,11 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { DebugProtectionFunctionIntervalTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate';
 
@@ -13,9 +14,9 @@ import { NodeAppender } from '../../node/NodeAppender';
 
 export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {string}

+ 4 - 3
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts

@@ -1,10 +1,11 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { DebugProtectionFunctionTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate';
 
@@ -14,9 +15,9 @@ import { Utils } from '../../Utils';
 
 export class DebugProtectionFunctionNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {string}

+ 10 - 3
src/custom-nodes/debug-protection-nodes/factory/DebugProtectionCustomNodesFactory.ts

@@ -1,4 +1,6 @@
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IObfuscationEventEmitter } from '../../../interfaces/IObfuscationEventEmitter';
+import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData';
 
 import { DebugProtectionFunctionCallNode } from '../DebugProtectionFunctionCallNode';
 import { DebugProtectionFunctionIntervalNode } from '../DebugProtectionFunctionIntervalNode';
@@ -9,9 +11,14 @@ import { Utils } from '../../../Utils';
 
 export class DebugProtectionCustomNodesFactory extends AbstractCustomNodesFactory {
     /**
-     * @returns {Map<string, ICustomNode> | undefined}
+     * @param obfuscationEventEmitter
+     * @param stackTraceData
+     * @returns {Map<string, ICustomNode>}
      */
-    public initializeCustomNodes (): Map <string, ICustomNode> | undefined {
+    public initializeCustomNodes (
+        obfuscationEventEmitter: IObfuscationEventEmitter,
+        stackTraceData: IStackTraceData[]
+    ): Map <string, ICustomNode> | undefined {
         if (!this.options.debugProtection) {
             return;
         }
@@ -35,6 +42,6 @@ export class DebugProtectionCustomNodesFactory extends AbstractCustomNodesFactor
             );
         }
 
-        return this.syncCustomNodesWithNodesFactory(customNodes);
+        return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, customNodes);
     }
 }

+ 4 - 3
src/custom-nodes/domain-lock-nodes/DomainLockNode.ts

@@ -1,11 +1,12 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { DomainLockNodeTemplate } from '../../templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
 
@@ -15,9 +16,9 @@ import { Utils } from '../../Utils';
 
 export class DomainLockNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {string}

+ 13 - 6
src/custom-nodes/domain-lock-nodes/factory/DomainLockCustomNodesFactory.ts

@@ -1,4 +1,6 @@
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IObfuscationEventEmitter } from '../../../interfaces/IObfuscationEventEmitter';
+import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData';
 
 import { DomainLockNode } from '../DomainLockNode';
 import { NodeCallsControllerFunctionNode } from '../../node-calls-controller-nodes/NodeCallsControllerFunctionNode';
@@ -9,21 +11,26 @@ import { Utils } from '../../../Utils';
 
 export class DomainLockCustomNodesFactory extends AbstractCustomNodesFactory {
     /**
-     * @returns {Map<string, ICustomNode> | undefined}
+     * @param obfuscationEventEmitter
+     * @param stackTraceData
+     * @returns {Map<string, ICustomNode>}
      */
-    public initializeCustomNodes (): Map <string, ICustomNode> | undefined {
+    public initializeCustomNodes (
+        obfuscationEventEmitter: IObfuscationEventEmitter,
+        stackTraceData: IStackTraceData[]
+    ): Map <string, ICustomNode> | undefined {
         if (!this.options.domainLock.length) {
             return;
         }
 
         const callsControllerFunctionName: string = Utils.getRandomVariableName();
-        const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
+        const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(stackTraceData.length);
 
-        return this.syncCustomNodesWithNodesFactory(new Map <string, ICustomNode> ([
+        return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, new Map <string, ICustomNode> ([
             [
                 'DomainLockNode',
                 new DomainLockNode(
-                    this.stackTraceData,
+                    stackTraceData,
                     callsControllerFunctionName,
                     randomStackTraceIndex,
                     this.options
@@ -32,7 +39,7 @@ export class DomainLockCustomNodesFactory extends AbstractCustomNodesFactory {
             [
                 'DomainLockNodeCallsControllerFunctionNode',
                 new NodeCallsControllerFunctionNode(
-                    this.stackTraceData,
+                    stackTraceData,
                     callsControllerFunctionName,
                     randomStackTraceIndex,
                     this.options

+ 5 - 4
src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts

@@ -1,11 +1,12 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { SingleNodeCallControllerTemplate } from '../../templates/custom-nodes/SingleNodeCallControllerTemplate';
 
@@ -17,9 +18,9 @@ import { NodeAppender } from '../../node/NodeAppender';
 
 export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.BeforeObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.BeforeObfuscation;
 
     /**
      * @type {string}
@@ -75,7 +76,7 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
      * @returns {string}
      */
     public getCode (): string {
-        if (this.appendState === AppendState.AfterObfuscation) {
+        if (this.appendEvent === ObfuscationEvents.AfterObfuscation) {
             return JavaScriptObfuscator.obfuscate(
                 format(SingleNodeCallControllerTemplate(), {
                     singleNodeCallControllerFunctionName: this.callsControllerFunctionName

+ 4 - 3
src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts

@@ -1,11 +1,12 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 import { IStackTraceData } from '../../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../preset-options/NoCustomNodesPreset';
 
@@ -18,9 +19,9 @@ import { Utils } from '../../Utils';
 
 export class SelfDefendingUnicodeNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
      * @type {string}

+ 18 - 9
src/custom-nodes/self-defending-nodes/factory/SelfDefendingCustomNodesFactory.ts

@@ -1,6 +1,10 @@
+import { TObfuscationEvent } from '../../../types/TObfuscationEvent';
+
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IObfuscationEventEmitter } from '../../../interfaces/IObfuscationEventEmitter';
+import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from '../../../enums/AppendState';
+import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { NodeCallsControllerFunctionNode } from '../../node-calls-controller-nodes/NodeCallsControllerFunctionNode';
 import { SelfDefendingUnicodeNode } from '../SelfDefendingUnicodeNode';
@@ -11,26 +15,31 @@ import { Utils } from '../../../Utils';
 
 export class SelfDefendingCustomNodesFactory extends AbstractCustomNodesFactory {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
-     * @returns {Map<string, ICustomNode> | undefined}
+     * @param obfuscationEventEmitter
+     * @param stackTraceData
+     * @returns {Map<string, ICustomNode>}
      */
-    public initializeCustomNodes (): Map <string, ICustomNode> | undefined {
+    public initializeCustomNodes (
+        obfuscationEventEmitter: IObfuscationEventEmitter,
+        stackTraceData: IStackTraceData[]
+    ): Map <string, ICustomNode> | undefined {
         if (!this.options.selfDefending) {
             return;
         }
 
         const callsControllerFunctionName: string = Utils.getRandomVariableName();
-        const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(this.stackTraceData.length);
+        const randomStackTraceIndex: number = NodeAppender.getRandomStackTraceIndex(stackTraceData.length);
 
-        return this.syncCustomNodesWithNodesFactory(new Map <string, ICustomNode> ([
+        return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, new Map <string, ICustomNode> ([
             [
                 'selfDefendingUnicodeNode',
                 new SelfDefendingUnicodeNode(
-                    this.stackTraceData,
+                    stackTraceData,
                     callsControllerFunctionName,
                     randomStackTraceIndex,
                     this.options
@@ -39,7 +48,7 @@ export class SelfDefendingCustomNodesFactory extends AbstractCustomNodesFactory
             [
                 'SelfDefendingNodeCallsControllerFunctionNode',
                 new NodeCallsControllerFunctionNode(
-                    this.stackTraceData,
+                    stackTraceData,
                     callsControllerFunctionName,
                     randomStackTraceIndex,
                     this.options

+ 4 - 3
src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts

@@ -1,13 +1,14 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 import { TStatement } from '../../types/TStatement';
 
 import { ICustomNodeWithIdentifier } from '../../interfaces/custom-nodes/ICustomNodeWithIdentifier';
 import { IOptions } from '../../interfaces/IOptions';
 import { IStorage } from '../../interfaces/IStorage';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../preset-options/NoCustomNodesPreset';
@@ -25,9 +26,9 @@ import { NodeAppender } from '../../node/NodeAppender';
 
 export class StringArrayCallsWrapper extends AbstractCustomNode implements ICustomNodeWithIdentifier {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
      * @type {IStorage <string>}

+ 4 - 3
src/custom-nodes/string-array-nodes/StringArrayNode.ts

@@ -1,13 +1,14 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 import { TStatement } from '../../types/TStatement';
 
 import { ICustomNodeWithData } from '../../interfaces/custom-nodes/ICustomNodeWithData';
 import { IOptions } from '../../interfaces/IOptions';
 import { IStorage } from '../../interfaces/IStorage';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { StringArrayTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-node/StringArrayTemplate';
 
@@ -22,9 +23,9 @@ export class StringArrayNode extends AbstractCustomNode implements ICustomNodeWi
     public static ARRAY_RANDOM_LENGTH: number = 4;
 
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
      * @type {IStorage <string>}

+ 4 - 3
src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts

@@ -1,11 +1,12 @@
 import * as format from 'string-template';
 
 import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 
 import { IOptions } from '../../interfaces/IOptions';
 import { IStorage } from '../../interfaces/IStorage';
 
-import { AppendState } from '../../enums/AppendState';
+import { ObfuscationEvents } from '../../enums/ObfuscationEvents';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../preset-options/NoCustomNodesPreset';
 
@@ -19,9 +20,9 @@ import { Utils } from '../../Utils';
 
 export class StringArrayRotateFunctionNode extends AbstractCustomNode {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected readonly appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
      * @type {IStorage <string>}

+ 15 - 6
src/custom-nodes/string-array-nodes/factory/StringArrayCustomNodesFactory.ts

@@ -1,6 +1,10 @@
+import { TObfuscationEvent } from '../../../types/TObfuscationEvent';
+
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IObfuscationEventEmitter } from '../../../interfaces/IObfuscationEventEmitter';
+import { IStackTraceData } from '../../../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { AppendState } from '../../../enums/AppendState';
+import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { StringArrayCallsWrapper } from '../StringArrayCallsWrapper';
 import { StringArrayNode } from '../StringArrayNode';
@@ -13,9 +17,9 @@ import { IStorage } from '../../../interfaces/IStorage';
 
 export class StringArrayCustomNodesFactory extends AbstractCustomNodesFactory {
     /**
-     * @type {AppendState}
+     * @type {TObfuscationEvent}
      */
-    protected appendState: AppendState = AppendState.AfterObfuscation;
+    protected appendEvent: TObfuscationEvent = ObfuscationEvents.AfterObfuscation;
 
     /**
      * @type {string}
@@ -33,9 +37,14 @@ export class StringArrayCustomNodesFactory extends AbstractCustomNodesFactory {
     private stringArrayRotateValue: number;
 
     /**
-     * @returns {Map<string, ICustomNode> | undefined}
+     * @param obfuscationEventEmitter
+     * @param stackTraceData
+     * @returns {Map<string, ICustomNode>}
      */
-    public initializeCustomNodes (): Map <string, ICustomNode> | undefined {
+    public initializeCustomNodes (
+        obfuscationEventEmitter: IObfuscationEventEmitter,
+        stackTraceData: IStackTraceData[]
+    ): Map <string, ICustomNode> | undefined {
         if (!this.options.stringArray) {
             return;
         }
@@ -80,6 +89,6 @@ export class StringArrayCustomNodesFactory extends AbstractCustomNodesFactory {
             );
         }
 
-        return this.syncCustomNodesWithNodesFactory(customNodes);
+        return this.syncCustomNodesWithNodesFactory(obfuscationEventEmitter, customNodes);
     }
 }

+ 0 - 4
src/enums/AppendState.ts

@@ -1,4 +0,0 @@
-export enum AppendState {
-    AfterObfuscation,
-    BeforeObfuscation
-}

+ 11 - 0
src/enums/ObfuscationEvents.ts

@@ -0,0 +1,11 @@
+import { TObfuscationEvent } from '../types/TObfuscationEvent';
+
+import { Utils } from '../Utils';
+
+export const ObfuscationEvents: {
+    AfterObfuscation: TObfuscationEvent,
+    BeforeObfuscation: TObfuscationEvent
+} = Utils.strEnumify({
+    AfterObfuscation: 'afterObfuscation',
+    BeforeObfuscation: 'beforeObfuscation'
+});

+ 5 - 0
src/event-emitters/ObfuscationEventEmitter.ts

@@ -0,0 +1,5 @@
+import { IObfuscationEventEmitter } from '../interfaces/IObfuscationEventEmitter';
+
+import { EventEmitter } from 'events';
+
+export class ObfuscationEventEmitter extends EventEmitter implements IObfuscationEventEmitter {}

+ 4 - 1
src/interfaces/ICustomNodesFactory.d.ts

@@ -1,8 +1,11 @@
+import { EventEmitter } from 'events';
+
 import { ICustomNode } from './custom-nodes/ICustomNode';
+import { IStackTraceData } from './stack-trace-analyzer/IStackTraceData';
 
 export interface ICustomNodesFactory {
     /**
      * @returns {Map <string, ICustomNode> | undefined}
      */
-    initializeCustomNodes (): Map <string, ICustomNode> | undefined;
+    initializeCustomNodes (eventEmitter: EventEmitter, stackTraceData: IStackTraceData[]): Map <string, ICustomNode> | undefined;
 }

+ 8 - 0
src/interfaces/IObfuscationEventEmitter.d.ts

@@ -0,0 +1,8 @@
+import Events = NodeJS.Events;
+
+import { TObfuscationEvent } from '../types/TObfuscationEvent';
+
+export interface IObfuscationEventEmitter extends Events {
+    on(event: TObfuscationEvent, listener: Function): this;
+    once(event: TObfuscationEvent, listener: Function): this;
+}

+ 4 - 5
src/interfaces/custom-nodes/ICustomNode.d.ts

@@ -1,9 +1,8 @@
 import * as ESTree from 'estree';
 
+import { TObfuscationEvent } from '../../types/TObfuscationEvent';
 import { TStatement } from '../../types/TStatement';
 
-import { AppendState } from '../../enums/AppendState';
-
 export interface ICustomNode {
     /**
      * @param astTree
@@ -11,9 +10,9 @@ export interface ICustomNode {
     appendNode (astTree: ESTree.Node): void;
 
     /**
-     * @returns {AppendState}
+     * @returns {TObfuscationEvent}
      */
-    getAppendState (): AppendState;
+    getAppendEvent (): TObfuscationEvent;
 
     /**
      * @returns {string}
@@ -28,5 +27,5 @@ export interface ICustomNode {
     /**
      * @param appendState
      */
-    setAppendState (appendState: AppendState): void;
+    setAppendEvent (appendState: TObfuscationEvent): void;
 }

+ 1 - 2
src/types/TCustomNodesFactory.d.ts

@@ -1,5 +1,4 @@
 import { ICustomNodesFactory } from '../interfaces/ICustomNodesFactory';
 import { IOptions } from '../interfaces/IOptions';
-import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
 
-export type TCustomNodesFactory = new (stackTraceData: IStackTraceData[], options: IOptions) => ICustomNodesFactory;
+export type TCustomNodesFactory = new (options: IOptions) => ICustomNodesFactory;

+ 1 - 0
src/types/TObfuscationEvent.d.ts

@@ -0,0 +1 @@
+export type TObfuscationEvent = 'beforeObfuscation' | 'afterObfuscation';