sanex3339 9 лет назад
Родитель
Сommit
f7ff0fd853

+ 171 - 162
dist/index.js

@@ -53,7 +53,7 @@ module.exports =
 /******/ 	__webpack_require__.p = "";
 
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 14);
+/******/ 	return __webpack_require__(__webpack_require__.s = 15);
 /******/ })
 /************************************************************************/
 /******/ ([
@@ -350,9 +350,7 @@ module.exports =
 	var NodeUtils_1 = __webpack_require__(0);
 
 	var Node = function () {
-	    function Node() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function Node(options) {
 	        _classCallCheck(this, Node);
 
 	        this.appendState = AppendState_1.AppendState.BeforeObfuscation;
@@ -447,9 +445,7 @@ module.exports =
 	var Utils_1 = __webpack_require__(1);
 
 	var NodeObfuscator = function () {
-	    function NodeObfuscator(nodes) {
-	        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
+	    function NodeObfuscator(nodes, options) {
 	        _classCallCheck(this, NodeObfuscator);
 
 	        this.nodes = nodes;
@@ -459,7 +455,7 @@ module.exports =
 	    _createClass(NodeObfuscator, [{
 	        key: "isReservedName",
 	        value: function isReservedName(name) {
-	            return this.options['reservedNames'].some(function (reservedName) {
+	            return this.options.getOption('reservedNames').some(function (reservedName) {
 	                return new RegExp(reservedName, 'g').test(name);
 	            });
 	        }
@@ -493,12 +489,12 @@ module.exports =
 	        key: "replaceLiteralValueByUnicodeValue",
 	        value: function replaceLiteralValueByUnicodeValue(nodeValue) {
 	            var value = nodeValue,
-	                replaceByUnicodeArrayFlag = Math.random() <= this.options['unicodeArrayThreshold'];
-	            if (this.options['encodeUnicodeLiterals'] && replaceByUnicodeArrayFlag) {
+	                replaceByUnicodeArrayFlag = Math.random() <= this.options.getOption('unicodeArrayThreshold');
+	            if (this.options.getOption('encodeUnicodeLiterals') && replaceByUnicodeArrayFlag) {
 	                value = Utils_1.Utils.btoa(value);
 	            }
 	            value = Utils_1.Utils.stringToUnicode(value);
-	            if (!this.options['unicodeArray'] || !replaceByUnicodeArrayFlag) {
+	            if (!this.options.getOption('unicodeArray') || !replaceByUnicodeArrayFlag) {
 	                return value;
 	            }
 	            return this.replaceLiteralValueByUnicodeArrayCall(value);
@@ -518,7 +514,7 @@ module.exports =
 	                unicodeArrayNode.updateNodeData(value);
 	            }
 	            hexadecimalIndex = this.replaceLiteralNumberByHexadecimalValue(index);
-	            if (this.options['wrapUnicodeArrayCalls']) {
+	            if (this.options.getOption('wrapUnicodeArrayCalls')) {
 	                return this.nodes.get('unicodeArrayCallsWrapper').getNodeIdentifier() + "('" + hexadecimalIndex + "')";
 	            }
 	            return unicodeArrayNode.getNodeIdentifier() + "[" + hexadecimalIndex + "]";
@@ -631,11 +627,9 @@ module.exports =
 
 	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-	var Kernel_1 = __webpack_require__(39);
+	var Kernel_1 = __webpack_require__(16);
 	var esprima = __webpack_require__(7);
 	var escodegen = __webpack_require__(9);
-	var DefaultPreset_1 = __webpack_require__(37);
-	var OptionsNormalizer_1 = __webpack_require__(16);
 
 	var JavaScriptObfuscator = function () {
 	    function JavaScriptObfuscator() {
@@ -646,8 +640,9 @@ module.exports =
 	        key: "obfuscate",
 	        value: function obfuscate(sourceCode, customOptions) {
 	            var astTree = esprima.parse(sourceCode),
-	                options = OptionsNormalizer_1.OptionsNormalizer.normalize(Object.assign({}, DefaultPreset_1.DEFAULT_PRESET, customOptions)),
+	                options = Kernel_1.default.get('IOptions'),
 	                obfuscator = Kernel_1.default.get('IObfuscator');
+	            options.assign(customOptions);
 	            astTree = obfuscator.obfuscateNode(astTree);
 	            return JavaScriptObfuscator.generateCode(astTree, options);
 	        }
@@ -655,11 +650,9 @@ module.exports =
 	        key: "generateCode",
 	        value: function generateCode(astTree, options) {
 	            var escodegenParams = Object.assign({}, JavaScriptObfuscator.escodegenParams);
-	            if (options.hasOwnProperty('compact')) {
-	                escodegenParams.format = {
-	                    compact: options.compact
-	                };
-	            }
+	            escodegenParams.format = {
+	                compact: options.getOption('compact')
+	            };
 	            return escodegen.generate(astTree, escodegenParams);
 	        }
 	    }]);
@@ -684,9 +677,7 @@ module.exports =
 	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 	var NodesGroup = function () {
-	    function NodesGroup() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function NodesGroup(options) {
 	        _classCallCheck(this, NodesGroup);
 
 	        this.nodes = new Map();
@@ -730,21 +721,43 @@ module.exports =
 /* 13 */
 /***/ function(module, exports) {
 
-	module.exports = require("babel-polyfill");
+	module.exports = require("inversify");
 
 /***/ },
 /* 14 */
+/***/ function(module, exports) {
+
+	module.exports = require("babel-polyfill");
+
+/***/ },
+/* 15 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
 	"use strict";
 
-	__webpack_require__(13);
+	__webpack_require__(14);
 	var JavaScriptObfuscator_1 = __webpack_require__(10);
 	module.exports = JavaScriptObfuscator_1.JavaScriptObfuscator;
 
 /***/ },
-/* 15 */
+/* 16 */
+/***/ function(module, exports, __webpack_require__) {
+
+	"use strict";
+	"use strict";
+
+	var inversify_1 = __webpack_require__(13);
+	var Obfuscator_1 = __webpack_require__(17);
+	var Options_1 = __webpack_require__(18);
+	var kernel = new inversify_1.Kernel();
+	kernel.bind('IOptions').to(Options_1.Options);
+	kernel.bind('IObfuscator').to(Obfuscator_1.Obfuscator);
+	Object.defineProperty(exports, "__esModule", { value: true });
+	exports.default = kernel;
+
+/***/ },
+/* 17 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -767,27 +780,30 @@ module.exports =
 	var __metadata = undefined && undefined.__metadata || function (k, v) {
 	    if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
 	};
-	var inversify_1 = __webpack_require__(38);
+	var __param = undefined && undefined.__param || function (paramIndex, decorator) {
+	    return function (target, key) {
+	        decorator(target, key, paramIndex);
+	    };
+	};
+	var inversify_1 = __webpack_require__(13);
 	var estraverse = __webpack_require__(4);
 	var AppendState_1 = __webpack_require__(6);
 	var NodeType_1 = __webpack_require__(3);
-	var CatchClauseObfuscator_1 = __webpack_require__(29);
-	var ConsoleOutputDisableExpressionNode_1 = __webpack_require__(17);
-	var DebugProtectionNodesGroup_1 = __webpack_require__(26);
-	var FunctionDeclarationObfuscator_1 = __webpack_require__(30);
-	var FunctionObfuscator_1 = __webpack_require__(31);
-	var LiteralObfuscator_1 = __webpack_require__(32);
-	var MemberExpressionObfuscator_1 = __webpack_require__(33);
-	var MethodDefinitionObfuscator_1 = __webpack_require__(34);
+	var CatchClauseObfuscator_1 = __webpack_require__(31);
+	var ConsoleOutputDisableExpressionNode_1 = __webpack_require__(19);
+	var DebugProtectionNodesGroup_1 = __webpack_require__(28);
+	var FunctionDeclarationObfuscator_1 = __webpack_require__(32);
+	var FunctionObfuscator_1 = __webpack_require__(33);
+	var LiteralObfuscator_1 = __webpack_require__(34);
+	var MemberExpressionObfuscator_1 = __webpack_require__(35);
+	var MethodDefinitionObfuscator_1 = __webpack_require__(36);
 	var NodeUtils_1 = __webpack_require__(0);
-	var ObjectExpressionObfuscator_1 = __webpack_require__(35);
-	var SelfDefendingNodesGroup_1 = __webpack_require__(27);
-	var UnicodeArrayNodesGroup_1 = __webpack_require__(28);
-	var VariableDeclarationObfuscator_1 = __webpack_require__(36);
+	var ObjectExpressionObfuscator_1 = __webpack_require__(37);
+	var SelfDefendingNodesGroup_1 = __webpack_require__(29);
+	var UnicodeArrayNodesGroup_1 = __webpack_require__(30);
+	var VariableDeclarationObfuscator_1 = __webpack_require__(38);
 	var Obfuscator = function () {
-	    function Obfuscator() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function Obfuscator(options) {
 	        _classCallCheck(this, Obfuscator);
 
 	        this.nodes = new Map();
@@ -864,16 +880,16 @@ module.exports =
 	    }, {
 	        key: "setNewNodes",
 	        value: function setNewNodes() {
-	            if (this.options['selfDefending']) {
+	            if (this.options.getOption('selfDefending')) {
 	                this.setNodesGroup(new SelfDefendingNodesGroup_1.SelfDefendingNodesGroup(this.options));
 	            }
-	            if (this.options['disableConsoleOutput']) {
-	                this.setNode('consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode());
+	            if (this.options.getOption('disableConsoleOutput')) {
+	                this.setNode('consoleOutputDisableExpressionNode', new ConsoleOutputDisableExpressionNode_1.ConsoleOutputDisableExpressionNode(this.options));
 	            }
-	            if (this.options['debugProtection']) {
+	            if (this.options.getOption('debugProtection')) {
 	                this.setNodesGroup(new DebugProtectionNodesGroup_1.DebugProtectionNodesGroup(this.options));
 	            }
-	            if (this.options['unicodeArray']) {
+	            if (this.options.getOption('unicodeArray')) {
 	                this.setNodesGroup(new UnicodeArrayNodesGroup_1.UnicodeArrayNodesGroup(this.options));
 	            }
 	        }
@@ -881,52 +897,87 @@ module.exports =
 
 	    return Obfuscator;
 	}();
-	Obfuscator = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [Object])], Obfuscator);
+	Obfuscator = __decorate([inversify_1.injectable(), __param(0, inversify_1.inject('IOptions')), __metadata('design:paramtypes', [Object])], Obfuscator);
 	exports.Obfuscator = Obfuscator;
 
 /***/ },
-/* 16 */
-/***/ function(module, exports) {
+/* 18 */
+/***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
 	"use strict";
 
 	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 
+	var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
+
 	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-	var OptionsNormalizer = function () {
-	    function OptionsNormalizer() {
-	        _classCallCheck(this, OptionsNormalizer);
+	var __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) {
+	    var c = arguments.length,
+	        r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
+	        d;
+	    if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) {
+	        if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+	    }return c > 3 && r && Object.defineProperty(target, key, r), r;
+	};
+	var __metadata = undefined && undefined.__metadata || function (k, v) {
+	    if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+	};
+	var inversify_1 = __webpack_require__(13);
+	var DefaultPreset_1 = __webpack_require__(39);
+	var Options_1 = void 0;
+	var Options = Options_1 = function () {
+	    function Options() {
+	        _classCallCheck(this, Options);
 	    }
 
-	    _createClass(OptionsNormalizer, null, [{
-	        key: 'normalize',
-	        value: function normalize(options) {
-	            var normalizedOptions = Object.assign({}, options);
-	            normalizedOptions = OptionsNormalizer.unicodeArrayRule(normalizedOptions);
-	            normalizedOptions = OptionsNormalizer.unicodeArrayThresholdRule(normalizedOptions);
-	            normalizedOptions = OptionsNormalizer.selfDefendingRule(normalizedOptions);
-	            return normalizedOptions;
+	    _createClass(Options, [{
+	        key: "assign",
+	        value: function assign(options) {
+	            if (this.options) {
+	                throw new Error('Options can\'t be reassigned!');
+	            }
+	            this.options = Object.assign({}, DefaultPreset_1.DEFAULT_PRESET, options);
+	            this.normalizeOptions();
 	        }
 	    }, {
-	        key: 'selfDefendingRule',
+	        key: "getOption",
+	        value: function getOption(optionName) {
+	            return this.options[optionName];
+	        }
+	    }, {
+	        key: "getOptions",
+	        value: function getOptions() {
+	            return this.options;
+	        }
+	    }, {
+	        key: "normalizeOptions",
+	        value: function normalizeOptions() {
+	            var normalizedOptions = Object.assign({}, this.options);
+	            normalizedOptions = Options_1.unicodeArrayRule(normalizedOptions);
+	            normalizedOptions = Options_1.unicodeArrayThresholdRule(normalizedOptions);
+	            normalizedOptions = Options_1.selfDefendingRule(normalizedOptions);
+	            this.options = Object.freeze(normalizedOptions);
+	        }
+	    }], [{
+	        key: "selfDefendingRule",
 	        value: function selfDefendingRule(options) {
 	            if (options['selfDefending']) {
-	                Object.assign(options, OptionsNormalizer.SELF_DEFENDING_OPTIONS);
+	                Object.assign(options, Options_1.SELF_DEFENDING_OPTIONS);
 	            }
 	            return options;
 	        }
 	    }, {
-	        key: 'unicodeArrayRule',
+	        key: "unicodeArrayRule",
 	        value: function unicodeArrayRule(options) {
 	            if (!options['unicodeArray']) {
-	                Object.assign(options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS);
+	                Object.assign(options, Options_1.DISABLED_UNICODE_ARRAY_OPTIONS);
 	            }
 	            return options;
 	        }
 	    }, {
-	        key: 'unicodeArrayThresholdRule',
+	        key: "unicodeArrayThresholdRule",
 	        value: function unicodeArrayThresholdRule(options) {
 	            var minValue = 0,
 	                maxValue = 1;
@@ -935,24 +986,24 @@ module.exports =
 	        }
 	    }]);
 
-	    return OptionsNormalizer;
+	    return Options;
 	}();
-
-	OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS = {
+	Options.DISABLED_UNICODE_ARRAY_OPTIONS = {
 	    encodeUnicodeLiterals: false,
 	    rotateUnicodeArray: false,
 	    unicodeArray: false,
 	    unicodeArrayThreshold: 0,
 	    wrapUnicodeArrayCalls: false
 	};
-	OptionsNormalizer.SELF_DEFENDING_OPTIONS = {
+	Options.SELF_DEFENDING_OPTIONS = {
 	    compact: true,
 	    selfDefending: true
 	};
-	exports.OptionsNormalizer = OptionsNormalizer;
+	Options = Options_1 = __decorate([inversify_1.injectable(), __metadata('design:paramtypes', [])], Options);
+	exports.Options = Options;
 
 /***/ },
-/* 17 */
+/* 19 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -973,9 +1024,7 @@ module.exports =
 	var ConsoleOutputDisableExpressionNode = function (_Node_1$Node) {
 	    _inherits(ConsoleOutputDisableExpressionNode, _Node_1$Node);
 
-	    function ConsoleOutputDisableExpressionNode() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function ConsoleOutputDisableExpressionNode(options) {
 	        _classCallCheck(this, ConsoleOutputDisableExpressionNode);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ConsoleOutputDisableExpressionNode).call(this, options));
@@ -1002,7 +1051,7 @@ module.exports =
 	exports.ConsoleOutputDisableExpressionNode = ConsoleOutputDisableExpressionNode;
 
 /***/ },
-/* 18 */
+/* 20 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1023,9 +1072,7 @@ module.exports =
 	var DebugProtectionFunctionCallNode = function (_Node_1$Node) {
 	    _inherits(DebugProtectionFunctionCallNode, _Node_1$Node);
 
-	    function DebugProtectionFunctionCallNode(debugProtectionFunctionName) {
-	        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
+	    function DebugProtectionFunctionCallNode(debugProtectionFunctionName, options) {
 	        _classCallCheck(this, DebugProtectionFunctionCallNode);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionCallNode).call(this, options));
@@ -1063,7 +1110,7 @@ module.exports =
 	exports.DebugProtectionFunctionCallNode = DebugProtectionFunctionCallNode;
 
 /***/ },
-/* 19 */
+/* 21 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1084,9 +1131,7 @@ module.exports =
 	var DebugProtectionFunctionIntervalNode = function (_Node_1$Node) {
 	    _inherits(DebugProtectionFunctionIntervalNode, _Node_1$Node);
 
-	    function DebugProtectionFunctionIntervalNode(debugProtectionFunctionName) {
-	        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
+	    function DebugProtectionFunctionIntervalNode(debugProtectionFunctionName, options) {
 	        _classCallCheck(this, DebugProtectionFunctionIntervalNode);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionIntervalNode).call(this, options));
@@ -1149,7 +1194,7 @@ module.exports =
 	exports.DebugProtectionFunctionIntervalNode = DebugProtectionFunctionIntervalNode;
 
 /***/ },
-/* 20 */
+/* 22 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1171,9 +1216,7 @@ module.exports =
 	var DebugProtectionFunctionNode = function (_Node_1$Node) {
 	    _inherits(DebugProtectionFunctionNode, _Node_1$Node);
 
-	    function DebugProtectionFunctionNode(debugProtectionFunctionName) {
-	        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
+	    function DebugProtectionFunctionNode(debugProtectionFunctionName, options) {
 	        _classCallCheck(this, DebugProtectionFunctionNode);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionNode).call(this, options));
@@ -1208,7 +1251,7 @@ module.exports =
 	exports.DebugProtectionFunctionNode = DebugProtectionFunctionNode;
 
 /***/ },
-/* 21 */
+/* 23 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1234,9 +1277,7 @@ module.exports =
 	var SelfDefendingUnicodeNode = function (_Node_1$Node) {
 	    _inherits(SelfDefendingUnicodeNode, _Node_1$Node);
 
-	    function SelfDefendingUnicodeNode() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function SelfDefendingUnicodeNode(options) {
 	        _classCallCheck(this, SelfDefendingUnicodeNode);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SelfDefendingUnicodeNode).call(this, options));
@@ -1271,7 +1312,7 @@ module.exports =
 	exports.SelfDefendingUnicodeNode = SelfDefendingUnicodeNode;
 
 /***/ },
-/* 22 */
+/* 24 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1296,9 +1337,7 @@ module.exports =
 	var UnicodeArrayCallsWrapper = function (_Node_1$Node) {
 	    _inherits(UnicodeArrayCallsWrapper, _Node_1$Node);
 
-	    function UnicodeArrayCallsWrapper(unicodeArrayCallsWrapperName, unicodeArrayName, unicodeArray) {
-	        var options = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
-
+	    function UnicodeArrayCallsWrapper(unicodeArrayCallsWrapperName, unicodeArrayName, unicodeArray, options) {
 	        _classCallCheck(this, UnicodeArrayCallsWrapper);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayCallsWrapper).call(this, options));
@@ -1347,7 +1386,7 @@ module.exports =
 	exports.UnicodeArrayCallsWrapper = UnicodeArrayCallsWrapper;
 
 /***/ },
-/* 23 */
+/* 25 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1375,9 +1414,7 @@ module.exports =
 	var UnicodeArrayDecodeNode = function (_Node_1$Node) {
 	    _inherits(UnicodeArrayDecodeNode, _Node_1$Node);
 
-	    function UnicodeArrayDecodeNode(unicodeArrayName, unicodeArray) {
-	        var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
-
+	    function UnicodeArrayDecodeNode(unicodeArrayName, unicodeArray, options) {
 	        _classCallCheck(this, UnicodeArrayDecodeNode);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayDecodeNode).call(this, options));
@@ -1412,7 +1449,7 @@ module.exports =
 	                tempArrayName = Utils_1.Utils.getRandomVariableName();
 	            var code = '',
 	                node = void 0;
-	            if (this.options['selfDefending']) {
+	            if (this.options.getOption('selfDefending')) {
 	                code = '\n                var ' + environmentName + ' = function(){return ' + Utils_1.Utils.stringToUnicode('dev') + ';};\n                   \n                Function(' + Utils_1.Utils.stringToUnicode('return/\\w+ *\\(\\) *{\\w+ *[\'|"].+[\'|"];? *}/') + ')()[' + Utils_1.Utils.stringToUnicode('test') + '](' + environmentName + '[' + Utils_1.Utils.stringToUnicode('toString') + ']()) !== ' + JSFuck_1.JSFuck.True + ' && !' + this.unicodeArrayName + '++ ? [][\'filter\'][\'constructor\'](' + Utils_1.Utils.stringToJSFuck('while') + ' + \'(' + JSFuck_1.JSFuck.True + '){}\')() : Function(' + Utils_1.Utils.stringToUnicode('a') + ', atob(' + Utils_1.Utils.stringToUnicode(Utils_1.Utils.btoa('a.call()')) + '))(' + forLoopFunctionName + ') ? [][\'filter\'][\'constructor\'](' + Utils_1.Utils.stringToJSFuck('while') + ' + \'(' + JSFuck_1.JSFuck.False + '){}\')() : [][\'filter\'][\'constructor\'](' + Utils_1.Utils.stringToJSFuck('while') + ' + \'(' + JSFuck_1.JSFuck.False + '){}\')();\n            ';
 	            } else {
 	                code = forLoopFunctionName + '();';
@@ -1429,7 +1466,7 @@ module.exports =
 	exports.UnicodeArrayDecodeNode = UnicodeArrayDecodeNode;
 
 /***/ },
-/* 24 */
+/* 26 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1457,7 +1494,7 @@ module.exports =
 
 	    function UnicodeArrayNode(unicodeArrayName) {
 	        var unicodeArrayRotateValue = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
-	        var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
+	        var options = arguments[2];
 
 	        _classCallCheck(this, UnicodeArrayNode);
 
@@ -1539,7 +1576,7 @@ module.exports =
 	exports.UnicodeArrayNode = UnicodeArrayNode;
 
 /***/ },
-/* 25 */
+/* 27 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1567,9 +1604,7 @@ module.exports =
 	var UnicodeArrayRotateFunctionNode = function (_Node_1$Node) {
 	    _inherits(UnicodeArrayRotateFunctionNode, _Node_1$Node);
 
-	    function UnicodeArrayRotateFunctionNode(unicodeArrayName, unicodeArray, unicodeArrayRotateValue) {
-	        var options = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
-
+	    function UnicodeArrayRotateFunctionNode(unicodeArrayName, unicodeArray, unicodeArrayRotateValue, options) {
 	        _classCallCheck(this, UnicodeArrayRotateFunctionNode);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayRotateFunctionNode).call(this, options));
@@ -1604,7 +1639,7 @@ module.exports =
 	                timesArgumentName = Utils_1.Utils.getRandomVariableName(),
 	                whileFunctionName = Utils_1.Utils.getRandomVariableName(),
 	                node = void 0;
-	            if (this.options['selfDefending']) {
+	            if (this.options.getOption('selfDefending')) {
 	                code = JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate("\n                (function () {\n                    var func = function(){return " + Utils_1.Utils.stringToUnicode('dev') + ";};\n                                        \n                    !Function(" + Utils_1.Utils.stringToUnicode("return/\\w+ *\\(\\) *{\\w+ *['|\"].+['|\"];? *}/") + ")().test(func.toString()) ? []['filter']['constructor'](" + Utils_1.Utils.stringToJSFuck('while') + " + '(" + JSFuck_1.JSFuck.True + "){}')() : Function(" + Utils_1.Utils.stringToUnicode('a') + ", " + Utils_1.Utils.stringToUnicode('b') + ", " + Utils_1.Utils.stringToUnicode('a(++b)') + ")(" + whileFunctionName + ", " + timesName + ") ? []['filter']['constructor'](" + Utils_1.Utils.stringToJSFuck('while') + " + '(" + JSFuck_1.JSFuck.False + "){}')() : []['filter']['constructor'](" + Utils_1.Utils.stringToJSFuck('while') + " + '(" + JSFuck_1.JSFuck.False + "){}')();\n                })();\n            ", NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET);
 	            } else {
 	                code = whileFunctionName + "(++" + timesName + ")";
@@ -1621,7 +1656,7 @@ module.exports =
 	exports.UnicodeArrayRotateFunctionNode = UnicodeArrayRotateFunctionNode;
 
 /***/ },
-/* 26 */
+/* 28 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1633,18 +1668,16 @@ module.exports =
 
 	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 DebugProtectionFunctionCallNode_1 = __webpack_require__(18);
-	var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(19);
-	var DebugProtectionFunctionNode_1 = __webpack_require__(20);
+	var DebugProtectionFunctionCallNode_1 = __webpack_require__(20);
+	var DebugProtectionFunctionIntervalNode_1 = __webpack_require__(21);
+	var DebugProtectionFunctionNode_1 = __webpack_require__(22);
 	var NodesGroup_1 = __webpack_require__(11);
 	var Utils_1 = __webpack_require__(1);
 
 	var DebugProtectionNodesGroup = function (_NodesGroup_1$NodesGr) {
 	    _inherits(DebugProtectionNodesGroup, _NodesGroup_1$NodesGr);
 
-	    function DebugProtectionNodesGroup() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function DebugProtectionNodesGroup(options) {
 	        _classCallCheck(this, DebugProtectionNodesGroup);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionNodesGroup).call(this, options));
@@ -1652,7 +1685,7 @@ module.exports =
 	        _this.debugProtectionFunctionIdentifier = Utils_1.Utils.getRandomVariableName();
 	        _this.nodes.set('debugProtectionFunctionNode', new DebugProtectionFunctionNode_1.DebugProtectionFunctionNode(_this.debugProtectionFunctionIdentifier, _this.options));
 	        _this.nodes.set('debugProtectionFunctionCallNode', new DebugProtectionFunctionCallNode_1.DebugProtectionFunctionCallNode(_this.debugProtectionFunctionIdentifier, _this.options));
-	        if (_this.options['debugProtectionInterval']) {
+	        if (_this.options.getOption('debugProtectionInterval')) {
 	            _this.nodes.set('debugProtectionFunctionIntervalNode', new DebugProtectionFunctionIntervalNode_1.DebugProtectionFunctionIntervalNode(_this.debugProtectionFunctionIdentifier, _this.options));
 	        }
 	        return _this;
@@ -1664,7 +1697,7 @@ module.exports =
 	exports.DebugProtectionNodesGroup = DebugProtectionNodesGroup;
 
 /***/ },
-/* 27 */
+/* 29 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1677,14 +1710,12 @@ module.exports =
 	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 NodesGroup_1 = __webpack_require__(11);
-	var SelfDefendingUnicodeNode_1 = __webpack_require__(21);
+	var SelfDefendingUnicodeNode_1 = __webpack_require__(23);
 
 	var SelfDefendingNodesGroup = function (_NodesGroup_1$NodesGr) {
 	    _inherits(SelfDefendingNodesGroup, _NodesGroup_1$NodesGr);
 
-	    function SelfDefendingNodesGroup() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function SelfDefendingNodesGroup(options) {
 	        _classCallCheck(this, SelfDefendingNodesGroup);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SelfDefendingNodesGroup).call(this, options));
@@ -1699,7 +1730,7 @@ module.exports =
 	exports.SelfDefendingNodesGroup = SelfDefendingNodesGroup;
 
 /***/ },
-/* 28 */
+/* 30 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1712,35 +1743,33 @@ module.exports =
 	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 NodesGroup_1 = __webpack_require__(11);
-	var UnicodeArrayCallsWrapper_1 = __webpack_require__(22);
-	var UnicodeArrayDecodeNode_1 = __webpack_require__(23);
-	var UnicodeArrayNode_1 = __webpack_require__(24);
-	var UnicodeArrayRotateFunctionNode_1 = __webpack_require__(25);
+	var UnicodeArrayCallsWrapper_1 = __webpack_require__(24);
+	var UnicodeArrayDecodeNode_1 = __webpack_require__(25);
+	var UnicodeArrayNode_1 = __webpack_require__(26);
+	var UnicodeArrayRotateFunctionNode_1 = __webpack_require__(27);
 	var Utils_1 = __webpack_require__(1);
 
 	var UnicodeArrayNodesGroup = function (_NodesGroup_1$NodesGr) {
 	    _inherits(UnicodeArrayNodesGroup, _NodesGroup_1$NodesGr);
 
-	    function UnicodeArrayNodesGroup() {
-	        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
+	    function UnicodeArrayNodesGroup(options) {
 	        _classCallCheck(this, UnicodeArrayNodesGroup);
 
 	        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayNodesGroup).call(this, options));
 
 	        _this.unicodeArrayName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
 	        _this.unicodeArrayTranslatorName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
-	        _this.unicodeArrayRotateValue = _this.options['rotateUnicodeArray'] ? Utils_1.Utils.getRandomInteger(100, 500) : 0;
+	        _this.unicodeArrayRotateValue = _this.options.getOption('rotateUnicodeArray') ? Utils_1.Utils.getRandomInteger(100, 500) : 0;
 	        var unicodeArrayNode = new UnicodeArrayNode_1.UnicodeArrayNode(_this.unicodeArrayName, _this.unicodeArrayRotateValue, _this.options),
 	            unicodeArray = unicodeArrayNode.getNodeData();
 	        _this.nodes.set('unicodeArrayNode', unicodeArrayNode);
-	        if (_this.options['wrapUnicodeArrayCalls']) {
+	        if (_this.options.getOption('wrapUnicodeArrayCalls')) {
 	            _this.nodes.set('unicodeArrayCallsWrapper', new UnicodeArrayCallsWrapper_1.UnicodeArrayCallsWrapper(_this.unicodeArrayTranslatorName, _this.unicodeArrayName, unicodeArray, _this.options));
 	        }
-	        if (_this.options['encodeUnicodeLiterals']) {
+	        if (_this.options.getOption('encodeUnicodeLiterals')) {
 	            _this.nodes.set('unicodeArrayDecodeNode', new UnicodeArrayDecodeNode_1.UnicodeArrayDecodeNode(_this.unicodeArrayName, unicodeArray, _this.options));
 	        }
-	        if (_this.options['rotateUnicodeArray']) {
+	        if (_this.options.getOption('rotateUnicodeArray')) {
 	            _this.nodes.set('unicodeArrayRotateFunctionNode', new UnicodeArrayRotateFunctionNode_1.UnicodeArrayRotateFunctionNode(_this.unicodeArrayName, unicodeArray, _this.unicodeArrayRotateValue, _this.options));
 	        }
 	        return _this;
@@ -1752,7 +1781,7 @@ module.exports =
 	exports.UnicodeArrayNodesGroup = UnicodeArrayNodesGroup;
 
 /***/ },
-/* 29 */
+/* 31 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1830,7 +1859,7 @@ module.exports =
 	exports.CatchClauseObfuscator = CatchClauseObfuscator;
 
 /***/ },
-/* 30 */
+/* 32 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1913,7 +1942,7 @@ module.exports =
 	exports.FunctionDeclarationObfuscator = FunctionDeclarationObfuscator;
 
 /***/ },
-/* 31 */
+/* 33 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -1993,7 +2022,7 @@ module.exports =
 	exports.FunctionObfuscator = FunctionObfuscator;
 
 /***/ },
-/* 32 */
+/* 34 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -2058,7 +2087,7 @@ module.exports =
 	exports.LiteralObfuscator = LiteralObfuscator;
 
 /***/ },
-/* 33 */
+/* 35 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -2151,7 +2180,7 @@ module.exports =
 	exports.MemberExpressionObfuscator = MemberExpressionObfuscator;
 
 /***/ },
-/* 34 */
+/* 36 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -2217,7 +2246,7 @@ module.exports =
 	exports.MethodDefinitionObfuscator = MethodDefinitionObfuscator;
 
 /***/ },
-/* 35 */
+/* 37 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -2309,7 +2338,7 @@ module.exports =
 	exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator;
 
 /***/ },
-/* 36 */
+/* 38 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
@@ -2408,7 +2437,7 @@ module.exports =
 	exports.VariableDeclarationObfuscator = VariableDeclarationObfuscator;
 
 /***/ },
-/* 37 */
+/* 39 */
 /***/ function(module, exports) {
 
 	"use strict";
@@ -2428,25 +2457,5 @@ module.exports =
 	    wrapUnicodeArrayCalls: true
 	});
 
-/***/ },
-/* 38 */
-/***/ function(module, exports) {
-
-	module.exports = require("inversify");
-
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
-
-	"use strict";
-	"use strict";
-
-	var inversify_1 = __webpack_require__(38);
-	var Obfuscator_1 = __webpack_require__(15);
-	var kernel = new inversify_1.Kernel();
-	kernel.bind('IObfuscator').to(Obfuscator_1.Obfuscator);
-	Object.defineProperty(exports, "__esModule", { value: true });
-	exports.default = kernel;
-
 /***/ }
 /******/ ]);

+ 9 - 13
src/JavaScriptObfuscator.ts

@@ -8,11 +8,7 @@ import * as escodegen from 'escodegen';
 import { INode } from './interfaces/nodes/INode';
 import { IObfuscator } from "./interfaces/IObfuscator";
 import { IOptions } from './interfaces/IOptions';
-
-import { DEFAULT_PRESET } from './preset-options/DefaultPreset';
-
-import { Obfuscator } from './Obfuscator';
-import { OptionsNormalizer } from "./OptionsNormalizer";
+import { IOptionsPreset } from "./interfaces/IOptionsPreset";
 
 export class JavaScriptObfuscator {
     /**
@@ -26,10 +22,12 @@ export class JavaScriptObfuscator {
      * @param sourceCode
      * @param customOptions
      */
-    public static obfuscate (sourceCode: string, customOptions?: IOptions): string {
+    public static obfuscate (sourceCode: string, customOptions?: IOptionsPreset): string {
         let astTree: INode = esprima.parse(sourceCode),
-            options: IOptions = OptionsNormalizer.normalize(Object.assign({}, DEFAULT_PRESET, customOptions)),
-            obfuscator: Obfuscator = kernel.get<IObfuscator>('IObfuscator');
+            options: IOptions = kernel.get<IOptions>('IOptions'),
+            obfuscator: IObfuscator = kernel.get<IObfuscator>('IObfuscator');
+
+        options.assign(customOptions);
 
         astTree = obfuscator.obfuscateNode(astTree);
 
@@ -43,11 +41,9 @@ export class JavaScriptObfuscator {
     private static generateCode (astTree: INode, options: IOptions): string {
         let escodegenParams: escodegen.GenerateOptions = Object.assign({}, JavaScriptObfuscator.escodegenParams);
 
-        if (options.hasOwnProperty('compact')) {
-            escodegenParams.format = {
-                compact: options.compact
-            };
-        }
+        escodegenParams.format = {
+            compact: options.getOption('compact')
+        };
 
         return escodegen.generate(astTree, escodegenParams);
     }

+ 3 - 0
src/Kernel.ts

@@ -1,11 +1,14 @@
 import { IKernel } from "inversify";
 import { IObfuscator } from "./interfaces/IObfuscator";
+import { IOptions } from "./interfaces/IOptions";
 
 import { Kernel } from "inversify";
 import { Obfuscator } from "./Obfuscator";
+import { Options } from "./Options";
 
 let kernel: IKernel = new Kernel();
 
+kernel.bind<IOptions>('IOptions').to(Options);
 kernel.bind<IObfuscator>('IObfuscator').to(Obfuscator);
 
 export default kernel;

+ 9 - 7
src/Obfuscator.ts

@@ -1,4 +1,4 @@
-import { injectable } from "inversify";
+import { inject, injectable } from "inversify";
 
 import * as estraverse from 'estraverse';
 
@@ -61,7 +61,9 @@ export class Obfuscator implements IObfuscator {
     /**
      * @param options
      */
-    constructor (options: IOptions = {}) {
+    constructor (
+        @inject('IOptions') options: IOptions
+    ) {
         this.options = options;
     }
 
@@ -149,22 +151,22 @@ export class Obfuscator implements IObfuscator {
     }
 
     private setNewNodes (): void {
-        if (this.options['selfDefending']) {
+        if (this.options.getOption('selfDefending')) {
             this.setNodesGroup(new SelfDefendingNodesGroup(this.options));
         }
 
-        if (this.options['disableConsoleOutput']) {
+        if (this.options.getOption('disableConsoleOutput')) {
             this.setNode(
                 'consoleOutputDisableExpressionNode',
-                new ConsoleOutputDisableExpressionNode()
+                new ConsoleOutputDisableExpressionNode(this.options)
             );
         }
 
-        if (this.options['debugProtection']) {
+        if (this.options.getOption('debugProtection')) {
             this.setNodesGroup(new DebugProtectionNodesGroup(this.options));
         }
 
-        if (this.options['unicodeArray']) {
+        if (this.options.getOption('unicodeArray')) {
             /**
              * Important to set this nodes latest to prevent runtime errors caused by `rotateUnicodeArray` option
              */

+ 114 - 0
src/Options.ts

@@ -0,0 +1,114 @@
+import { injectable } from "inversify";
+
+import { IOptions } from "./interfaces/IOptions";
+import { IOptionsPreset } from "./interfaces/IOptionsPreset";
+
+import { DEFAULT_PRESET } from "./preset-options/DefaultPreset";
+
+@injectable()
+export class Options implements IOptions {
+    /**
+     * @type {IOptionsPreset}
+     */
+    private static DISABLED_UNICODE_ARRAY_OPTIONS: IOptionsPreset = {
+        encodeUnicodeLiterals: false,
+        rotateUnicodeArray: false,
+        unicodeArray: false,
+        unicodeArrayThreshold: 0,
+        wrapUnicodeArrayCalls: false
+    };
+
+    /**
+     * @type {IOptionsPreset}
+     */
+    private options: IOptionsPreset;
+
+    /**
+     * @type {IOptionsPreset}
+     */
+    public static SELF_DEFENDING_OPTIONS: IOptionsPreset = {
+        compact: true,
+        selfDefending: true
+    };
+
+    /**
+     * @param options
+     */
+    public assign (options: IOptionsPreset): void {
+        if (this.options) {
+            throw new Error('Options can\'t be reassigned!');
+        }
+
+        this.options = Object.assign({}, DEFAULT_PRESET, options);
+
+        this.normalizeOptions();
+    }
+
+    /**
+     * @param optionName
+     * @returns {any}
+     */
+    public getOption (optionName: string): any {
+        return this.options[optionName];
+    }
+
+    /**
+     * @returns {IOptionsPreset}
+     */
+    public getOptions (): IOptionsPreset {
+        return this.options;
+    }
+
+    private normalizeOptions (): void {
+        let normalizedOptions: IOptionsPreset = Object.assign({}, this.options);
+
+        normalizedOptions = Options.unicodeArrayRule(normalizedOptions);
+        normalizedOptions = Options.unicodeArrayThresholdRule(normalizedOptions);
+        normalizedOptions = Options.selfDefendingRule(normalizedOptions);
+
+        this.options = Object.freeze(normalizedOptions);
+    }
+
+    /**
+     * @param options
+     * @returns {IOptionsPreset}
+     */
+    private static selfDefendingRule (options: IOptionsPreset): IOptionsPreset {
+        if (options['selfDefending']) {
+            Object.assign(options, Options.SELF_DEFENDING_OPTIONS);
+        }
+
+        return options;
+    }
+
+    /**
+     * @param options
+     * @returns {IOptionsPreset}
+     */
+    private static unicodeArrayRule (options: IOptionsPreset): IOptionsPreset {
+        if (!options['unicodeArray']) {
+            Object.assign(options, Options.DISABLED_UNICODE_ARRAY_OPTIONS);
+        }
+
+        return options;
+    }
+
+    /**
+     * @param options
+     * @returns {IOptionsPreset}
+     */
+    private static unicodeArrayThresholdRule (options: IOptionsPreset): IOptionsPreset {
+        const minValue: number = 0,
+            maxValue: number = 1;
+
+        options['unicodeArrayThreshold'] = Math.min(
+            Math.max(
+                options['unicodeArrayThreshold'],
+                minValue
+            ),
+            maxValue
+        );
+
+        return options;
+    }
+}

+ 0 - 79
src/OptionsNormalizer.ts

@@ -1,79 +0,0 @@
-import { IOptions } from "./interfaces/IOptions";
-
-export class OptionsNormalizer {
-    /**
-     * @type {IOptions}
-     */
-    public static DISABLED_UNICODE_ARRAY_OPTIONS: IOptions = {
-        encodeUnicodeLiterals: false,
-        rotateUnicodeArray: false,
-        unicodeArray: false,
-        unicodeArrayThreshold: 0,
-        wrapUnicodeArrayCalls: false
-    };
-
-    /**
-     * @type {IOptions}
-     */
-    public static SELF_DEFENDING_OPTIONS: IOptions = {
-        compact: true,
-        selfDefending: true
-    };
-
-    /**
-     * @param options
-     * @returns {IOptions}
-     */
-    public static normalize (options: IOptions): IOptions {
-        let normalizedOptions: IOptions = Object.assign({}, options);
-
-        normalizedOptions = OptionsNormalizer.unicodeArrayRule(normalizedOptions);
-        normalizedOptions = OptionsNormalizer.unicodeArrayThresholdRule(normalizedOptions);
-        normalizedOptions = OptionsNormalizer.selfDefendingRule(normalizedOptions);
-
-        return normalizedOptions;
-    }
-
-    /**
-     * @param options
-     * @returns {IOptions}
-     */
-    private static selfDefendingRule (options: IOptions): IOptions {
-        if (options['selfDefending']) {
-            Object.assign(options, OptionsNormalizer.SELF_DEFENDING_OPTIONS);
-        }
-
-        return options;
-    }
-
-    /**
-     * @param options
-     * @returns {IOptions}
-     */
-    private static unicodeArrayRule (options: IOptions): IOptions {
-        if (!options['unicodeArray']) {
-            Object.assign(options, OptionsNormalizer.DISABLED_UNICODE_ARRAY_OPTIONS);
-        }
-
-        return options;
-    }
-
-    /**
-     * @param options
-     * @returns {IOptions}
-     */
-    private static unicodeArrayThresholdRule (options: IOptions): IOptions {
-        const minValue: number = 0,
-            maxValue: number = 1;
-
-        options['unicodeArrayThreshold'] = Math.min(
-            Math.max(
-                options['unicodeArrayThreshold'],
-                minValue
-            ),
-            maxValue
-        );
-
-        return options;
-    }
-}

+ 1 - 1
src/custom-nodes/Node.ts

@@ -25,7 +25,7 @@ export abstract class Node implements ICustomNode {
     /**
      * @param options
      */
-    constructor (options: IOptions = {}) {
+    constructor (options: IOptions) {
         this.options = options;
     }
 

+ 1 - 1
src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts

@@ -12,7 +12,7 @@ export class ConsoleOutputDisableExpressionNode extends Node {
     /**
      * @param options
      */
-    constructor (options: IOptions = {}) {
+    constructor (options: IOptions) {
         super(options);
 
         this.node = this.getNodeStructure();

+ 1 - 1
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts

@@ -18,7 +18,7 @@ export class DebugProtectionFunctionCallNode extends Node {
      * @param debugProtectionFunctionName
      * @param options
      */
-    constructor (debugProtectionFunctionName: string, options: IOptions = {}) {
+    constructor (debugProtectionFunctionName: string, options: IOptions) {
         super(options);
 
         this.debugProtectionFunctionName = debugProtectionFunctionName;

+ 1 - 1
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts

@@ -18,7 +18,7 @@ export class DebugProtectionFunctionIntervalNode extends Node {
      * @param debugProtectionFunctionName
      * @param options
      */
-    constructor (debugProtectionFunctionName: string, options: IOptions = {}) {
+    constructor (debugProtectionFunctionName: string, options: IOptions) {
         super(options);
 
         this.debugProtectionFunctionName = debugProtectionFunctionName;

+ 1 - 1
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts

@@ -19,7 +19,7 @@ export class DebugProtectionFunctionNode extends Node {
      * @param debugProtectionFunctionName
      * @param options
      */
-    constructor (debugProtectionFunctionName: string, options: IOptions = {}) {
+    constructor (debugProtectionFunctionName: string, options: IOptions) {
         super(options);
 
         this.debugProtectionFunctionName = debugProtectionFunctionName;

+ 1 - 1
src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts

@@ -24,7 +24,7 @@ export class SelfDefendingUnicodeNode extends Node {
     /**
      * @param options
      */
-    constructor (options: IOptions = {}) {
+    constructor (options: IOptions) {
         super(options);
 
         this.node = this.getNodeStructure();

+ 1 - 1
src/custom-nodes/unicode-array-nodes/UnicodeArrayCallsWrapper.ts

@@ -42,7 +42,7 @@ export class UnicodeArrayCallsWrapper extends Node {
         unicodeArrayCallsWrapperName: string,
         unicodeArrayName: string,
         unicodeArray: string[],
-        options: IOptions = {}
+        options: IOptions
     ) {
         super(options);
 

+ 2 - 2
src/custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNode.ts

@@ -39,7 +39,7 @@ export class UnicodeArrayDecodeNode extends Node {
     constructor (
         unicodeArrayName: string,
         unicodeArray: string[],
-        options: IOptions = {}
+        options: IOptions
     ) {
         super(options);
 
@@ -81,7 +81,7 @@ export class UnicodeArrayDecodeNode extends Node {
         let code: string = '',
             node: INode;
 
-        if (this.options['selfDefending']) {
+        if (this.options.getOption('selfDefending')) {
             code = `
                 var ${environmentName} = function(){return ${Utils.stringToUnicode('dev')};};
                    

+ 1 - 1
src/custom-nodes/unicode-array-nodes/UnicodeArrayNode.ts

@@ -47,7 +47,7 @@ export class UnicodeArrayNode extends Node {
     constructor (
         unicodeArrayName: string,
         unicodeArrayRotateValue: number = 0,
-        options: IOptions = {}
+        options: IOptions
     ) {
         super(options);
 

+ 2 - 2
src/custom-nodes/unicode-array-nodes/UnicodeArrayRotateFunctionNode.ts

@@ -46,7 +46,7 @@ export class UnicodeArrayRotateFunctionNode extends Node {
         unicodeArrayName: string,
         unicodeArray: string[],
         unicodeArrayRotateValue: number,
-        options: IOptions = {}
+        options: IOptions
     ) {
         super(options);
 
@@ -86,7 +86,7 @@ export class UnicodeArrayRotateFunctionNode extends Node {
             whileFunctionName: string = Utils.getRandomVariableName(),
             node: INode;
 
-        if (this.options['selfDefending']) {
+        if (this.options.getOption('selfDefending')) {
             code = JavaScriptObfuscator.obfuscate(`
                 (function () {
                     var func = function(){return ${Utils.stringToUnicode('dev')};};

+ 13 - 11
src/interfaces/IOptions.d.ts

@@ -1,13 +1,15 @@
+import { IOptionsPreset } from "./IOptionsPreset";
+
 export interface IOptions {
-    compact?: boolean;
-    debugProtection?: boolean;
-    debugProtectionInterval?: boolean;
-    disableConsoleOutput?: boolean;
-    encodeUnicodeLiterals?: boolean;
-    reservedNames?: string[];
-    rotateUnicodeArray?: boolean;
-    selfDefending?: boolean;
-    unicodeArray?: boolean;
-    unicodeArrayThreshold?: number;
-    wrapUnicodeArrayCalls?: boolean;
+    /**
+     * @param options
+     */
+    assign (options: IOptionsPreset): void;
+
+    /**
+     * @param optionName
+     */
+    getOption (optionName: string): any;
+
+    getOptions (): IOptionsPreset;
 }

+ 13 - 0
src/interfaces/IOptionsPreset.d.ts

@@ -0,0 +1,13 @@
+export interface IOptionsPreset {
+    compact?: boolean;
+    debugProtection?: boolean;
+    debugProtectionInterval?: boolean;
+    disableConsoleOutput?: boolean;
+    encodeUnicodeLiterals?: boolean;
+    reservedNames?: string[];
+    rotateUnicodeArray?: boolean;
+    selfDefending?: boolean;
+    unicodeArray?: boolean;
+    unicodeArrayThreshold?: number;
+    wrapUnicodeArrayCalls?: boolean;
+}

+ 2 - 2
src/node-groups/DebugProtectionNodesGroup.ts

@@ -16,7 +16,7 @@ export class DebugProtectionNodesGroup extends NodesGroup {
     /**
      * @param options
      */
-    constructor (options: IOptions = {}) {
+    constructor (options: IOptions) {
         super(options);
 
         this.nodes.set(
@@ -28,7 +28,7 @@ export class DebugProtectionNodesGroup extends NodesGroup {
             new DebugProtectionFunctionCallNode(this.debugProtectionFunctionIdentifier, this.options)
         );
 
-        if (this.options['debugProtectionInterval']) {
+        if (this.options.getOption('debugProtectionInterval')) {
             this.nodes.set(
                 'debugProtectionFunctionIntervalNode',
                 new DebugProtectionFunctionIntervalNode(this.debugProtectionFunctionIdentifier, this.options)

+ 1 - 1
src/node-groups/NodesGroup.ts

@@ -14,7 +14,7 @@ export abstract class NodesGroup implements INodesGroup {
      */
     protected options: IOptions;
 
-    constructor (options: IOptions = {}) {
+    constructor (options: IOptions) {
         this.options = options;
     }
 

+ 1 - 1
src/node-groups/SelfDefendingNodesGroup.ts

@@ -7,7 +7,7 @@ export class SelfDefendingNodesGroup extends NodesGroup {
     /**
      * @param options
      */
-    constructor (options: IOptions = {}) {
+    constructor (options: IOptions) {
         super(options);
 
         this.nodes.set(

+ 5 - 5
src/node-groups/UnicodeArrayNodesGroup.ts

@@ -26,10 +26,10 @@ export class UnicodeArrayNodesGroup extends NodesGroup {
     /**
      * @param options
      */
-    constructor (options: IOptions = {}) {
+    constructor (options: IOptions) {
         super(options);
 
-        this.unicodeArrayRotateValue = this.options['rotateUnicodeArray'] ? Utils.getRandomInteger(100, 500) : 0;
+        this.unicodeArrayRotateValue = this.options.getOption('rotateUnicodeArray') ? Utils.getRandomInteger(100, 500) : 0;
 
         let unicodeArrayNode: UnicodeArrayNode = new UnicodeArrayNode(
                 this.unicodeArrayName,
@@ -43,7 +43,7 @@ export class UnicodeArrayNodesGroup extends NodesGroup {
             unicodeArrayNode
         );
 
-        if (this.options['wrapUnicodeArrayCalls']) {
+        if (this.options.getOption('wrapUnicodeArrayCalls')) {
             this.nodes.set(
                 'unicodeArrayCallsWrapper',
                 new UnicodeArrayCallsWrapper(
@@ -55,7 +55,7 @@ export class UnicodeArrayNodesGroup extends NodesGroup {
             );
         }
 
-        if (this.options['encodeUnicodeLiterals']) {
+        if (this.options.getOption('encodeUnicodeLiterals')) {
             this.nodes.set(
                 'unicodeArrayDecodeNode',
                 new UnicodeArrayDecodeNode (
@@ -66,7 +66,7 @@ export class UnicodeArrayNodesGroup extends NodesGroup {
             );
         }
 
-        if (this.options['rotateUnicodeArray']) {
+        if (this.options.getOption('rotateUnicodeArray')) {
             this.nodes.set(
                 'unicodeArrayRotateFunctionNode',
                 new UnicodeArrayRotateFunctionNode(

+ 9 - 8
src/node-obfuscators/NodeObfuscator.ts

@@ -24,7 +24,7 @@ export abstract class NodeObfuscator implements INodeObfuscator {
      * @param nodes
      * @param options
      */
-    constructor(nodes: Map <string, ICustomNode>, options: IOptions = {}) {
+    constructor(nodes: Map <string, ICustomNode>, options: IOptions) {
         this.nodes = nodes;
         this.options = options;
     }
@@ -40,9 +40,10 @@ export abstract class NodeObfuscator implements INodeObfuscator {
      * @returns {boolean}
      */
     protected isReservedName (name: string): boolean {
-        return this.options['reservedNames'].some((reservedName: string) => {
-            return new RegExp(reservedName, 'g').test(name);
-        });
+        return this.options.getOption('reservedNames')
+            .some((reservedName: string) => {
+                return new RegExp(reservedName, 'g').test(name);
+            });
     }
 
     /**
@@ -98,15 +99,15 @@ export abstract class NodeObfuscator implements INodeObfuscator {
      */
     protected replaceLiteralValueByUnicodeValue (nodeValue: string): string {
         let value: string = nodeValue,
-            replaceByUnicodeArrayFlag: boolean = Math.random() <= this.options['unicodeArrayThreshold'];
+            replaceByUnicodeArrayFlag: boolean = Math.random() <= this.options.getOption('unicodeArrayThreshold');
 
-        if (this.options['encodeUnicodeLiterals'] && replaceByUnicodeArrayFlag) {
+        if (this.options.getOption('encodeUnicodeLiterals') && replaceByUnicodeArrayFlag) {
             value = Utils.btoa(value);
         }
 
         value = Utils.stringToUnicode(value);
 
-        if (!this.options['unicodeArray'] || !replaceByUnicodeArrayFlag) {
+        if (!this.options.getOption('unicodeArray') || !replaceByUnicodeArrayFlag) {
             return value;
         }
 
@@ -133,7 +134,7 @@ export abstract class NodeObfuscator implements INodeObfuscator {
 
         hexadecimalIndex = this.replaceLiteralNumberByHexadecimalValue(index);
 
-        if (this.options['wrapUnicodeArrayCalls']) {
+        if (this.options.getOption('wrapUnicodeArrayCalls')) {
             return `${this.nodes.get('unicodeArrayCallsWrapper').getNodeIdentifier()}('${hexadecimalIndex}')`;
         }
 

+ 2 - 2
src/preset-options/DefaultPreset.ts

@@ -1,6 +1,6 @@
-import { IOptions } from "../interfaces/IOptions";
+import { IOptionsPreset } from "../interfaces/IOptionsPreset";
 
-export const DEFAULT_PRESET: IOptions = Object.freeze({
+export const DEFAULT_PRESET: IOptionsPreset = Object.freeze({
     compact: true,
     debugProtection: false,
     debugProtectionInterval: false,

+ 2 - 2
src/preset-options/NoCustomNodesPreset.ts

@@ -1,6 +1,6 @@
-import { IOptions } from "../interfaces/IOptions";
+import { IOptionsPreset } from "../interfaces/IOptionsPreset";
 
-export const NO_CUSTOM_NODES_PRESET: IOptions = Object.freeze({
+export const NO_CUSTOM_NODES_PRESET: IOptionsPreset = Object.freeze({
     compact: true,
     debugProtection: false,
     debugProtectionInterval: false,

+ 1 - 1
tsconfig.json

@@ -6,7 +6,7 @@
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "removeComments": true,
-    "noImplicitAny": true
+    "noImplicitAny": false
   },
   "exclude": [
     "node_modules",